/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <array>
#include <iostream>
#include "accessibility_def.h"
#include "ani_accessibility_system_ability_client.h"
#include "ani_utils.h"
#include "hilog_wrapper.h"
#include <ani_signature_builder.h>

using namespace OHOS::Accessibility;
using namespace arkts::ani_signature;

constexpr int32_t ANI_SCOPE_SIZE = 16;
const std::string DEFAULT_FONT_FAMILY = "default";
constexpr uint32_t DEFAULT_FONT_SCALE = 75;
constexpr uint32_t DEFAULT_COLOR = 0xff000000;
const std::string DEFAULT_FONT_EDGE_TYPE = "none";

std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::accessibilityStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::touchGuideStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::screenReaderStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::touchModeStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED);
std::shared_ptr<AccessibilityCaptionsObserverImpl> ANIAccessibilityClient::captionListeners_ =
    std::make_shared<AccessibilityCaptionsObserverImpl>();
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::audioMonoStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_AUDIO_MONO);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::animationOffStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_ANIMATION_OFF);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::flashReminderSwitchStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_FLASH_REMINDER_SWITCH);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::seniorModeStateListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_ELDER_CARE_ENABLED);
std::shared_ptr<StateListenerImpl> ANIAccessibilityClient::seniorModeStateForAppListeners_ =
    std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_SELF_SENIOR_MODE_STATE_CHANGE);

void StateListenerImpl::SubscribeToFramework()
{
    HILOG_INFO("StateListenerImpl SubscribeFromFramework");
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient) {
        asaClient->SubscribeStateObserver(shared_from_this(), type_);
    }
}

void StateListenerImpl::UnsubscribeFromFramework()
{
    HILOG_INFO("StateListenerImpl UnsubscribeFromFramework");
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient) {
        asaClient->UnsubscribeStateObserver(shared_from_this(), type_);
    }
}

void StateListenerImpl::OnStateChanged(const bool state)
{
    HILOG_INFO("state is %{public}d, type = %{public}d", state, static_cast<int32_t>(type_));
    std::lock_guard<ffrt::mutex> lock(mutex_);
    std::string touchMode = "";
    if (type_ == AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED) {
        for (auto &observer : observers_) {
            touchMode = state ? "singleTouchMode" : "doubleTouchMode";
            observer->OnStateChanged(touchMode);
        }
        return;
    }

    for (auto &observer : observers_) {
        if (observer->isBoolObserver_) {
            observer->OnStateChanged(state);
        } else if (!state) {
            // notify the touch mode change
            touchMode = "none";
            observer->OnStateChanged(touchMode);
        }
    }
}

void AccessibilityCaptionsObserverImpl::SubscribeToFramework()
{
    HILOG_INFO("AccessibilityCaptionsObserverImpl SubscribeFromFramework");
    auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
    instance.SubscribeConfigObserver(OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE, shared_from_this(),
        false);
    instance.SubscribeConfigObserver(OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE, shared_from_this(),
        false);
}

void AccessibilityCaptionsObserverImpl::UnsubscribeFromFramework()
{
    HILOG_INFO("AccessibilityCaptionsObserverImpl UnsubscribeFromFramework");
    auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
    instance.UnsubscribeConfigObserver(OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE,
        shared_from_this());
    instance.UnsubscribeConfigObserver(OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE,
        shared_from_this());
}

void AccessibilityCaptionsObserverImpl::OnConfigChanged(const OHOS::AccessibilityConfig::CONFIG_ID id,
    const OHOS::AccessibilityConfig::ConfigValue& value)
{
    HILOG_INFO("captions OnConfigChanged, config id is %{public}d", static_cast<int32_t>(id));
    std::lock_guard<ffrt::mutex> lock(mutex_);
    for (auto &observer : observers_) {
        if (observer->configId_ == id) {
            observer->OnConfigChanged(value);
        }
    }
}

void StateListenerImpl::SubscribeObserver(ani_env *env, ani_object observer, bool isBoolObserver)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    ani_ref fnRef;
    env->GlobalReference_Create(observer, &fnRef);
    for (auto iter = observers_.begin(); iter != observers_.end(); iter++) {
        if (ANIUtils::CheckObserverEqual(env, fnRef, (*iter)->env_, (*iter)->fnRef_)) {
            env->GlobalReference_Delete(fnRef);
            HILOG_WARN("SubscribeObserver Observer exist");
            return;
        }
    }

    std::shared_ptr<StateListener> stateListener = std::make_shared<StateListener>(env, fnRef, isBoolObserver);
    observers_.emplace_back(stateListener);
    HILOG_INFO("observer size:%{public}zu", observers_.size());
}

void StateListenerImpl::UnsubscribeObserver(ani_env *env, ani_object observer)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    ani_ref fnRef;
    env->GlobalReference_Create(observer, &fnRef);
    for (auto iter = observers_.begin(); iter != observers_.end(); iter++) {
        if (ANIUtils::CheckObserverEqual(env, fnRef, (*iter)->env_, (*iter)->fnRef_)) {
            observers_.erase(iter);
            break;
        }
    }
    env->GlobalReference_Delete(fnRef);
    HILOG_WARN("UnsubscribeObserver Observer not exist");
}

void StateListenerImpl::UnsubscribeObservers()
{
    HILOG_INFO();
    std::lock_guard<ffrt::mutex> lock(mutex_);
    for (auto iter = observers_.begin(); iter != observers_.end(); iter++) {
        (*iter)->env_->GlobalReference_Delete((*iter)->fnRef_);
    }
    observers_.clear();
}

void AccessibilityCaptionsObserverImpl::SubscribeObserver(ani_env *env, OHOS::AccessibilityConfig::CONFIG_ID id,
    ani_object observer)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    ani_ref fnRef;
    env->GlobalReference_Create(observer, &fnRef);
    for (auto iter = observers_.begin(); iter != observers_.end(); iter++) {
        if (((*iter)->configId_ == id) && (ANIUtils::CheckObserverEqual(env, fnRef, (*iter)->env_, (*iter)->fnRef_))) {
            env->GlobalReference_Delete(fnRef);
            HILOG_WARN("SubscribeObserver Observer exist");
            return;
        }
    }

    std::shared_ptr<AccessibilityCaptionsObserver> captionsObserver = std::make_shared<AccessibilityCaptionsObserver>(
        env, fnRef, id);
    observers_.emplace_back(captionsObserver);
    HILOG_INFO("observer size:%{public}zu", observers_.size());
}

void AccessibilityCaptionsObserverImpl::UnsubscribeObserver(ani_env *env, OHOS::AccessibilityConfig::CONFIG_ID id,
    ani_object observer)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    ani_ref fnRef;
    env->GlobalReference_Create(observer, &fnRef);
    for (auto iter = observers_.begin(); iter != observers_.end(); iter++) {
        if (((*iter)->configId_ == id) && (ANIUtils::CheckObserverEqual(env, fnRef, (*iter)->env_, (*iter)->fnRef_))) {
            observers_.erase(iter);
            break;
        }
    }
    env->GlobalReference_Delete(fnRef);
    HILOG_WARN("UnsubscribeObserver Observer not exist");
}

void AccessibilityCaptionsObserverImpl::UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID id)
{
    HILOG_INFO();
    std::lock_guard<ffrt::mutex> lock(mutex_);
    for (auto iter = observers_.begin(); iter != observers_.end();) {
        if ((*iter)->configId_ == id) {
            (*iter)->env_->GlobalReference_Delete((*iter)->fnRef_);
            iter = observers_.erase(iter);
        } else {
            iter++;
        }
    }
}

void StateListener::NotifyETS(ani_env *env, bool state, ani_ref fnRef)
{
    HILOG_INFO("state = [%{public}s]", state ? "true" : "false");
    
    std::shared_ptr<ANIStateCallbackInfo> callbackInfo = std::make_shared<ANIStateCallbackInfo>();
    if (callbackInfo == nullptr) {
        HILOG_ERROR("Failed to create callbackInfo");
        return;
    }
    callbackInfo->state_ = state;
    callbackInfo->env_ = env;
    callbackInfo->fnRef_ = fnRef;
    auto task = [callbackInfo]() {
        HILOG_INFO("notify state changed to ets");
        ani_env *tmpEnv = callbackInfo->env_;
        ani_size nr_refs = ANI_SCOPE_SIZE;
        tmpEnv->CreateLocalScope(nr_refs);
        auto fnObj = reinterpret_cast<ani_fn_object>(callbackInfo->fnRef_);
        ani_object state = ANIUtils::CreateBoolObject(tmpEnv, static_cast<ani_boolean>(callbackInfo->state_));
        if (state == nullptr) {
            HILOG_ERROR("create boolean object failed");
            tmpEnv->DestroyLocalScope();
            return;
        }
        std::vector<ani_ref> args = {reinterpret_cast<ani_ref>(state)};
        ani_ref result;
        tmpEnv->FunctionalObject_Call(fnObj, 1, args.data(), &result);
        tmpEnv->DestroyLocalScope();
    };
    if (!ANIUtils::SendEventToMainThread(task)) {
        HILOG_ERROR("failed to send event");
    }
}

void StateListener::NotifyETS(ani_env *env, std::string mode, ani_ref fnRef)
{
    HILOG_INFO("mode = [%{public}s]", mode.c_str());
    std::shared_ptr<ANIStateCallbackInfo> callbackInfo = std::make_shared<ANIStateCallbackInfo>();
    if (callbackInfo == nullptr) {
        HILOG_ERROR("Failed to create callbackInfo");
        return;
    }
    callbackInfo->stringValue_ = mode;
    callbackInfo->env_ = env;
    callbackInfo->fnRef_ = fnRef;
    auto task = [callbackInfo]() {
        HILOG_INFO("notify mode changed to ets");
        ani_env *tmpEnv = callbackInfo->env_;
        ani_size nr_refs = ANI_SCOPE_SIZE;
        tmpEnv->CreateLocalScope(nr_refs);
        auto fnObj = reinterpret_cast<ani_fn_object>(callbackInfo->fnRef_);
        ani_string state = ANIUtils::CreateAniString(tmpEnv, callbackInfo->stringValue_);
        if (state == nullptr) {
            HILOG_ERROR("create boolean object failed");
            tmpEnv->DestroyLocalScope();
            return;
        }
        std::vector<ani_ref> args = {reinterpret_cast<ani_ref>(state)};
        ani_ref result;
        tmpEnv->FunctionalObject_Call(fnObj, 1, args.data(), &result);
        tmpEnv->DestroyLocalScope();
    };
    if (!ANIUtils::SendEventToMainThread(task)) {
        HILOG_ERROR("failed to send event");
    }
}

void AccessibilityCaptionsObserver::NotifyCaptionsStateToETS(ani_env *env, bool state, ani_ref fnRef)
{
    HILOG_INFO("captions state = [%{public}s]", state ? "true" : "false");
    
    std::shared_ptr<ANIStateCallbackInfo> callbackInfo = std::make_shared<ANIStateCallbackInfo>();
    if (callbackInfo == nullptr) {
        HILOG_ERROR("Failed to create callbackInfo");
        return;
    }
    callbackInfo->state_ = state;
    callbackInfo->env_ = env;
    callbackInfo->fnRef_ = fnRef;
    auto task = [callbackInfo]() {
        HILOG_INFO("notify captions state changed to ets");
        ani_env *tmpEnv = callbackInfo->env_;
        ani_size nr_refs = ANI_SCOPE_SIZE;
        tmpEnv->CreateLocalScope(nr_refs);
        auto fnObj = reinterpret_cast<ani_fn_object>(callbackInfo->fnRef_);
        ani_object state = ANIUtils::CreateBoolObject(tmpEnv, static_cast<ani_boolean>(callbackInfo->state_));
        if (state == nullptr) {
            HILOG_ERROR("create boolean object failed");
            tmpEnv->DestroyLocalScope();
            return;
        }
        std::vector<ani_ref> args = {reinterpret_cast<ani_ref>(state)};
        ani_ref result;
        tmpEnv->FunctionalObject_Call(fnObj, 1, args.data(), &result);
        tmpEnv->DestroyLocalScope();
    };
    if (!ANIUtils::SendEventToMainThread(task)) {
        HILOG_ERROR("failed to send event");
    }
}

void AccessibilityCaptionsObserver::NotifyCaptionsStyleToETS(ani_env *env,
    OHOS::AccessibilityConfig::CaptionProperty style, ani_ref fnRef)
{
    HILOG_INFO("notify captions style");
    
    std::shared_ptr<ANICaptionCallbackInfo> callbackInfo = std::make_shared<ANICaptionCallbackInfo>();
    if (callbackInfo == nullptr) {
        HILOG_ERROR("Failed to create callbackInfo");
        return;
    }
    callbackInfo->caption_ = style;
    callbackInfo->env_ = env;
    callbackInfo->fnRef_ = fnRef;
    auto task = [callbackInfo]() {
        HILOG_INFO("notify captions style changed to ets");
        ani_env *tmpEnv = callbackInfo->env_;
        ani_size nr_refs = ANI_SCOPE_SIZE;
        tmpEnv->CreateLocalScope(nr_refs);
        auto fnObj = reinterpret_cast<ani_fn_object>(callbackInfo->fnRef_);
        ani_object caption = ANIAccessibilityClient::CreateAccessibilityCaptionProperty(tmpEnv, callbackInfo->caption_);
        if (caption == nullptr) {
            HILOG_ERROR("create caption style object failed");
            tmpEnv->DestroyLocalScope();
            return;
        }
        std::vector<ani_ref> args = {reinterpret_cast<ani_ref>(caption)};
        ani_ref result;
        tmpEnv->FunctionalObject_Call(fnObj, 1, args.data(), &result);
        tmpEnv->DestroyLocalScope();
    };
    if (!ANIUtils::SendEventToMainThread(task)) {
        HILOG_ERROR("failed to send event");
    }
}

void StateListener::OnStateChanged(const bool state)
{
    NotifyETS(env_, state, fnRef_);
}

void StateListener::OnStateChanged(const std::string mode)
{
    NotifyETS(env_, mode, fnRef_);
}

void AccessibilityCaptionsObserver::OnConfigChanged(const OHOS::AccessibilityConfig::ConfigValue& value)
{
    if (configId_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE) {
        NotifyCaptionsStateToETS(env_, value.captionState, fnRef_);
    } else if (configId_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE) {
        NotifyCaptionsStyleToETS(env_, value.captionStyle, fnRef_);
    } else {
        HILOG_ERROR("configId_ is invalid");
        return;
    }
}

void ANIAccessibilityClient::SubscribeState(ani_env *env, ani_string type, ani_object callback)
{
    std::string eventType = ANIUtils::ANIStringToStdString(env, type);
    HILOG_DEBUG("SubscribeState:%{public}s", eventType.c_str());
    if (std::strcmp(eventType.c_str(), "accessibilityStateChange") == 0) {
        accessibilityStateListeners_->SubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "touchGuideStateChange") == 0) {
        touchGuideStateListeners_->SubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "screenReaderStateChange") == 0) {
        screenReaderStateListeners_->SubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "touchModeChange") == 0) {
        touchModeStateListeners_->SubscribeObserver(env, callback);
        touchGuideStateListeners_->SubscribeObserver(env, callback, false);
    } else if (std::strcmp(eventType.c_str(), "audioMonoStateChange") == 0) {
        audioMonoStateListeners_->SubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "animationReduceStateChange") == 0) {
        animationOffStateListeners_->SubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "flashReminderStateChange") == 0) {
        flashReminderSwitchStateListeners_->SubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "seniorModeStateChange") == 0) {
        seniorModeStateListeners_->SubscribeObserver(env, callback);
    } else {
        HILOG_ERROR("SubscribeState eventType[%{public}s] is error", eventType.c_str());
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
    }
}

void ANIAccessibilityClient::UnsubscribeState(ani_env *env, ani_string type, ani_object callback)
{
    std::string eventType = ANIUtils::ANIStringToStdString(env, type);
    HILOG_DEBUG("UnsubscribeState:%{public}s", eventType.c_str());
    if (std::strcmp(eventType.c_str(), "accessibilityStateChange") == 0) {
        accessibilityStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "touchGuideStateChange") == 0) {
        touchGuideStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "screenReaderStateChange") == 0) {
        screenReaderStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "touchModeChange") == 0) {
        touchModeStateListeners_->UnsubscribeObserver(env, callback);
        touchGuideStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "audioMonoStateChange") == 0) {
        audioMonoStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "animationReduceStateChange") == 0) {
        animationOffStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "flashReminderStateChange") == 0) {
        flashReminderSwitchStateListeners_->UnsubscribeObserver(env, callback);
    } else if (std::strcmp(eventType.c_str(), "seniorModeStateChange") == 0) {
        seniorModeStateListeners_->UnsubscribeObserver(env, callback);
    } else {
        HILOG_ERROR("UnsubscribeState eventType[%{public}s] is error", eventType.c_str());
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
    }
}

void ANIAccessibilityClient::UnsubscribeStateAll(ani_env *env, ani_string type)
{
    std::string eventType = ANIUtils::ANIStringToStdString(env, type);
    HILOG_DEBUG("UnsubscribeStateAll:%{public}s", eventType.c_str());
    if (std::strcmp(eventType.c_str(), "accessibilityStateChange") == 0) {
        accessibilityStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "touchGuideStateChange") == 0) {
        touchGuideStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "screenReaderStateChange") == 0) {
        screenReaderStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "touchModeChange") == 0) {
        touchModeStateListeners_->UnsubscribeObservers();
        touchGuideStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "audioMonoStateChange") == 0) {
        audioMonoStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "animationReduceStateChange") == 0) {
        animationOffStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "flashReminderStateChange") == 0) {
        flashReminderSwitchStateListeners_->UnsubscribeObservers();
    } else if (std::strcmp(eventType.c_str(), "seniorModeStateChange") == 0) {
        seniorModeStateListeners_->UnsubscribeObservers();
    } else {
        HILOG_ERROR("UnsubscribeStateAll eventType[%{public}s] is error", eventType.c_str());
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
    }
}

void ANIAccessibilityClient::SubscribeEnableChange(ani_env *env, ani_object object, ani_object callback)
{
    HILOG_INFO();
    captionListeners_->SubscribeObserver(env, OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE, callback);
}

void ANIAccessibilityClient::SubscribeStyleChange(ani_env *env, ani_object object, ani_object callback)
{
    HILOG_INFO();
    captionListeners_->SubscribeObserver(env, OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE, callback);
}

void ANIAccessibilityClient::UnsubscribeEnableChangeWithCallback(ani_env *env, ani_object object, ani_object callback)
{
    HILOG_INFO();
    captionListeners_->UnsubscribeObserver(env, OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE, callback);
}

void ANIAccessibilityClient::UnsubscribeStyleChangeWithCallback(ani_env *env, ani_object object, ani_object callback)
{
    HILOG_INFO();
    captionListeners_->UnsubscribeObserver(env, OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE, callback);
}

void ANIAccessibilityClient::UnsubscribeEnableChangeAll(ani_env *env, ani_object object)
{
    HILOG_INFO();
    captionListeners_->UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE);
}

void ANIAccessibilityClient::UnsubscribeStyleChangeAll(ani_env *env, ani_object object)
{
    HILOG_INFO();
    captionListeners_->UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE);
}

ani_boolean ANIAccessibilityClient::IsOpenTouchGuideSync([[maybe_unused]] ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->IsTouchExplorationEnabled(status);
    if (ret != RET_OK) {
        HILOG_ERROR("get touch guide state failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }

    return status;
}

ani_boolean ANIAccessibilityClient::IsOpenAccessibilitySync([[maybe_unused]] ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->IsEnabled(status);
    if (ret != RET_OK) {
        HILOG_ERROR("get accessibility state failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }

    return status;
}

ani_boolean ANIAccessibilityClient::IsScreenReaderOpenSync([[maybe_unused]] ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->IsScreenReaderEnabled(status);
    if (ret != RET_OK) {
        HILOG_ERROR("get screen reader state failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }

    return status;
}

ani_string ANIAccessibilityClient::getTouchModeSync([[maybe_unused]] ani_env *env)
{
    ani_string retResult = nullptr;
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
        return nullptr;
    }
    std::string touchMode = "";
    asaClient->GetTouchMode(touchMode);
    env->String_NewUTF8(touchMode.c_str(), touchMode.size(), &retResult);
    return retResult;
}

ani_object ANIAccessibilityClient::CreateJsOtherInfoInner(ani_env *env, ani_class cls,
    ani_object &object, AccessibilityAbilityInfo &info)
{
    if (!ANIUtils::SetStringProperty(env, object, ABILITY_INFO_DESCRIPTION, info.GetDescription())) {
        HILOG_ERROR("set description failed");
        return nullptr;
    }
    uint32_t eventTypesValue = info.GetEventTypes();
    std::vector<std::string> eventTypes = ParseEventTypesToVec(eventTypesValue);
    if (eventTypes.size() > 0) {
        ANIUtils::SetStringArrayProperty(env, object, ABILITY_INFO_EVENT_TYPES, eventTypes);
    }
    ani_status status;
    if ((status = env->Object_SetPropertyByName_Boolean(object, ABILITY_INFO_NEED_HIDE, info.NeedHide())) != ANI_OK) {
        HILOG_ERROR("set needHide failed status=%{public}d", status);
        return nullptr;
    }

    if (!ANIUtils::SetStringProperty(env, object, ABILITY_INFO_LABEL, info.GetLabel())) {
        HILOG_ERROR("set label failed");
        return nullptr;
    }
    return object;
}

ani_object ANIAccessibilityClient::CreateJsAccessibilityAbilityInfoInner(ani_env *env, ani_class cls,
    ani_object &object, AccessibilityAbilityInfo &info)
{
    if (env == nullptr || cls == nullptr || object == nullptr) {
        HILOG_ERROR("invalid args");
        return nullptr;
    }

    if (!ANIUtils::SetStringProperty(env, object, ABILITY_INFO_ID, info.GetId())) {
        HILOG_ERROR("set id failed id");
        return nullptr;
    }
    if (!ANIUtils::SetStringProperty(env, object, ABILITY_INFO_NAME, info.GetName())) {
        HILOG_ERROR("set name failed");
        return nullptr;
    }

    if (!ANIUtils::SetStringProperty(env, object, ABILITY_INFO_BUNDLE_NAME, info.GetPackageName())) {
        HILOG_ERROR("set bundleName failed");
        return nullptr;
    }
    std::vector<std::string> filterNames = info.GetFilterBundleNames();
    if (filterNames.size() > 0) {
        ANIUtils::SetStringArrayProperty(env, object, ABILITY_INFO_TARGET_BUNDLE_NAMES, filterNames);
    }
    std::vector<std::string> abilityTypes = ParseAbilityTypesToVec(info.GetAccessibilityAbilityType());
    if (abilityTypes.size() > 0) {
        ANIUtils::SetStringArrayProperty(env, object, ABILITY_INFO_ABILITY_TYPES, abilityTypes);
    }
    std::vector<std::string> capabilities = ParseCapabilitiesToVec(info.GetStaticCapabilityValues());
    if (capabilities.size() > 0) {
        ANIUtils::SetStringArrayProperty(env, object, ABILITY_INFO_CAPABILITIES, capabilities);
    }
    return CreateJsOtherInfoInner(env, cls, object, info);
}

ani_object ANIAccessibilityClient::CreateJsAccessibilityAbilityInfo(ani_env *env,
    AccessibilityAbilityInfo &info)
{
    HILOG_DEBUG();
    ani_class cls = nullptr;
    ani_status status = ANI_ERROR;
    ani_method ctor = nullptr;
    ani_object object = nullptr;

    if ((status = env->FindClass(Builder::BuildClass("@ohos.accessibility.accessibility.AccessibilityAbilityInfoImpl")
        .Descriptor().c_str(), &cls)) != ANI_OK || cls == nullptr) {
        HILOG_ERROR("FindClass status : %{public}d or null cls", status);
        return nullptr;
    }
    std::string ctorName = Builder::BuildConstructorName();
    SignatureBuilder sb{};
    if ((status = env->Class_FindMethod(cls, ctorName.c_str(), sb.BuildSignatureDescriptor().c_str(), &ctor)) != ANI_OK
        || ctor == nullptr) {
        HILOG_ERROR("Class_FindMethod Constructor fail : %{public}d or null ctor", status);
        return nullptr;
    }
    if ((status = env->Object_New(cls, ctor, &object)) != ANI_OK || object == nullptr) {
        HILOG_ERROR("Object_New status : %{public}d or null cls", status);
        return nullptr;
    }

    return CreateJsAccessibilityAbilityInfoInner(env, cls, object, info);
}

ani_object ANIAccessibilityClient::ConvertAccessibleAbilityInfosToJs(ani_env *env,
    std::vector<AccessibilityAbilityInfo> &accessibleAbilityInfos)
{
    if (accessibleAbilityInfos.empty()) {
        HILOG_ERROR("convert accessible ability infos accessibleAbilityInfos empty");
        return nullptr;
    }
    ani_ref undefinedRef = nullptr;
    if (env->GetUndefined(&undefinedRef) != ANI_OK) {
        HILOG_ERROR("GetUndefined Failed.");
    }
    ani_array aniArray;
    env->Array_New(accessibleAbilityInfos.size(), undefinedRef, &aniArray);
    if (aniArray == nullptr) {
        HILOG_ERROR("ConvertAccessibleAbilityInfosToJs array is null");
        return nullptr;
    }
    ani_size index = 0;
    for (auto &abilityInfo : accessibleAbilityInfos) {
        ani_ref ani_info = CreateJsAccessibilityAbilityInfo(env, abilityInfo);
        if (ani_info == nullptr) {
            HILOG_ERROR("ConvertAccessibleAbilityInfosToJs obj is null");
            return nullptr;
        }
        auto status = env->Array_Set(aniArray, index, ani_info);
        if (status != ANI_OK) {
            HILOG_ERROR("Object_CallMethodByName_Void failed  --%{public}d ", status);
            return nullptr;
        }
        index++;
    }
    return aniArray;
}

ani_object ANIAccessibilityClient::GetAccessibilityExtensionListSync(ani_env *env, ani_string abilityType,
    ani_string stateType)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return nullptr;
    }
    std::string abilityTypeStr = ANIUtils::ANIStringToStdString(env, abilityType);
    std::string stateTypeStr = ANIUtils::ANIStringToStdString(env, stateType);

    RetError errCode = RET_OK;
    AbilityStateType stateTypes = ABILITY_STATE_INVALID;
    uint32_t abilityTypes = 0;

    HILOG_INFO("abilityTypeStr = %{public}s", abilityTypeStr.c_str());
    if (CheckAbilityType(abilityTypeStr)) {
        abilityTypes = ConvertStringToAccessibilityAbilityTypes(abilityTypeStr);
    } else {
        errCode = RET_ERR_INVALID_PARAM;
    }

    // parse ability state
    if (CheckStateType(stateTypeStr)) {
        stateTypes = ConvertStringToAbilityStateType(stateTypeStr);
    } else {
        errCode = RET_ERR_INVALID_PARAM;
    }

    std::vector<AccessibilityAbilityInfo> accessibilityAbilityList{};
    if (errCode == RET_OK) {
        auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
        if (asaClient) {
            errCode = asaClient->GetAbilityList(abilityTypes, stateTypes, accessibilityAbilityList);
        }
    }

    if (errCode != RET_OK) {
        HILOG_ERROR("get accessibility ability list failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
        return nullptr;
    }

    ani_object aniArray = ConvertAccessibleAbilityInfosToJs(env, accessibilityAbilityList);
    if (aniArray == nullptr) {
        HILOG_WARN("get accessibility extension list convert null aniArray");
    }
    return aniArray;
}

ani_object ANIAccessibilityClient::GetCaptionsManager(ani_env *env)
{
    HILOG_INFO();
    ani_class cls = nullptr;
    ani_status status = ANI_ERROR;
    ani_method ctor = nullptr;
    ani_object object = nullptr;

    if ((env->FindClass(Builder::BuildClass("@ohos.accessibility.accessibility.CaptionsManagerImpl")
        .Descriptor().c_str(), &cls)) != ANI_OK || cls == nullptr) {
        HILOG_ERROR("FindClass CaptionsManagerImpl failed");
        return nullptr;
    }
    std::string ctorName = Builder::BuildConstructorName();
    SignatureBuilder sb{};
    if ((env->Class_FindMethod(cls, ctorName.c_str(), sb.BuildSignatureDescriptor().c_str(), &ctor)) != ANI_OK ||
        ctor == nullptr) {
        HILOG_ERROR("Class CaptionsManagerImpl find constructor failed");
        return nullptr;
    }
    if ((env->Object_New(cls, ctor, &object)) != ANI_OK || object == nullptr) {
        HILOG_ERROR("create CaptionsManagerImpl failed");
        return nullptr;
    }
    return object;
}

ani_boolean ANIAccessibilityClient::GetAudioMonoStateSync(ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->GetAudioMonoState(status);
    if (ret != RET_OK) {
        HILOG_ERROR("GetAudioMonoState failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }
    return status;
}

ani_boolean ANIAccessibilityClient::GetAnimationOffStateSync(ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->GetAnimationOffState(status);
    if (ret != RET_OK) {
        HILOG_ERROR("GetAnimationOffState failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }
    return status;
}

ani_boolean ANIAccessibilityClient::GetFlashReminderSwitchSync(ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->GetFlashReminderSwitch(status);
    if (ret != RET_OK) {
        HILOG_ERROR("GetFlashReminderSwitch failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }
    return status;
}

ani_boolean ANIAccessibilityClient::GetSeniorModeStateSync(ani_env *env)
{
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool status = false;
    auto ret = asaClient->GetSeniorModeState(status);
    if (ret != RET_OK) {
        HILOG_ERROR("GetSeniorModeState failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }
    return status;
}

ani_boolean ANIAccessibilityClient::GetEnabled(ani_env *env, ani_object object)
{
    auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
    bool state = false;
    RetError ret = instance.GetCaptionsState(state, false);
    if (ret != RET_OK) {
        HILOG_ERROR("GetEnabled failed, ret = %{public}d", static_cast<int32_t>(ret));
        return false;
    }
    HILOG_INFO("GetEnabled successful, state = %{public}d", static_cast<int32_t>(state));
    return static_cast<ani_boolean>(state);
}

void ANIAccessibilityClient::SetEnabled(ani_env *env, ani_object object, ani_boolean enabled)
{
    auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
    RetError ret = instance.SetCaptionsState(enabled, false);
    if (ret != RET_OK) {
        HILOG_ERROR("SetEnabled failed, ret = %{public}d", static_cast<int32_t>(ret));
        return;
    }
    HILOG_INFO("SetEnabled successful, state = %{public}d", static_cast<int32_t>(enabled));
    return;
}

ani_object ANIAccessibilityClient::GetStyle(ani_env *env, ani_object object)
{
    auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
    OHOS::AccessibilityConfig::CaptionProperty captionProperty;
    RetError ret = instance.GetCaptionsProperty(captionProperty, false);
    if (ret != RET_OK) {
        HILOG_ERROR("GetStyle failed, ret = %{public}d", static_cast<int32_t>(ret));
        return nullptr;
    }

    HILOG_INFO("GetStyle successful");
    return CreateAccessibilityCaptionProperty(env, captionProperty);
}

ani_object ANIAccessibilityClient::CreateAccessibilityCaptionProperty(ani_env *env,
    OHOS::AccessibilityConfig::CaptionProperty &captionProperty)
{
    arkts::ani_signature::Type className =
        arkts::ani_signature::Builder::BuildClass("@ohos.accessibility.accessibility.CaptionsStyleImpl");
    ani_class cls;
    if (env->FindClass(className.Descriptor().c_str(), &cls) != ANI_OK) {
        HILOG_ERROR("Class CaptionsStyleImpl not found");
        return nullptr;
    }
    ani_method ctor;
    if (env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor) != ANI_OK) {
        HILOG_ERROR("Find method '<ctor>' failed");
        return nullptr;
    }

    ani_object object;
    if (env->Object_New(cls, ctor, &object) != ANI_OK) {
        HILOG_ERROR("New object fail");
        return nullptr;
    }

    return CreateCaptionPropertyInfoInner(env, cls, object, captionProperty);
}

ani_object ANIAccessibilityClient::CreateCaptionPropertyInfoInner(ani_env *env, ani_class cls,
    ani_object &object, OHOS::AccessibilityConfig::CaptionProperty &captionProperty)
{
    if (env == nullptr || cls == nullptr || object == nullptr) {
        HILOG_ERROR("invalid args");
        return nullptr;
    }

    if (!ANIUtils::SetStringProperty(env, object, "fontFamily", captionProperty.GetFontFamily())) {
        HILOG_ERROR("set fontFamily failed");
    }
    if (!ANIUtils::SetStringProperty(env, object, "fontEdgeType", captionProperty.GetFontEdgeType())) {
        HILOG_ERROR("set fontEdgeType failed");
    }
    if (env->Object_SetPropertyByName_Int(object, "fontScale", captionProperty.GetFontScale()) != ANI_OK) {
        HILOG_ERROR("Set property fontScale failed");
    }

    if (!ANIUtils::SetStringProperty(env, object, "fontColor",
        ConvertColorToString(captionProperty.GetFontColor()))) {
        HILOG_ERROR("Set property fontColor failed");
    }

    if (!ANIUtils::SetStringProperty(env, object, "backgroundColor",
        ConvertColorToString(captionProperty.GetBackgroundColor()))) {
        HILOG_ERROR("Set property backgroundColor failed");
    }

    if (!ANIUtils::SetStringProperty(env, object, "windowColor",
        ConvertColorToString(captionProperty.GetWindowColor()))) {
        HILOG_ERROR("Set property windowColor failed");
    }

    return object;
}

void ANIAccessibilityClient::SetStyle(ani_env *env, ani_object object, ani_object style)
{
    OHOS::AccessibilityConfig::CaptionProperty captionProperty;
    std::string fontFamily = DEFAULT_FONT_FAMILY;
    uint32_t fontScale = DEFAULT_FONT_SCALE;
    uint32_t fontColor = DEFAULT_COLOR;
    std::string fontEdgeType = DEFAULT_FONT_EDGE_TYPE;
    uint32_t backgroundColor = DEFAULT_COLOR;
    uint32_t windowColor = DEFAULT_COLOR;
    ani_boolean isUndefined = true;
    if (env->Reference_IsUndefined(style, &isUndefined) != ANI_OK) {
        HILOG_ERROR("SetSyncCaptionsStyle Reference_IsUndefined");
        return;
    }

    if (!isUndefined) {
        RETURN_IF_FALSE(ANIUtils::GetStringMember(env, style, "fontFamily", fontFamily));
        RETURN_IF_FALSE(ANIUtils::GetColorMember(env, style, "fontColor", fontColor));
        RETURN_IF_FALSE(ANIUtils::GetStringMember(env, style, "fontEdgeType", fontEdgeType));
        RETURN_IF_FALSE(ANIUtils::GetColorMember(env, style, "backgroundColor", backgroundColor));
        RETURN_IF_FALSE(ANIUtils::GetColorMember(env, style, "windowColor", windowColor));
        int styleValue = 0;
        if ((env->Object_GetPropertyByName_Int(style, "fontScale", &styleValue) != ANI_OK) || (styleValue < 0)) {
            HILOG_ERROR("Get property failed");
            return;
        }
        fontScale = static_cast<uint32_t>(styleValue);
    }

    auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
    captionProperty.SetFontFamily(fontFamily);
    captionProperty.SetFontScale(fontScale);
    captionProperty.SetFontColor(fontColor);
    captionProperty.SetFontEdgeType(fontEdgeType);
    captionProperty.SetBackgroundColor(backgroundColor);
    captionProperty.SetWindowColor(windowColor);
    auto ret = instance.SetCaptionsProperty(captionProperty, false);
    HILOG_INFO("SetSyncCaptionsStyle ret = %{public}d", static_cast<int32_t>(ret));
    return;
}

void ANIAccessibilityClient::SendAccessibilityEvent(ani_env *env, ani_object eventObject)
{
    AccessibilityEventInfo eventInfo {};

    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
        return;
    }

    bool ret = ANIUtils::ConvertEventInfoMandatoryFields(env, eventObject, eventInfo);
    if (!ret) {
        HILOG_ERROR("ConvertEventInfoMandatoryFields failed");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_INVALID_PARAM));
        return;
    }

    ANIUtils::ConvertEventInfoStringFields(env, eventObject, eventInfo);
    ANIUtils::ConvertEventInfoIntFields(env, eventObject, eventInfo);
    ANIUtils::ConvertEventInfoRefFields(env, eventObject, eventInfo);

    auto result = asaClient->SendEvent(eventInfo);
    if (result != RET_OK) {
        HILOG_ERROR("SendAccessibilityEvent failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(result));
    }
    return;
}

void ANIAccessibilityClient::OnSeniorModeStateChangeForSelfSync(ani_env *env, ani_object observer)
{
    HILOG_INFO("OnSeniorModeStateChangeForSelf");
    seniorModeStateForAppListeners_->SubscribeObserver(env, observer);
}

void ANIAccessibilityClient::OffSeniorModeStateChangeForSelfSync(ani_env *env, ani_object observer)
{
    HILOG_INFO("OffSeniorModeStateChangeForSelf");
    ani_boolean isUndefined = true;
    if (env->Reference_IsUndefined(observer, &isUndefined) != ANI_OK) {
        HILOG_ERROR("OffSeniorModeStateChangeForSelf Reference_IsUndefined failed");
        return;
    }

    if (!isUndefined) {
        seniorModeStateForAppListeners_->UnsubscribeObserver(env, observer);
    } else {
        seniorModeStateForAppListeners_->UnsubscribeObservers();
    }
}

ani_boolean ANIAccessibilityClient::GetSeniorModeStateForSelfSync(ani_env *env)
{
    HILOG_INFO("GetSeniorModeStateForSelf");
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return false;
    }
    bool state = false;
    auto ret = asaClient->GetSeniorModeStateForApp(state);
    if (ret != RET_OK) {
        HILOG_ERROR("GetSeniorModeStateForApp failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return false;
    }
    HILOG_INFO("GetSeniorModeStateForSelf state: %{public}d", state);
    return state;
}

void ANIAccessibilityClient::SetSeniorModeStateForSelfSync(ani_env *env, ani_boolean state)
{
    HILOG_INFO("SetSeniorModeStateForSelf state: %{public}d", state);
    auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
    if (asaClient == nullptr) {
        HILOG_ERROR("asaClient is nullptr!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_NULLPTR));
        return;
    }
    auto ret = asaClient->SetSeniorModeStateForApp(state);
    if (ret != RET_OK) {
        HILOG_ERROR("SetSeniorModeStateForApp failed!");
        ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(RET_ERR_FAILED));
        return;
    }
    HILOG_INFO("SetSeniorModeStateForSelf success");
}