1/*
2 * Copyright (C) 2022 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 "accessibility_account_data.h"
17
18#include <any>
19#ifdef OHOS_BUILD_ENABLE_HITRACE
20#include <hitrace_meter.h>
21#endif // OHOS_BUILD_ENABLE_HITRACE
22#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
23#include "accessibility_display_manager.h"
24#endif
25#include "accessible_ability_manager_service.h"
26#include "extension_ability_info.h"
27#include "hilog_wrapper.h"
28#include "utils.h"
29#include "system_ability_definition.h"
30#include "os_account_manager.h"
31
32namespace OHOS {
33namespace Accessibility {
34namespace {
35    constexpr int32_t AUTOCLICK_DELAY_TIME_MIN = 1000; // ms
36    constexpr int32_t AUTOCLICK_DELAY_TIME_MAX = 5000; // ms
37    constexpr int32_t INIT_DATASHARE_HELPER_SLEEP_TIME = 500;
38    constexpr int DEFAULT_ACCOUNT_ID = 100;
39    constexpr int SHORT_KEY_TIMEOUT_AFTER_USE = 1000; // ms
40    constexpr int SHORT_KEY_TIMEOUT_BEFORE_USE = 3000; // ms
41    constexpr int INVALID_SHORTCUT_ON_LOCK_SCREEN_STATE = 2;
42    const std::string HIGH_TEXT_CONTRAST_ENABLED = "high_text_contrast_enabled";
43    const std::string ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled";
44    const std::string ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED = "accessibility_display_daltonizer_enabled";
45    const std::string MASTER_MONO = "master_mono";
46    const std::string ACCESSIBILITY_SCREENREADER_ENABLED = "accessibility_screenreader_enabled";
47    const std::string MASTER_BALENCE = "master_balance";
48    const std::string CLICK_RESPONSE_TIME = "click_response_time";
49    const std::string IGNORE_REPEAT_CLICK_SWITCH = "ignore_repeat_click_switch";
50    const std::string IGNORE_REPEAT_CLICK_TIME = "ignore_repeat_click_time";
51    const std::string ACCESSIBILITY_DISPLAY_DALTONIZER = "accessibility_display_daltonizer";
52    const std::string SCREEN_READER_BUNDLE_ABILITY_NAME = "com.huawei.hmos.screenreader/AccessibilityExtAbility";
53    const std::string DEVICE_PROVISIONED = "device_provisioned";
54    const std::string ENABLED_ACCESSIBILITY_SERVICES = "enabled_accessibility_services";
55    const std::string ACCESSIBILITY_SHORTCUT_ENABLED = "accessibility_shortcut_enabled";
56    const std::string ACCESSIBILITY_SHORTCUT_ENABLED_ON_LOCK_SCREEN = "accessibility_shortcut_enabled_on_lock_screen";
57    const std::string ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN = "accessibility_shortcut_on_lock_screen";
58    const std::string ACCESSIBILITY_SHORTCUT_TIMEOUT = "accessibility_shortcut_timeout";
59    const std::string SCREEN_MAGNIFICATION_KEY = "accessibility_display_magnification_enabled";
60    const std::string ACCESSIBILITY_CLONE_FLAG = "accessibility_config_clone";
61} // namespace
62
63AccessibilityAccountData::AccessibilityAccountData(int32_t accountId)
64{
65    id_ = accountId;
66}
67
68AccessibilityAccountData::~AccessibilityAccountData()
69{}
70
71int32_t AccessibilityAccountData::GetAccountId()
72{
73    HILOG_INFO();
74    return id_;
75}
76
77uint32_t AccessibilityAccountData::GetAccessibilityState()
78{
79    HILOG_DEBUG();
80    uint32_t state = 0;
81    if (connectedA11yAbilities_.GetSize() != 0 || connectingA11yAbilities_.GetSize() != 0) {
82        HILOG_DEBUG("connectingA11yAbilities %{public}zu connectedA11yAbilities %{public}zu",
83            connectingA11yAbilities_.GetSize(), connectedA11yAbilities_.GetSize());
84        state |= STATE_ACCESSIBILITY_ENABLED;
85        if (!config_->GetEnabledState()) {
86            config_->SetEnabled(true);
87        }
88    } else {
89        if (config_->GetEnabledState()) {
90            config_->SetEnabled(false);
91        }
92    }
93
94    if (config_->GetTouchGuideState()) {
95        state |= STATE_EXPLORATION_ENABLED;
96    }
97
98    if (config_->GetKeyEventObserverState()) {
99        state |= STATE_KEYEVENT_ENABLED;
100    }
101
102    if (config_->GetGestureState()) {
103        state |= STATE_GESTURE_ENABLED;
104    }
105    return state;
106}
107
108void AccessibilityAccountData::OnAccountSwitched()
109{
110    HILOG_INFO();
111    connectingA11yAbilities_.Clear();
112    std::vector<sptr<AccessibleAbilityConnection>> connectionList;
113    connectedA11yAbilities_.GetAccessibilityAbilities(connectionList);
114    for (auto& connection : connectionList) {
115        if (connection) {
116            connection->Disconnect();
117        }
118    }
119
120    connectedA11yAbilities_.Clear();
121    enabledAbilities_.clear();
122    std::lock_guard lock(asacConnectionsMutex_);
123    asacConnections_.clear();
124}
125
126void AccessibilityAccountData::AddConnectedAbility(sptr<AccessibleAbilityConnection>& connection)
127{
128    if (!connection) {
129        HILOG_ERROR("connection is nullptr");
130        return;
131    }
132
133    std::string uri = Utils::GetUri(connection->GetElementName());
134    connectedA11yAbilities_.AddAccessibilityAbility(uri, connection);
135}
136
137void AccessibilityAccountData::RemoveConnectedAbility(const AppExecFwk::ElementName &element)
138{
139    connectedA11yAbilities_.RemoveAccessibilityAbilityByUri(Utils::GetUri(element));
140}
141
142void AccessibilityAccountData::AddCaptionPropertyCallback(
143    const sptr<IAccessibleAbilityManagerCaptionObserver>& callback)
144{
145    HILOG_DEBUG();
146    std::lock_guard<ffrt::mutex> lock(captionPropertyCallbacksMutex_);
147    captionPropertyCallbacks_.push_back(callback);
148}
149
150void AccessibilityAccountData::RemoveCaptionPropertyCallback(const wptr<IRemoteObject>& callback)
151{
152    HILOG_DEBUG();
153    std::lock_guard<ffrt::mutex> lock(captionPropertyCallbacksMutex_);
154    for (auto itr = captionPropertyCallbacks_.begin(); itr != captionPropertyCallbacks_.end(); itr++) {
155        if ((*itr)->AsObject() == callback) {
156            captionPropertyCallbacks_.erase(itr);
157            break;
158        }
159    }
160}
161
162void AccessibilityAccountData::AddEnableAbilityListsObserver(
163    const sptr<IAccessibilityEnableAbilityListsObserver>& observer)
164{
165    HILOG_DEBUG();
166    std::lock_guard<ffrt::mutex> lock(enableAbilityListObserversMutex_);
167    if (std::any_of(enableAbilityListsObservers_.begin(), enableAbilityListsObservers_.end(),
168        [observer](const sptr<IAccessibilityEnableAbilityListsObserver> &listObserver) {
169            return listObserver == observer;
170        })) {
171        HILOG_ERROR("observer is already exist");
172        return;
173    }
174    enableAbilityListsObservers_.push_back(observer);
175    HILOG_DEBUG("observer's size is %{public}zu", enableAbilityListsObservers_.size());
176}
177
178void AccessibilityAccountData::RemoveEnableAbilityListsObserver(const wptr<IRemoteObject>& observer)
179{
180    HILOG_INFO();
181    std::lock_guard<ffrt::mutex> lock(enableAbilityListObserversMutex_);
182    for (auto itr = enableAbilityListsObservers_.begin(); itr != enableAbilityListsObservers_.end(); itr++) {
183        if ((*itr)->AsObject() == observer) {
184            HILOG_DEBUG("erase observer");
185            enableAbilityListsObservers_.erase(itr);
186            HILOG_DEBUG("observer's size is %{public}zu", enableAbilityListsObservers_.size());
187            return;
188        }
189    }
190}
191
192void AccessibilityAccountData::UpdateEnableAbilityListsState()
193{
194    std::lock_guard<ffrt::mutex> lock(enableAbilityListObserversMutex_);
195    HILOG_DEBUG("observer's size is %{public}zu", enableAbilityListsObservers_.size());
196    for (auto &observer : enableAbilityListsObservers_) {
197        if (observer) {
198            observer->OnAccessibilityEnableAbilityListsChanged();
199        }
200    }
201}
202
203void AccessibilityAccountData::UpdateInstallAbilityListsState()
204{
205    std::lock_guard<ffrt::mutex> lock(enableAbilityListObserversMutex_);
206    HILOG_DEBUG("observer's size is %{public}zu", enableAbilityListsObservers_.size());
207    for (auto &observer : enableAbilityListsObservers_) {
208        if (observer) {
209            observer->OnAccessibilityInstallAbilityListsChanged();
210        }
211    }
212}
213
214void AccessibilityAccountData::AddAccessibilityWindowConnection(
215    const int32_t windowId, const sptr<AccessibilityWindowConnection>& interactionConnection)
216{
217    HILOG_INFO("windowId(%{public}d)", windowId);
218    std::lock_guard lock(asacConnectionsMutex_);
219    asacConnections_[windowId] = interactionConnection;
220}
221
222void AccessibilityAccountData::RemoveAccessibilityWindowConnection(const int32_t windowId)
223{
224    HILOG_INFO("windowId(%{public}d)", windowId);
225    std::lock_guard lock(asacConnectionsMutex_);
226    std::map<int32_t, sptr<AccessibilityWindowConnection>>::iterator it = asacConnections_.find(windowId);
227    if (it != asacConnections_.end()) {
228        asacConnections_.erase(it);
229    }
230}
231
232void AccessibilityAccountData::AddConnectingA11yAbility(const std::string &uri,
233    const sptr<AccessibleAbilityConnection> &connection)
234{
235    connectingA11yAbilities_.AddAccessibilityAbility(uri, connection);
236}
237
238void AccessibilityAccountData::RemoveConnectingA11yAbility(const std::string &uri)
239{
240    connectingA11yAbilities_.RemoveAccessibilityAbilityByUri(uri);
241}
242
243void AccessibilityAccountData::AddEnabledAbility(const std::string &name)
244{
245    HILOG_DEBUG("AddEnabledAbility start.");
246    if (std::any_of(enabledAbilities_.begin(), enabledAbilities_.end(),
247        [name](const std::string &abilityName) {
248            return abilityName == name;
249        })) {
250        HILOG_DEBUG("The ability is already enabled, and it's name is %{public}s", name.c_str());
251        return;
252    }
253    enabledAbilities_.push_back(name);
254    if (name == screenReaderAbilityName_) {
255        SetScreenReaderState(screenReaderKey_, "1");
256    }
257    UpdateEnableAbilityListsState();
258    HILOG_DEBUG("Add EnabledAbility: %{public}zu", enabledAbilities_.size());
259}
260
261RetError AccessibilityAccountData::RemoveEnabledAbility(const std::string &name)
262{
263    HILOG_DEBUG("RemoveEnabledAbility start");
264    for (auto it = enabledAbilities_.begin(); it != enabledAbilities_.end(); it++) {
265        if (*it == name) {
266            HILOG_DEBUG("Removed %{public}s from EnabledAbility: ", name.c_str());
267            enabledAbilities_.erase(it);
268            if (name == screenReaderAbilityName_) {
269                SetScreenReaderState(screenReaderKey_, "0");
270            }
271            UpdateEnableAbilityListsState();
272            HILOG_DEBUG("EnabledAbility size %{public}zu", enabledAbilities_.size());
273            return RET_OK;
274        }
275    }
276    HILOG_ERROR("The ability %{public}s is not enabled.", name.c_str());
277    return RET_ERR_NOT_ENABLED;
278}
279
280void AccessibilityAccountData::AddInstalledAbility(AccessibilityAbilityInfo& abilityInfo)
281{
282    HILOG_DEBUG("abilityInfo's bundle name is %{public}s", abilityInfo.GetPackageName().c_str());
283    for (size_t i = 0; i < installedAbilities_.size(); i++) {
284        if ((installedAbilities_[i].GetPackageName() == abilityInfo.GetPackageName()) &&
285            installedAbilities_[i].GetName() == abilityInfo.GetName()) {
286            HILOG_DEBUG("the ability is already exist.");
287            return;
288        }
289    }
290    installedAbilities_.push_back(abilityInfo);
291    UpdateInstallAbilityListsState();
292    HILOG_DEBUG("push back installed ability successfully and installedAbilities_'s size is %{public}zu",
293        installedAbilities_.size());
294}
295
296void AccessibilityAccountData::RemoveInstalledAbility(const std::string &bundleName)
297{
298    HILOG_DEBUG("start.");
299    for (auto it = installedAbilities_.begin(); it != installedAbilities_.end();) {
300        if (it->GetPackageName() == bundleName) {
301            HILOG_DEBUG("Removed %{public}s from InstalledAbility: ", bundleName.c_str());
302            if (!config_) {
303                it = installedAbilities_.erase(it);
304                UpdateInstallAbilityListsState();
305                continue;
306            }
307            it = installedAbilities_.erase(it);
308            UpdateInstallAbilityListsState();
309        } else {
310            ++it;
311        }
312    }
313}
314
315void AccessibilityAccountData::ClearInstalledAbility()
316{
317    HILOG_DEBUG("start.");
318    installedAbilities_.clear();
319}
320
321const sptr<AccessibleAbilityConnection> AccessibilityAccountData::GetAccessibleAbilityConnection(
322    const std::string &elementName)
323{
324    return connectedA11yAbilities_.GetAccessibilityAbilityByName(elementName);
325}
326
327const sptr<AccessibilityWindowConnection> AccessibilityAccountData::GetAccessibilityWindowConnection(
328    const int32_t windowId)
329{
330    std::lock_guard lock(asacConnectionsMutex_);
331    HILOG_DEBUG("window id[%{public}d] interactionOperators's size[%{public}zu]", windowId, asacConnections_.size());
332    for (auto &asacConnection : asacConnections_) {
333        HILOG_DEBUG("window id of asacConnection is %{public}d", asacConnection.first);
334    }
335
336    if (asacConnections_.count(windowId) > 0) {
337        return asacConnections_[windowId];
338    }
339
340    return nullptr;
341}
342
343const std::map<std::string, sptr<AccessibleAbilityConnection>> AccessibilityAccountData::GetConnectedA11yAbilities()
344{
345    std::map<std::string, sptr<AccessibleAbilityConnection>> connectionMap;
346    connectedA11yAbilities_.GetAccessibilityAbilitiesMap(connectionMap);
347    return connectionMap;
348}
349
350const std::map<int32_t, sptr<AccessibilityWindowConnection>> AccessibilityAccountData::GetAsacConnections()
351{
352    HILOG_DEBUG("GetAsacConnections start.");
353    return asacConnections_;
354}
355
356const CaptionPropertyCallbacks AccessibilityAccountData::GetCaptionPropertyCallbacks()
357{
358    HILOG_DEBUG("GetCaptionPropertyCallbacks start.");
359    std::lock_guard<ffrt::mutex> lock(captionPropertyCallbacksMutex_);
360    CaptionPropertyCallbacks rtnVec = captionPropertyCallbacks_;
361    return rtnVec;
362}
363
364sptr<AccessibleAbilityConnection> AccessibilityAccountData::GetConnectingA11yAbility(const std::string &uri)
365{
366    return connectingA11yAbilities_.GetAccessibilityAbilityByUri(uri);
367}
368
369const std::vector<std::string> &AccessibilityAccountData::GetEnabledAbilities()
370{
371    HILOG_DEBUG("enabledAbilities_'s size is (%{public}zu).", enabledAbilities_.size());
372    for (auto& ability : enabledAbilities_) {
373        HILOG_DEBUG("bundleName is %{public}s ", ability.c_str());
374    }
375    return enabledAbilities_;
376}
377
378const std::vector<AccessibilityAbilityInfo> &AccessibilityAccountData::GetInstalledAbilities() const
379{
380    HILOG_DEBUG("GetInstalledAbilities start.");
381    return installedAbilities_;
382}
383
384void AccessibilityAccountData::GetAbilitiesByState(AbilityStateType state,
385    std::vector<AccessibilityAbilityInfo> &abilities)
386{
387    HILOG_DEBUG("get abilities by state %{public}d", state);
388    if (state == ABILITY_STATE_ENABLE) {
389        connectedA11yAbilities_.GetAbilitiesInfo(abilities);
390    } else if (state == ABILITY_STATE_DISABLE) {
391        GetDisableAbilities(abilities);
392        HILOG_DEBUG("the size of disable abilities is %{public}zu", abilities.size());
393    } else {
394        abilities = installedAbilities_;
395    }
396}
397
398void AccessibilityAccountData::GetDisableAbilities(std::vector<AccessibilityAbilityInfo> &disabledAbilities)
399{
400    HILOG_DEBUG("get disable abilities");
401    disabledAbilities = installedAbilities_;
402    connectedA11yAbilities_.GetDisableAbilities(disabledAbilities);
403}
404
405void AccessibilityAccountData::UpdateAccountCapabilities()
406{
407    HILOG_DEBUG("start.");
408    UpdateFilteringKeyEventsCapability();
409    UpdateEventTouchGuideCapability();
410    UpdateGesturesSimulationCapability();
411    UpdateMagnificationCapability();
412    config_->SetTouchGuideState(isEventTouchGuideState_);
413    config_->SetGestureState(isGesturesSimulation_);
414    config_->SetKeyEventObserverState(isFilteringKeyEvents_);
415}
416
417void AccessibilityAccountData::UpdateEventTouchGuideCapability()
418{
419    if (connectedA11yAbilities_.IsExistCapability(Capability::CAPABILITY_TOUCH_GUIDE)) {
420        isEventTouchGuideState_ = true;
421        return;
422    }
423
424    isEventTouchGuideState_ = false;
425}
426
427void AccessibilityAccountData::UpdateGesturesSimulationCapability()
428{
429    if (connectedA11yAbilities_.IsExistCapability(Capability::CAPABILITY_GESTURE)) {
430        isGesturesSimulation_ = true;
431        return;
432    }
433
434    isGesturesSimulation_ = false;
435}
436
437void AccessibilityAccountData::UpdateFilteringKeyEventsCapability()
438{
439    if (connectedA11yAbilities_.IsExistCapability(Capability::CAPABILITY_KEY_EVENT_OBSERVER)) {
440        isFilteringKeyEvents_ = true;
441        return;
442    }
443
444    isFilteringKeyEvents_ = false;
445}
446
447void AccessibilityAccountData::UpdateMagnificationCapability()
448{
449    if (connectedA11yAbilities_.IsExistCapability(Capability::CAPABILITY_ZOOM)) {
450        isScreenMagnification_ = true;
451        return;
452    }
453
454    isScreenMagnification_ = false;
455}
456
457void AccessibilityAccountData::SetScreenReaderExtInAllAccounts(const bool state)
458{
459    RetError rtn = RET_OK;
460    std::vector<int32_t> accountIds = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAllAccountIds();
461    for (auto accountId : accountIds) {
462        auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
463        std::shared_ptr<AccessibilitySettingsConfig> config = accountData->GetConfig();
464        if (config == nullptr) {
465            HILOG_WARN("config is nullptr, accountId = %{public}d", accountId);
466            continue;
467        }
468        if (state) {
469            rtn = config->AddEnabledAccessibilityService(SCREEN_READER_BUNDLE_ABILITY_NAME);
470        } else {
471            rtn = config->RemoveEnabledAccessibilityService(SCREEN_READER_BUNDLE_ABILITY_NAME);
472        }
473        HILOG_INFO("set screenReader state = %{public}d, rtn = %{public}d, accountId = %{public}d", state, rtn,
474            accountId);
475    }
476}
477
478void AccessibilityAccountData::SetAbilityAutoStartState(const std::string &name, const bool state)
479{
480    RetError rtn = RET_OK;
481    if (name == SCREEN_READER_BUNDLE_ABILITY_NAME) {
482        SetScreenReaderState(screenReaderKey_, state ? "1" : "0");
483        SetScreenReaderExtInAllAccounts(state);
484        return;
485    }
486    if (!config_) {
487        HILOG_WARN("conig_ is nullptr.");
488        return;
489    }
490    if (state) {
491        rtn = config_->AddEnabledAccessibilityService(name);
492    } else {
493        rtn = config_->RemoveEnabledAccessibilityService(name);
494    }
495    if (rtn != RET_OK) {
496        HILOG_WARN("handle service %{public}s state = %{public}d failed, rtn = %{public}d", name.c_str(), state, rtn);
497    }
498}
499
500void AccessibilityAccountData::SetScreenReaderState(const std::string &name, const std::string &state)
501{
502    HILOG_DEBUG("set screen reader key [%{public}s], state = [%{public}s].", name.c_str(), state.c_str());
503    std::shared_ptr<AccessibilitySettingProvider> service =
504        AccessibilitySettingProvider::GetInstance(POWER_MANAGER_SERVICE_ID);
505    if (service == nullptr) {
506        HILOG_ERROR("service is nullptr");
507        return;
508    }
509    ErrCode ret = service->PutStringValue(name, state, true);
510    if (ret != ERR_OK) {
511        HILOG_ERROR("set failed, ret=%{public}d", ret);
512    }
513}
514
515bool AccessibilityAccountData::GetDefaultUserScreenReaderState()
516{
517    HILOG_DEBUG();
518    std::vector<std::string> services = config_->GetEnabledAccessibilityServices();
519    auto iter = std::find(services.begin(), services.end(), SCREEN_READER_BUNDLE_ABILITY_NAME);
520    return iter != services.end();
521}
522
523void AccessibilityAccountData::DelAutoStartPrefKeyInRemovePkg(const std::string &bundleName)
524{
525    HILOG_ERROR("start and bundleName[%{public}s].", bundleName.c_str());
526    if (installedAbilities_.empty()) {
527        HILOG_DEBUG("There is no installed abilities.");
528        return;
529    }
530    for (auto &installAbility : installedAbilities_) {
531        if (installAbility.GetPackageName() == bundleName) {
532            std::string abilityName = installAbility.GetName();
533            std::string uri = Utils::GetUri(bundleName, abilityName);
534            SetAbilityAutoStartState(uri, false);
535            break;
536        }
537    }
538}
539
540bool AccessibilityAccountData::GetAbilityAutoStartState(const std::string &name)
541{
542    if (name == SCREEN_READER_BUNDLE_ABILITY_NAME && GetAccountType() == AccountSA::OsAccountType::PRIVATE) {
543        return GetDefaultUserScreenReaderState();
544    }
545    if (!config_) {
546        HILOG_WARN("config_ is nullptr.");
547        return false;
548    }
549    std::vector<std::string> serviceList = config_->GetEnabledAccessibilityServices();
550    auto iter = std::find(serviceList.begin(), serviceList.end(), name);
551    if (iter != serviceList.end()) {
552        return true;
553    } else {
554        return false;
555    }
556}
557
558void AccessibilityAccountData::GetConfigValueAtoHos(ConfigValueAtoHosUpdate &value)
559{
560    HILOG_DEBUG();
561    if (config_ == nullptr) {
562        HILOG_ERROR("config_ is nullptr");
563        return;
564    }
565
566    if (config_->GetDbHandle() == nullptr) {
567        HILOG_INFO("helper is null, retry.");
568        std::this_thread::sleep_for(std::chrono::milliseconds(INIT_DATASHARE_HELPER_SLEEP_TIME));
569        if (config_->GetDbHandle() == nullptr) {
570            HILOG_ERROR("helper is null");
571            return;
572        }
573    }
574
575    value.highContrastText = config_->GetDbHandle()->GetBoolValue(HIGH_TEXT_CONTRAST_ENABLED, false);
576    value.invertColor = config_->GetDbHandle()->GetBoolValue(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, false);
577    value.daltonizationState = config_->GetDbHandle()->GetBoolValue(ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, false);
578    value.displayDaltonizer = config_->GetDbHandle()->GetIntValue(ACCESSIBILITY_DISPLAY_DALTONIZER, 0);
579    value.shortcutEnabled = config_->GetDbHandle()->GetBoolValue(ACCESSIBILITY_SHORTCUT_ENABLED, false);
580    value.shortcutEnabledOnLockScreen = config_->GetDbHandle()->GetIntValue(
581        ACCESSIBILITY_SHORTCUT_ENABLED_ON_LOCK_SCREEN, INVALID_SHORTCUT_ON_LOCK_SCREEN_STATE);
582    value.shortcutOnLockScreen = config_->GetDbHandle()->GetIntValue(
583        ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, INVALID_SHORTCUT_ON_LOCK_SCREEN_STATE);
584    config_->GetDbHandle()->PutIntValue(ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, INVALID_SHORTCUT_ON_LOCK_SCREEN_STATE);
585    value.shortcutTimeout = config_->GetDbHandle()->GetIntValue(ACCESSIBILITY_SHORTCUT_TIMEOUT,
586        SHORT_KEY_TIMEOUT_BEFORE_USE);
587    value.clickResponseTime = config_->GetDbHandle()->GetIntValue(CLICK_RESPONSE_TIME, 0);
588    value.ignoreRepeatClickState = config_->GetDbHandle()->GetBoolValue(IGNORE_REPEAT_CLICK_SWITCH, false);
589    value.ignoreRepeatClickTime = config_->GetDbHandle()->GetIntValue(IGNORE_REPEAT_CLICK_TIME, 0);
590    value.screenMagnificationState = config_->GetDbHandle()->GetBoolValue(SCREEN_MAGNIFICATION_KEY, false);
591
592    // In Aos, the audio configuration is stored in SYSTEM and it should be copied to SECURE
593    config_->CloneAudioState();
594    value.audioMono = config_->GetDbHandle()->GetBoolValue(MASTER_MONO, false);
595    value.audioBalance = config_->GetDbHandle()->GetFloatValue(MASTER_BALENCE, 0);
596
597    std::shared_ptr<AccessibilitySettingProvider> service =
598        AccessibilitySettingProvider::GetInstance(POWER_MANAGER_SERVICE_ID);
599    if (service == nullptr) {
600        HILOG_ERROR("service is nullptr");
601        return;
602    }
603    service->GetBoolValue(ACCESSIBILITY_SCREENREADER_ENABLED, value.isScreenReaderEnabled);
604    service->DeleteInstance();
605}
606
607RetError AccessibilityAccountData::EnableAbility(const std::string &name, const uint32_t capabilities)
608{
609    HILOG_DEBUG("start and name[%{public}s] capabilities[%{public}d]", name.c_str(), capabilities);
610
611    bool isInstalled = false;
612    for (auto itr = installedAbilities_.begin(); itr != installedAbilities_.end(); itr++) {
613        if (itr->GetId() == name) {
614            isInstalled = true;
615
616            // Judge capabilities
617            uint32_t resultCapabilities = itr->GetStaticCapabilityValues() & capabilities;
618            HILOG_DEBUG("resultCapabilities is [%{public}d]", resultCapabilities);
619            if (resultCapabilities == 0) {
620                HILOG_ERROR("the result of capabilities is wrong");
621                return RET_ERR_NO_CAPABILITY;
622            }
623
624            itr->SetCapabilityValues(resultCapabilities);
625            break;
626        }
627    }
628    if (!isInstalled) {
629        HILOG_ERROR("the ability[%{public}s] is not installed", name.c_str());
630        return RET_ERR_NOT_INSTALLED;
631    }
632
633    // Add enabled ability
634    if (std::any_of(enabledAbilities_.begin(), enabledAbilities_.end(),
635        [name](const std::string &abilityName) {
636            return abilityName == name;
637        })) {
638        HILOG_ERROR("The ability[%{public}s] is already enabled", name.c_str());
639        return RET_ERR_CONNECTION_EXIST;
640    }
641#ifdef OHOS_BUILD_ENABLE_HITRACE
642    HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "EnableAbility:" + name);
643#endif // OHOS_BUILD_ENABLE_HITRACE
644
645    enabledAbilities_.push_back(name);
646    SetAbilityAutoStartState(name, true);
647    if (name == screenReaderAbilityName_) {
648        SetScreenReaderState(screenReaderKey_, "1");
649    }
650    UpdateAbilities();
651    Utils::RecordStartingA11yEvent(name);
652    return RET_OK;
653}
654
655bool AccessibilityAccountData::GetInstalledAbilitiesFromBMS()
656{
657    HILOG_DEBUG("start.");
658#ifdef OHOS_BUILD_ENABLE_HITRACE
659    HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryInstalledAbilityInfo");
660#endif // OHOS_BUILD_ENABLE_HITRACE
661    std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
662    sptr<AppExecFwk::IBundleMgr> bms = Singleton<AccessibleAbilityManagerService>::GetInstance().GetBundleMgrProxy();
663    if (!bms) {
664        Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_PACKAGE_INFO_FAILED);
665        HILOG_ERROR("GetBundleMgrProxy failed.");
666        return false;
667    }
668    bool ret = bms->QueryExtensionAbilityInfos(AppExecFwk::ExtensionAbilityType::ACCESSIBILITY, id_, extensionInfos);
669    if (!ret) {
670        Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_PACKAGE_INFO_FAILED);
671        HILOG_ERROR("Query extension ability information failed.");
672    }
673    HILOG_DEBUG("query extensionAbilityInfos' size is %{public}zu.", extensionInfos.size());
674    for (auto& info : extensionInfos) {
675        AccessibilityAbilityInitParams initParams;
676        Utils::Parse(info, initParams);
677        std::shared_ptr<AccessibilityAbilityInfo> accessibilityInfo =
678            std::make_shared<AccessibilityAbilityInfo>(initParams);
679        AddInstalledAbility(*accessibilityInfo);
680    }
681    return true;
682}
683
684void AccessibilityAccountData::Init()
685{
686    HILOG_DEBUG("Init start.");
687    if (!config_) {
688        config_ = std::make_shared<AccessibilitySettingsConfig>(id_);
689        config_->Init();
690    }
691    ErrCode rtn = AccountSA::OsAccountManager::GetOsAccountType(id_, accountType_);
692    if (rtn != ERR_OK) {
693        HILOG_ERROR("get account type failed for accountId [%{public}d]", id_);
694    }
695    std::shared_ptr<AccessibilitySettingProvider> service =
696        AccessibilitySettingProvider::GetInstance(POWER_MANAGER_SERVICE_ID);
697    if (service == nullptr) {
698        HILOG_ERROR("service is nullptr");
699        return;
700    }
701    bool cloneState = false;
702    service->GetBoolValue(ACCESSIBILITY_CLONE_FLAG, cloneState);
703    if (cloneState == true) {
704        service->PutBoolValue(ACCESSIBILITY_CLONE_FLAG, false);
705    }
706    if (id_ != DEFAULT_ACCOUNT_ID) {
707        HILOG_WARN("id != default_account_id.");
708        return;
709    }
710
711    HILOG_INFO("register clone observer.");
712    AccessibilitySettingObserver::UpdateFunc func = [ = ](const std::string& state) {
713        Singleton<AccessibleAbilityManagerService>::GetInstance().OnDataClone();
714    };
715    RetError ret = service->RegisterObserver(ACCESSIBILITY_CLONE_FLAG, func);
716    if (ret != RET_OK) {
717        HILOG_WARN("register clone observer failed %{public}d.", ret);
718    }
719}
720
721void AccessibilityAccountData::AddConfigCallback(
722    const sptr<IAccessibleAbilityManagerConfigObserver>& callback)
723{
724    HILOG_DEBUG("AddConfigCallback start.");
725    std::lock_guard<ffrt::mutex> lock(configCallbacksMutex_);
726    configCallbacks_.push_back(callback);
727}
728
729const std::vector<sptr<IAccessibleAbilityManagerConfigObserver>> AccessibilityAccountData::GetConfigCallbacks()
730{
731    HILOG_DEBUG("GetConfigCallbacks start.");
732    std::lock_guard<ffrt::mutex> lock(configCallbacksMutex_);
733    std::vector<sptr<IAccessibleAbilityManagerConfigObserver>> rtnVec = configCallbacks_;
734    return rtnVec;
735}
736
737void AccessibilityAccountData::SetConfigCallbacks(std::vector<sptr<IAccessibleAbilityManagerConfigObserver>>& observer)
738{
739    HILOG_DEBUG("SetConfigCallbacks start.");
740    std::lock_guard<ffrt::mutex> lock(configCallbacksMutex_);
741    configCallbacks_ = observer;
742}
743
744void AccessibilityAccountData::RemoveConfigCallback(const wptr<IRemoteObject>& callback)
745{
746    HILOG_DEBUG("RemoveConfigCallback start.");
747    std::lock_guard<ffrt::mutex> lock(configCallbacksMutex_);
748    for (auto itr = configCallbacks_.begin(); itr != configCallbacks_.end(); itr++) {
749        if ((*itr)->AsObject() == callback) {
750            configCallbacks_.erase(itr);
751            break;
752        }
753    }
754}
755
756std::shared_ptr<AccessibilitySettingsConfig> AccessibilityAccountData::GetConfig()
757{
758    HILOG_DEBUG("GetConfig start.");
759    return config_;
760}
761
762void AccessibilityAccountData::GetImportantEnabledAbilities(
763    std::map<std::string, uint32_t> &importantEnabledAbilities) const
764{
765    HILOG_DEBUG("GetImportantEnabledAbilities start.");
766    if (installedAbilities_.empty()) {
767        HILOG_DEBUG("Current user has no installed Abilities.");
768        return;
769    }
770    if (enabledAbilities_.empty()) {
771        HILOG_DEBUG("Current user has no enabled abilities.");
772        return;
773    }
774    HILOG_DEBUG("installedAbilities_'s is %{public}zu.", installedAbilities_.size());
775    for (auto &installAbility : installedAbilities_) {
776        if (!installAbility.IsImportant()) {
777            HILOG_DEBUG("The ability is not important.");
778            continue;
779        }
780        std::string bundleName = installAbility.GetPackageName();
781        std::string abilityName = installAbility.GetName();
782        HILOG_DEBUG("installAbility's packageName is %{public}s and abilityName is %{public}s",
783            bundleName.c_str(), abilityName.c_str());
784        std::string uri = Utils::GetUri(bundleName, abilityName);
785        std::vector<std::string>::const_iterator iter = std::find(enabledAbilities_.begin(),
786            enabledAbilities_.end(), uri);
787        if (iter != enabledAbilities_.end()) {
788            uint32_t capabilityValues = installAbility.GetCapabilityValues();
789            importantEnabledAbilities.emplace(std::make_pair(uri, capabilityValues));
790        }
791    }
792}
793
794void AccessibilityAccountData::UpdateImportantEnabledAbilities(
795    std::map<std::string, uint32_t> &importantEnabledAbilities)
796{
797    HILOG_DEBUG();
798    if (importantEnabledAbilities.empty()) {
799        HILOG_DEBUG("There is no enabled abilities.");
800        return;
801    }
802    if (installedAbilities_.empty()) {
803        HILOG_DEBUG("Current user has no installedAbilities.");
804        return;
805    }
806    HILOG_DEBUG("installedAbilities is %{public}zu.", installedAbilities_.size());
807    for (auto &installAbility : installedAbilities_) {
808        std::string bundleName = installAbility.GetPackageName();
809        std::string abilityName = installAbility.GetName();
810        HILOG_DEBUG("installAbility's packageName is %{public}s and abilityName is %{public}s",
811            bundleName.c_str(), abilityName.c_str());
812        std::string uri = Utils::GetUri(bundleName, abilityName);
813        std::map<std::string, uint32_t>::iterator iter = importantEnabledAbilities.find(uri);
814        if (iter != importantEnabledAbilities.end()) {
815            AddEnabledAbility(uri);
816            installAbility.SetCapabilityValues(iter->second);
817        }
818    }
819}
820
821void AccessibilityAccountData::UpdateAutoStartEnabledAbilities()
822{
823    HILOG_DEBUG();
824    if (id_ == -1) {
825        HILOG_DEBUG("Current user is -1.");
826        return;
827    }
828    if (installedAbilities_.empty()) {
829        HILOG_DEBUG("Current user has no installedAbilities.");
830        return;
831    }
832    if (!config_) {
833        HILOG_DEBUG("config_ is null.");
834        return;
835    }
836    HILOG_DEBUG("installedAbilities is %{public}zu.", installedAbilities_.size());
837    for (auto &installAbility : installedAbilities_) {
838        std::string bundleName = installAbility.GetPackageName();
839        std::string abilityName = installAbility.GetName();
840        std::string abilityId = bundleName + "/" + abilityName;
841        if (GetAbilityAutoStartState(abilityId)) {
842            HILOG_INFO("auto start packageName is %{public}s.", bundleName.c_str());
843            uint32_t capabilities = CAPABILITY_GESTURE | CAPABILITY_KEY_EVENT_OBSERVER | CAPABILITY_RETRIEVE |
844                CAPABILITY_TOUCH_GUIDE | CAPABILITY_ZOOM;
845            uint32_t resultCapabilities = installAbility.GetStaticCapabilityValues() & capabilities;
846            installAbility.SetCapabilityValues(resultCapabilities);
847            std::string uri = Utils::GetUri(bundleName, abilityName);
848            AddEnabledAbility(uri);
849        }
850    }
851}
852
853uint32_t AccessibilityAccountData::GetInputFilterFlag() const
854{
855    HILOG_DEBUG();
856    if (!config_) {
857        HILOG_ERROR("config is null");
858        return 0;
859    }
860    uint32_t flag = 0;
861    if (config_->GetScreenMagnificationState()) {
862        flag |= AccessibilityInputInterceptor::FEATURE_SCREEN_MAGNIFICATION;
863    }
864    if (isEventTouchGuideState_) {
865        flag |= AccessibilityInputInterceptor::FEATURE_TOUCH_EXPLORATION;
866    }
867    if (isFilteringKeyEvents_) {
868        flag |= AccessibilityInputInterceptor::FEATURE_FILTER_KEY_EVENTS;
869    }
870    if (isGesturesSimulation_) {
871        flag |= AccessibilityInputInterceptor::FEATURE_INJECT_TOUCH_EVENTS;
872    }
873    if (config_->GetMouseKeyState()) {
874        flag |= AccessibilityInputInterceptor::FEATURE_MOUSE_KEY;
875    }
876
877    int32_t autoclickTime = config_->GetMouseAutoClick();
878    if (autoclickTime >= AUTOCLICK_DELAY_TIME_MIN && autoclickTime <= AUTOCLICK_DELAY_TIME_MAX) {
879        flag |= AccessibilityInputInterceptor::FEATURE_MOUSE_AUTOCLICK;
880    }
881
882    uint32_t clickResponseTime = config_->GetClickResponseTime();
883    bool ignoreRepeatClickState = config_->GetIgnoreRepeatClickState();
884    if (clickResponseTime > 0 || ignoreRepeatClickState == true) {
885        flag |= AccessibilityInputInterceptor::FEATURE_SCREEN_TOUCH;
886    }
887
888    return flag;
889}
890
891void AccessibilityAccountData::UpdateAbilities()
892{
893    HILOG_DEBUG("installedAbilities is %{public}zu.", installedAbilities_.size());
894    for (auto &installAbility : installedAbilities_) {
895        std::string bundleName = installAbility.GetPackageName();
896        std::string abilityName = installAbility.GetName();
897        HILOG_DEBUG("installAbility's packageName is %{public}s and abilityName is %{public}s",
898            bundleName.c_str(), abilityName.c_str());
899
900        if (connectingA11yAbilities_.GetSizeByUri(Utils::GetUri(bundleName, abilityName))) {
901            HILOG_DEBUG("The ability(bundleName[%{public}s] abilityName[%{public}s]) is connecting.",
902                bundleName.c_str(), abilityName.c_str());
903            continue;
904        }
905        sptr<AccessibleAbilityConnection> connection =
906            GetAccessibleAbilityConnection(Utils::GetUri(bundleName, abilityName));
907
908        auto iter = std::find(enabledAbilities_.begin(), enabledAbilities_.end(),
909            Utils::GetUri(bundleName, abilityName));
910        if (iter != enabledAbilities_.end()) {
911            if (connection) {
912                continue;
913            }
914            AppExecFwk::ElementName element("", bundleName, abilityName);
915            connection = new(std::nothrow) AccessibleAbilityConnection(id_, connectCounter_++, installAbility);
916            if (connection != nullptr && connection->Connect(element)) {
917                AddConnectingA11yAbility(Utils::GetUri(bundleName, abilityName), connection);
918            }
919        } else {
920            HILOG_DEBUG("not in enabledAbilites list .");
921            if (connection) {
922                RemoveConnectedAbility(connection->GetElementName());
923                connection->Disconnect();
924            }
925        }
926    }
927}
928
929bool AccessibilityAccountData::RemoveAbility(const std::string &bundleName)
930{
931    HILOG_DEBUG("bundleName(%{public}s)", bundleName.c_str());
932    if (installedAbilities_.empty()) {
933        HILOG_DEBUG("There is no installed abilities.");
934        return false;
935    }
936    RemoveInstalledAbility(bundleName);
937
938    bool result = false;
939    // Remove enabled ability, remove connecting ability if it is connecting.
940    for (auto& enableAbility : enabledAbilities_) {
941        if (enableAbility.substr(0, enableAbility.find("/")) == bundleName) {
942            RemoveEnabledAbility(enableAbility);
943            RemoveConnectingA11yAbility(enableAbility);
944            result = true;
945        }
946    }
947
948    // Remove connected ability
949    connectedA11yAbilities_.RemoveAccessibilityAbilityByName(bundleName, result);
950    if (result) {
951        UpdateAbilities();
952    }
953
954    return result;
955}
956
957void AccessibilityAccountData::AddAbility(const std::string &bundleName)
958{
959    HILOG_DEBUG("bundleName(%{public}s)", bundleName.c_str());
960
961    std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
962    sptr<AppExecFwk::IBundleMgr> bms = Singleton<AccessibleAbilityManagerService>::GetInstance().GetBundleMgrProxy();
963    if (!bms) {
964        HILOG_ERROR("bms is nullptr.");
965        return;
966    }
967    bms->QueryExtensionAbilityInfos(AppExecFwk::ExtensionAbilityType::ACCESSIBILITY, id_, extensionInfos);
968    HILOG_DEBUG("query extensionAbilityInfos' size is %{public}zu.", extensionInfos.size());
969    bool hasNewExtensionAbility = false;
970    for (auto &newAbility : extensionInfos) {
971        if (newAbility.bundleName == bundleName) {
972            HILOG_DEBUG("The package%{public}s added", (bundleName + "/" + newAbility.name).c_str());
973            AccessibilityAbilityInitParams initParams;
974            Utils::Parse(newAbility, initParams);
975            std::shared_ptr<AccessibilityAbilityInfo> accessibilityInfo =
976                std::make_shared<AccessibilityAbilityInfo>(initParams);
977
978            std::string abilityId = accessibilityInfo->GetId();
979            if (GetAbilityAutoStartState(abilityId)) {
980                HILOG_DEBUG("auto start packageName is %{public}s.", bundleName.c_str());
981                uint32_t capabilities = CAPABILITY_GESTURE | CAPABILITY_KEY_EVENT_OBSERVER | CAPABILITY_RETRIEVE |
982                    CAPABILITY_TOUCH_GUIDE | CAPABILITY_ZOOM;
983                uint32_t resultCapabilities = accessibilityInfo->GetStaticCapabilityValues() & capabilities;
984                accessibilityInfo->SetCapabilityValues(resultCapabilities);
985                AddInstalledAbility(*accessibilityInfo);
986                hasNewExtensionAbility = true;
987                std::string uri = Utils::GetUri(bundleName, accessibilityInfo->GetName());
988                AddEnabledAbility(uri);
989                RemoveConnectingA11yAbility(uri);
990                continue;
991            }
992
993            AddInstalledAbility(*accessibilityInfo);
994            hasNewExtensionAbility = true;
995        }
996    }
997
998    if (hasNewExtensionAbility) {
999        HILOG_DEBUG("add new extension ability and update abilities.");
1000        UpdateAbilities();
1001    }
1002}
1003
1004void AccessibilityAccountData::ChangeAbility(const std::string &bundleName)
1005{
1006    HILOG_DEBUG("bundleName(%{public}s)", bundleName.c_str());
1007
1008    if (installedAbilities_.empty()) {
1009        HILOG_DEBUG("There is no installed abilities.");
1010        return;
1011    }
1012    std::vector<std::string> autoStartAbilities;
1013    for (auto &ability : installedAbilities_) {
1014        if (ability.GetPackageName() != bundleName) {
1015            continue;
1016        }
1017        if (GetAbilityAutoStartState(ability.GetId())) {
1018            autoStartAbilities.push_back(ability.GetId());
1019        }
1020    }
1021
1022    RemoveInstalledAbility(bundleName);
1023    AddAbility(bundleName);
1024
1025    for (auto &name : autoStartAbilities) {
1026        auto iter = installedAbilities_.begin();
1027        for (; iter != installedAbilities_.end(); ++iter) {
1028            if (name == iter->GetId()) {
1029                break;
1030            }
1031        }
1032        if (iter == installedAbilities_.end()) {
1033            SetAbilityAutoStartState(name, false);
1034        }
1035    }
1036}
1037
1038void AccessibilityAccountData::AddUITestClient(const sptr<IRemoteObject> &obj,
1039    const std::string &bundleName, const std::string &abilityName)
1040{
1041    HILOG_DEBUG();
1042    // Add installed ability
1043    std::shared_ptr<AccessibilityAbilityInfo> abilityInfo = std::make_shared<AccessibilityAbilityInfo>();
1044    abilityInfo->SetPackageName(bundleName);
1045    uint32_t capabilities = CAPABILITY_RETRIEVE | CAPABILITY_GESTURE;
1046    abilityInfo->SetCapabilityValues(capabilities);
1047    abilityInfo->SetAccessibilityAbilityType(ACCESSIBILITY_ABILITY_TYPE_ALL);
1048    abilityInfo->SetEventTypes(EventType::TYPES_ALL_MASK);
1049    AddInstalledAbility(*abilityInfo);
1050
1051    // Add connected ability
1052    sptr<AppExecFwk::ElementName> elementName = new(std::nothrow) AppExecFwk::ElementName();
1053    if (!elementName) {
1054        HILOG_ERROR("elementName is null");
1055        return;
1056    }
1057    elementName->SetBundleName(bundleName);
1058    elementName->SetAbilityName(abilityName);
1059    sptr<AccessibleAbilityConnection> connection = new(std::nothrow) AccessibleAbilityConnection(
1060        id_, connectCounter_++, *abilityInfo);
1061    if (!connection) {
1062        HILOG_ERROR("connection is null");
1063        return;
1064    }
1065    connection->OnAbilityConnectDoneSync(*elementName, obj);
1066}
1067
1068void AccessibilityAccountData::RemoveUITestClient(sptr<AccessibleAbilityConnection> &connection,
1069    const std::string &bundleName)
1070{
1071    HILOG_DEBUG();
1072    if (!connection) {
1073        HILOG_ERROR("connection is nullptr");
1074        return;
1075    }
1076    RemoveInstalledAbility(bundleName);
1077    RemoveConnectedAbility(connection->GetElementName());
1078    connection->OnAbilityDisconnectDoneSync(connection->GetElementName());
1079}
1080
1081AccountSA::OsAccountType AccessibilityAccountData::GetAccountType()
1082{
1083    return accountType_;
1084}
1085
1086void AccessibilityAccountData::AccessibilityAbility::AddAccessibilityAbility(const std::string& uri,
1087    const sptr<AccessibleAbilityConnection>& connection)
1088{
1089    HILOG_INFO("uri is %{private}s", uri.c_str());
1090    std::lock_guard<ffrt::mutex> lock(mutex_);
1091    if (!connectionMap_.count(uri)) {
1092        connectionMap_[uri] = connection;
1093        HILOG_DEBUG("connectionMap_ size %{public}zu", connectionMap_.size());
1094        return;
1095    }
1096
1097    HILOG_DEBUG("uri %{private}s, connectionMap_ %{public}zu", uri.c_str(), connectionMap_.size());
1098}
1099
1100void AccessibilityAccountData::AccessibilityAbility::RemoveAccessibilityAbilityByUri(const std::string& uri)
1101{
1102    HILOG_INFO("uri is %{private}s", uri.c_str());
1103    std::lock_guard<ffrt::mutex> lock(mutex_);
1104    auto it = connectionMap_.find(uri);
1105    if (it != connectionMap_.end()) {
1106        connectionMap_.erase(it);
1107    }
1108
1109    HILOG_DEBUG("connectionMap_ %{public}zu", connectionMap_.size());
1110}
1111
1112sptr<AccessibleAbilityConnection> AccessibilityAccountData::AccessibilityAbility::GetAccessibilityAbilityByName(
1113    const std::string& elementName)
1114{
1115    HILOG_DEBUG("elementName is %{public}s", elementName.c_str());
1116    std::lock_guard<ffrt::mutex> lock(mutex_);
1117    for (auto& connection : connectionMap_) {
1118        std::string::size_type index = connection.first.find(elementName);
1119        if (index == std::string::npos) {
1120            continue;
1121        } else {
1122            HILOG_DEBUG("uri %{private}s ", connection.first.c_str());
1123            return connection.second;
1124        }
1125    }
1126
1127    return nullptr;
1128}
1129
1130sptr<AccessibleAbilityConnection> AccessibilityAccountData::AccessibilityAbility::GetAccessibilityAbilityByUri(
1131    const std::string& uri)
1132{
1133    HILOG_DEBUG("uri is %{private}s", uri.c_str());
1134    std::lock_guard<ffrt::mutex> lock(mutex_);
1135    auto iter = connectionMap_.find(uri);
1136    if (iter != connectionMap_.end()) {
1137        return iter->second;
1138    }
1139    return nullptr;
1140}
1141
1142void AccessibilityAccountData::AccessibilityAbility::GetAccessibilityAbilities(
1143    std::vector<sptr<AccessibleAbilityConnection>>& connectionList)
1144{
1145    std::lock_guard<ffrt::mutex> lock(mutex_);
1146    for (auto& connection : connectionMap_) {
1147        connectionList.push_back(connection.second);
1148    }
1149}
1150
1151void AccessibilityAccountData::AccessibilityAbility::GetAbilitiesInfo(
1152    std::vector<AccessibilityAbilityInfo>& abilities)
1153{
1154    std::lock_guard<ffrt::mutex> lock(mutex_);
1155    for (auto& connection : connectionMap_) {
1156        if (connection.second) {
1157            abilities.push_back(connection.second->GetAbilityInfo());
1158        }
1159    }
1160
1161    HILOG_DEBUG("connectionMap_ %{public}zu and enabledAbilities %{public}zu",
1162        connectionMap_.size(), abilities.size());
1163}
1164
1165bool AccessibilityAccountData::AccessibilityAbility::IsExistCapability(Capability capability)
1166{
1167    HILOG_DEBUG("capability %{public}d", capability);
1168    std::lock_guard<ffrt::mutex> lock(mutex_);
1169    for (auto iter = connectionMap_.begin(); iter != connectionMap_.end(); iter++) {
1170        if (iter->second->GetAbilityInfo().GetCapabilityValues() & capability) {
1171            return true;
1172        }
1173    }
1174
1175    return false;
1176}
1177
1178void AccessibilityAccountData::AccessibilityAbility::GetAccessibilityAbilitiesMap(
1179    std::map<std::string, sptr<AccessibleAbilityConnection>>& connectionMap)
1180{
1181    std::lock_guard<ffrt::mutex> lock(mutex_);
1182    connectionMap = connectionMap_;
1183}
1184
1185void AccessibilityAccountData::AccessibilityAbility::Clear()
1186{
1187    std::lock_guard<ffrt::mutex> lock(mutex_);
1188    return connectionMap_.clear();
1189}
1190
1191size_t AccessibilityAccountData::AccessibilityAbility::GetSize()
1192{
1193    std::lock_guard<ffrt::mutex> lock(mutex_);
1194    return connectionMap_.size();
1195}
1196
1197void AccessibilityAccountData::AccessibilityAbility::GetDisableAbilities(
1198    std::vector<AccessibilityAbilityInfo> &disabledAbilities)
1199{
1200    std::lock_guard<ffrt::mutex> lock(mutex_);
1201    for (auto& connection : connectionMap_) {
1202        for (auto iter = disabledAbilities.begin(); iter != disabledAbilities.end();) {
1203            if (connection.second && (iter->GetId() == connection.second->GetAbilityInfo().GetId())) {
1204                iter = disabledAbilities.erase(iter);
1205            } else {
1206                iter++;
1207            }
1208        }
1209    }
1210}
1211
1212void AccessibilityAccountData::AccessibilityAbility::RemoveAccessibilityAbilityByName(const std::string& bundleName,
1213    bool& result)
1214{
1215    std::lock_guard<ffrt::mutex> lock(mutex_);
1216    for (auto& connection : connectionMap_) {
1217        std::size_t firstPos = connection.first.find_first_of('/') + 1;
1218        std::size_t endPos = connection.first.find_last_of('/');
1219        if (endPos <= firstPos) {
1220            HILOG_ERROR("it's a wrong ability and the uri %{public}s ", connection.first.c_str());
1221            continue;
1222        }
1223
1224        std::string connectedBundleName = connection.first.substr(firstPos, endPos - firstPos);
1225        if (connectedBundleName == bundleName) {
1226            HILOG_DEBUG("remove connected ability, bundle name %{public}s", connectedBundleName.c_str());
1227            std::string uri = Utils::GetUri(connection.second->GetElementName());
1228            auto it = connectionMap_.find(uri);
1229            if (it != connectionMap_.end()) {
1230                connectionMap_.erase(it);
1231            }
1232            result = true;
1233        }
1234    }
1235}
1236
1237int32_t AccessibilityAccountData::AccessibilityAbility::GetSizeByUri(const std::string& uri)
1238{
1239    std::lock_guard<ffrt::mutex> lock(mutex_);
1240    return connectionMap_.count(uri);
1241}
1242
1243sptr<AccessibilityAccountData> AccessibilityAccountDataMap::AddAccountData(
1244    int32_t accountId)
1245{
1246    std::lock_guard<ffrt::mutex> lock(accountDataMutex_);
1247    auto iter = accountDataMap_.find(accountId);
1248    if (iter != accountDataMap_.end()) {
1249        HILOG_WARN("accountId is existed");
1250        return iter->second;
1251    }
1252
1253    sptr<AccessibilityAccountData> accountData = new(std::nothrow) AccessibilityAccountData(accountId);
1254    if (accountData == nullptr) {
1255        HILOG_ERROR("accountData is null");
1256        return nullptr;
1257    }
1258
1259    accountData->Init();
1260    accountDataMap_[accountId] = accountData;
1261    return accountData;
1262}
1263
1264sptr<AccessibilityAccountData> AccessibilityAccountDataMap::GetCurrentAccountData(
1265    int32_t accountId)
1266{
1267    std::lock_guard<ffrt::mutex> lock(accountDataMutex_);
1268    auto iter = accountDataMap_.find(accountId);
1269    if (iter != accountDataMap_.end()) {
1270        return iter->second;
1271    }
1272
1273    sptr<AccessibilityAccountData> accountData = new(std::nothrow) AccessibilityAccountData(accountId);
1274    if (!accountData) {
1275        HILOG_ERROR("accountData is null");
1276        return nullptr;
1277    }
1278
1279    accountDataMap_[accountId] = accountData;
1280    return accountData;
1281}
1282
1283sptr<AccessibilityAccountData> AccessibilityAccountDataMap::GetAccountData(
1284    int32_t accountId)
1285{
1286    std::lock_guard<ffrt::mutex> lock(accountDataMutex_);
1287    auto iter = accountDataMap_.find(accountId);
1288    if (iter != accountDataMap_.end()) {
1289        return iter->second;
1290    }
1291
1292    HILOG_DEBUG("accountId is not existed");
1293    return nullptr;
1294}
1295
1296sptr<AccessibilityAccountData> AccessibilityAccountDataMap::RemoveAccountData(
1297    int32_t accountId)
1298{
1299    sptr<AccessibilityAccountData> accountData = nullptr;
1300    std::lock_guard<ffrt::mutex> lock(accountDataMutex_);
1301    auto iter = accountDataMap_.find(accountId);
1302    if (iter != accountDataMap_.end()) {
1303        accountData = iter->second;
1304        accountDataMap_.erase(iter);
1305    }
1306
1307    return accountData;
1308}
1309
1310std::vector<int32_t> AccessibilityAccountDataMap::GetAllAccountIds()
1311{
1312    std::lock_guard<ffrt::mutex> lock(accountDataMutex_);
1313    std::vector<int32_t> accountIds;
1314    for (auto it = accountDataMap_.begin(); it != accountDataMap_.end(); it++) {
1315        accountIds.push_back(it->first);
1316    }
1317    return accountIds;
1318}
1319
1320void AccessibilityAccountDataMap::Clear()
1321{
1322    std::lock_guard<ffrt::mutex> lock(accountDataMutex_);
1323    accountDataMap_.clear();
1324}
1325} // namespace Accessibility
1326} // namespace OHOS
1327