提供闪烁能力的接口

Signed-off-by: chenrui_wza <chenrui129@h-partners.com>

CO-authored-by: OpenCode+GLM5
This commit is contained in:
chenrui_wza
2026-07-17 11:51:03 +08:00
parent f44210547c
commit 7641968bb6
36 changed files with 2398 additions and 7 deletions
+31
View File
@@ -22,6 +22,9 @@ declare_args() {
accessibility_feature_hiviewdfx_hitrace = true
accessibility_feature_hiviewdfx_hisysevent = true
accessibility_dynamic_support = false
accessibility_camera_support = false
accessibility_screenlock_manager = false
accessibility_sensor_support = false
security_component_enable = false
if (defined(global_parts_info) &&
!defined(global_parts_info.powermgr_display_manager)) {
@@ -55,6 +58,22 @@ declare_args() {
defined(global_parts_info.security_security_component_manager)) {
security_component_enable = true
}
if (defined(global_parts_info) &&
defined(global_parts_info.multimedia_camera_framework) &&
global_parts_info.multimedia_camera_framework) {
accessibility_camera_support = true
}
if (defined(global_parts_info) &&
defined(global_parts_info.theme_screenlock_mgr)) {
accessibility_screenlock_manager = true
}
if (defined(global_parts_info) &&
defined(global_parts_info.sensors_sensor)) {
accessibility_sensor_support = true
}
}
print(
@@ -104,4 +123,16 @@ if (product_name != "qemu-arm-linux-min") {
if (security_component_enable) {
accessibility_default_defines += [ "ACCESSIBILITY_SECURITY_COMPONENT" ]
}
if (accessibility_camera_support) {
accessibility_default_defines += [ "OHOS_BUILD_ENABLE_CAMERA" ]
}
if (accessibility_screenlock_manager) {
accessibility_default_defines += [ "OHOS_BUILD_ENABLE_SCREENLOCK_MANAGER" ]
}
if (accessibility_sensor_support) {
accessibility_default_defines += [ "OHOS_BUILD_ENABLE_SENSOR" ]
}
+6 -1
View File
@@ -75,9 +75,13 @@
"time_service",
"json",
"ets_frontend",
"sensor",
"camera_framework",
"screenlock_mgr",
"image_framework",
"node",
"libuv"
"libuv",
"call_manager"
],
"third_party": []
},
@@ -101,6 +105,7 @@
"//foundation/barrierfree/accessibility/services/aams:accessibleabilityms",
"//foundation/barrierfree/accessibility/services/etc:ohos.para.dac",
"//foundation/barrierfree/accessibility/services/aams_ext:aams_ext",
"//foundation/barrierfree/accessibility/services/blinking_reminder:accessibleBlinking",
"//foundation/barrierfree/accessibility/tools/ohos-accessibilityManager:ohos-a11yManager"
]
},
@@ -115,4 +115,6 @@ interface OHOS.Accessibility.IAccessibleAbilityManagerService {
void GetSeniorModeStateForApp([in] String name, [in] int appIndex, [out] boolean state);
void SetSeniorModeStateForApp([in] AccessibilityBundleSeniorModeInfoParcel[] infos);
void DeRegisterSeniorModeStateObserver([in] IRemoteObject obj);
void StartBlinking([in] int mode, [in] int scenario, [out] int funcResult);
void StopBlinking([in] int mode, [in] int scenario, [out] int funcResult);
}
@@ -423,6 +423,14 @@ public:
{
return RET_OK;
}
ErrCode StartBlinking(int32_t mode, int32_t scenario, int32_t& funcResult) override
{
return RET_OK;
}
ErrCode StopBlinking(int32_t mode, int32_t scenario, int32_t& funcResult) override
{
return RET_OK;
}
};
uint32_t GetU32Data(const uint8_t *ptr)
+13
View File
@@ -133,6 +133,7 @@ ohos_unittest("accessible_ability_test") {
"../../../services/aams/src/accessible_ability_manager.cpp",
"../../../services/aams/src/accessibility_element_operator_manager.cpp",
"../../../services/aams/src/element_operator_callback_impl.cpp",
"../../../services/aams/src/accessibility_blinking_reminder_proxy.cpp",
"../../../services/aams/test/mock/src/mock_accessibility_account_data.cpp",
"../../../services/aams/test/mock/src/mock_accessibility_common_event.cpp",
"../../../services/aams/test/mock/src/mock_accessibility_event_transmission.cpp",
@@ -235,6 +236,18 @@ ohos_unittest("accessible_ability_test") {
if (security_component_enable) {
external_deps += [ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
}
###############################################################################
@@ -109,6 +109,8 @@ public:
Accessibility::RetError SetEnhanceConfig(uint8_t *cfg, uint32_t cfgLen);
Accessibility::RetError GetSeniorModeStateForApp(const std::string &bundleName, int32_t appIndex, bool &state);
Accessibility::RetError SetSeniorModeStateForApp(const std::vector<AccessibilityBundleSeniorModeInfo> &infos);
Accessibility::RetError StartBlinking(int32_t mode, int32_t scenario, Accessibility::BlinkResultCode &blinkResult);
Accessibility::RetError StopBlinking(int32_t mode, int32_t scenario, Accessibility::BlinkResultCode &blinkResult);
void ResetService(const wptr<IRemoteObject> &remote);
void OnAccessibleAbilityManagerCaptionPropertyChanged(const CaptionProperty &property);
@@ -397,5 +397,21 @@ Accessibility::RetError AccessibilityConfig::UnsubscribeAppSeniorModeStateObserv
CHECK_IMPL_PTR(Accessibility::RET_ERR_NULLPTR)
return pImpl_->UnsubscribeAppSeniorModeStateObserver(observer);
}
Accessibility::RetError AccessibilityConfig::StartBlinking(int32_t mode, int32_t scenario,
Accessibility::BlinkResultCode &blinkResult)
{
HILOG_INFO();
CHECK_IMPL_PTR(Accessibility::RET_ERR_NULLPTR)
return pImpl_->StartBlinking(mode, scenario, blinkResult);
}
Accessibility::RetError AccessibilityConfig::StopBlinking(int32_t mode, int32_t scenario,
Accessibility::BlinkResultCode &blinkResult)
{
HILOG_INFO();
CHECK_IMPL_PTR(Accessibility::RET_ERR_NULLPTR)
return pImpl_->StopBlinking(mode, scenario, blinkResult);
}
} // Accessibility
} // OHOS
@@ -2284,5 +2284,45 @@ Accessibility::RetError AccessibilityConfig::Impl::UnsubscribeAppSeniorModeState
}
return Accessibility::RET_OK;
}
Accessibility::RetError AccessibilityConfig::Impl::StartBlinking(int32_t mode, int32_t scenario,
Accessibility::BlinkResultCode &blinkResult)
{
HILOG_INFO("mode = [%{public}d], scenario = [%{public}d]", mode, scenario);
sptr<Accessibility::IAccessibleAbilityManagerService> proxy = GetServiceProxy();
if (proxy == nullptr) {
HILOG_ERROR("Failed to get accessibility service");
return Accessibility::RET_ERR_SAMGR;
}
int32_t funcResult = 0;
Accessibility::RetError ret =
static_cast<Accessibility::RetError>(proxy->StartBlinking(mode, scenario, funcResult));
if (ret != Accessibility::RET_OK) {
HILOG_ERROR("StartBlinking failed, ret=%{public}d", ret);
return ret;
}
blinkResult = static_cast<Accessibility::BlinkResultCode>(funcResult);
return Accessibility::RET_OK;
}
Accessibility::RetError AccessibilityConfig::Impl::StopBlinking(int32_t mode, int32_t scenario,
Accessibility::BlinkResultCode &blinkResult)
{
HILOG_INFO("mode = [%{public}d], scenario = [%{public}d]", mode, scenario);
sptr<Accessibility::IAccessibleAbilityManagerService> proxy = GetServiceProxy();
if (proxy == nullptr) {
HILOG_ERROR("Failed to get accessibility service");
return Accessibility::RET_ERR_SAMGR;
}
int32_t funcResult = 0;
Accessibility::RetError ret =
static_cast<Accessibility::RetError>(proxy->StopBlinking(mode, scenario, funcResult));
if (ret != Accessibility::RET_OK) {
HILOG_ERROR("StopBlinking failed, ret=%{public}d", ret);
return ret;
}
blinkResult = static_cast<Accessibility::BlinkResultCode>(funcResult);
return Accessibility::RET_OK;
}
} // namespace AccessibilityConfig
} // namespace OHOS
@@ -539,6 +539,25 @@ public:
Accessibility::RetError UnsubscribeAppSeniorModeStateObserver(
const std::shared_ptr<AccessibilityAppSeniorModeStateObserver> &observer);
/**
* @brief Start blinking with specified mode and scenario
* @param mode Indicates the blinking mode (SINGLE_BLINK or CONTINUOUS_BLINK)
* @param scenario Indicates the scenario (ALARM, NOTIFICATION, CALL, or TESTING)
* @param blinkResult Indicates the BlinkResultCode result of the blinking operation.
* @return Returns RET_OK if successful, otherwise refer to the RetError for the failure.
*/
Accessibility::RetError StartBlinking(int32_t mode, int32_t scenario,
Accessibility::BlinkResultCode &blinkResult);
/**
* @brief Stop blinking with specified mode and scenario
* @param mode Indicates the blinking mode (SINGLE_BLINK or CONTINUOUS_BLINK)
* @param scenario Indicates the scenario (ALARM, NOTIFICATION, CALL, or TESTING)
* @param blinkResult Indicates the BlinkResultCode result of the blinking operation.
* @return Returns RET_OK if successful, otherwise refer to the RetError for the failure.
*/
Accessibility::RetError StopBlinking(int32_t mode, int32_t scenario,
Accessibility::BlinkResultCode &blinkResult);
private:
class Impl;
std::unique_ptr<Impl> pImpl_;
@@ -512,6 +512,34 @@ struct FocusMoveResult {
bool changeToNewInfo;
bool needTerminate;
};
enum BlinkingMode : int32_t {
SINGLE_BLINK = 1,
CONTINUOUS_BLINK = 2,
};
enum BlinkingScenario : int32_t {
ALARM = 1,
NOTIFICATION = 2,
CALL = 3,
TESTING = 4,
};
enum FlashReminderMode : int32_t {
NONE = 0,
DISPLAY = 1,
FLASHLIGHT = 2,
BOTH = 3,
};
enum BlinkResultCode : int32_t {
BLINK_SUCCESS = 0,
ALREADY_FLASHING = 1,
DEVICE_IN_USE = 2,
FLASH_BLINKING_UNSUPPORTED = 3,
SCREEN_BLINKING_UNSUPPORTED = 4,
FEATURE_DISABLE = 5,
};
} // namespace Accessibility
} // namespace OHOS
@@ -154,6 +154,39 @@ namespace config {
native function setMagnificationState(state: boolean): void;
export enum BlinkingMode {
SINGLE_BLINK = 1,
CONTINUOUS_BLINK = 2,
}
export enum BlinkingScenario {
ALARM = 1,
NOTIFICATION = 2,
CALL = 3,
TESTING = 4,
}
export enum BlinkResultCode {
BLINK_SUCCESS = 0,
ALREADY_FLASHING = 1,
DEVICE_IN_USE = 2,
FLASH_BLINKING_UNSUPPORTED = 3,
SCREEN_BLINKING_UNSUPPORTED = 4,
FEATURE_DISABLE = 5,
}
native function startBlinkingSync(mode: BlinkingMode, scenario: BlinkingScenario): BlinkResultCode;
native function stopBlinkingSync(mode: BlinkingMode, scenario: BlinkingScenario): BlinkResultCode;
export function startBlinking(mode: BlinkingMode, scenario: BlinkingScenario): BlinkResultCode {
return startBlinkingSync(mode, scenario);
}
export function stopBlinking(mode: BlinkingMode, scenario: BlinkingScenario): BlinkResultCode {
return stopBlinkingSync(mode, scenario);
}
native function setSeniorModeStateForAppSync(seniorModeInfoArray: Array<AppSeniorModeInfo>): void;
native function getSeniorModeStateForAppSync(bundleName: string, appIndex: int): boolean;
@@ -197,6 +197,9 @@ public:
static ani_boolean GetSeniorModeStateForApp(ani_env *env, ani_string bundleName, ani_int appIndex);
static void SetSeniorModeStateForApp(ani_env *env, ani_array seniorModeInfoArray);
static ani_enum_item StartBlinking(ani_env *env, ani_enum_item mode, ani_enum_item scenario);
static ani_enum_item StopBlinking(ani_env *env, ani_enum_item mode, ani_enum_item scenario);
static std::shared_ptr<EnableAbilityListsObserverImpl> enableAbilityListsObservers_;
static std::shared_ptr<ANIAccessibilityConfigObserverImpl> configObservers_;
static std::shared_ptr<EnableAbilityCallbackObserverImpl> enableAbilityCallbackObservers_;
@@ -30,6 +30,7 @@ using CONFIG_ID = OHOS::AccessibilityConfig::CONFIG_ID;
using ConfigValue = OHOS::AccessibilityConfig::ConfigValue;
constexpr int32_t ANI_SCOPE_SIZE = 16;
constexpr const char *BLINK_RESULT_CODE = "@ohos.accessibility.config.config.BlinkResultCode";
const std::string DEFAULT_FONT_FAMILY = "default";
constexpr uint32_t DEFAULT_FONT_SCALE = 75;
constexpr uint32_t DEFAULT_COLOR = 0xff000000;
@@ -1538,4 +1539,68 @@ void ANIAccessibilityConfig::SetSeniorModeStateForApp(ani_env *env, ani_array se
if (ret != OHOS::Accessibility::RET_OK) {
HILOG_ERROR("SetSeniorModeStateForApp failed: %{public}d", ret);
}
}
ani_enum_item ANIAccessibilityConfig::StartBlinking(ani_env *env, ani_enum_item mode, ani_enum_item scenario)
{
HILOG_INFO();
ani_int modeValue = 0;
ani_int scenarioValue = 0;
if (ANI_OK != env->EnumItem_GetValue_Int(mode, &modeValue)) {
HILOG_ERROR("Failed to get mode enum value");
ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(OHOS::Accessibility::RET_ERR_INVALID_PARAM));
return nullptr;
}
if (ANI_OK != env->EnumItem_GetValue_Int(scenario, &scenarioValue)) {
HILOG_ERROR("Failed to get scenario enum value");
ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(OHOS::Accessibility::RET_ERR_INVALID_PARAM));
return nullptr;
}
auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
OHOS::Accessibility::BlinkResultCode blinkResult = OHOS::Accessibility::BlinkResultCode::BLINK_SUCCESS;
OHOS::Accessibility::RetError ret = instance.StartBlinking(modeValue, scenarioValue, blinkResult);
if (ret != OHOS::Accessibility::RET_OK) {
HILOG_ERROR("StartBlinking failed, ret=%{public}d", static_cast<int32_t>(ret));
ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(ret));
return nullptr;
}
ani_enum_item result = nullptr;
if (!ANIUtils::EnumConvert_NativeToEts(env, BLINK_RESULT_CODE, blinkResult, result)) {
HILOG_ERROR("EnumConvert_NativeToEts BlinkResultCode failed");
return nullptr;
}
return result;
}
ani_enum_item ANIAccessibilityConfig::StopBlinking(ani_env *env, ani_enum_item mode, ani_enum_item scenario)
{
HILOG_INFO();
ani_int modeValue = 0;
ani_int scenarioValue = 0;
if (ANI_OK != env->EnumItem_GetValue_Int(mode, &modeValue)) {
HILOG_ERROR("Failed to get mode enum value");
ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(OHOS::Accessibility::RET_ERR_INVALID_PARAM));
return nullptr;
}
if (ANI_OK != env->EnumItem_GetValue_Int(scenario, &scenarioValue)) {
HILOG_ERROR("Failed to get scenario enum value");
ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(OHOS::Accessibility::RET_ERR_INVALID_PARAM));
return nullptr;
}
auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
OHOS::Accessibility::BlinkResultCode blinkResult = OHOS::Accessibility::BlinkResultCode::BLINK_SUCCESS;
OHOS::Accessibility::RetError ret = instance.StopBlinking(modeValue, scenarioValue, blinkResult);
if (ret != OHOS::Accessibility::RET_OK) {
HILOG_ERROR("StopBlinking failed, ret=%{public}d", static_cast<int32_t>(ret));
ANIUtils::ThrowBusinessError(env, ANIUtils::QueryRetMsg(ret));
return nullptr;
}
ani_enum_item result = nullptr;
if (!ANIUtils::EnumConvert_NativeToEts(env, BLINK_RESULT_CODE, blinkResult, result)) {
HILOG_ERROR("EnumConvert_NativeToEts BlinkResultCode failed");
return nullptr;
}
return result;
}
@@ -59,7 +59,11 @@ static bool NamespaceBindMethod(ani_env *env, ani_namespace ns, ani_module mod)
ani_native_function{"offSeniorModeStateChangeForAppObserver", nullptr, reinterpret_cast<void *>(
ANIAccessibilityConfig::OffSeniorModeStateChangeForApp)},
ani_native_function{"offSeniorModeStateChangeForAppObservers", nullptr, reinterpret_cast<void *>(
ANIAccessibilityConfig::OffSeniorModeStateChangeForApps)}
ANIAccessibilityConfig::OffSeniorModeStateChangeForApps)},
ani_native_function{"startBlinkingSync", nullptr, reinterpret_cast<void *>(
ANIAccessibilityConfig::StartBlinking)},
ani_native_function{"stopBlinkingSync", nullptr, reinterpret_cast<void *>(
ANIAccessibilityConfig::StopBlinking)}
};
if (env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size()) != ANI_OK) {
@@ -172,6 +172,8 @@ public:
static napi_value DisableAbility(napi_env env, napi_callback_info info);
static napi_value SubscribeState(napi_env env, napi_callback_info info);
static napi_value UnsubscribeState(napi_env env, napi_callback_info info);
static napi_value StartBlinking(napi_env env, napi_callback_info info);
static napi_value StopBlinking(napi_env env, napi_callback_info info);
static napi_value SetMagnificationState(napi_env env, napi_callback_info info);
static napi_value SetConfig(napi_env env, napi_callback_info info);
static napi_value GetConfig(napi_env env, napi_callback_info info);
@@ -1976,3 +1976,89 @@ void SeniorModeStateObserverImpl::UnsubscribeObservers()
std::lock_guard<ffrt::mutex> lock(mutex_);
observers_.clear();
}
napi_value NAccessibilityConfig::StartBlinking(napi_env env, napi_callback_info info)
{
HILOG_DEBUG();
size_t argc = ARGS_SIZE_TWO;
napi_value parameters[ARGS_SIZE_TWO] = {0};
napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
int32_t mode = 0;
int32_t scenario = 0;
if (argc < ARGS_SIZE_TWO) {
HILOG_ERROR("argc is invalid: %{public}zu", argc);
napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
napi_throw(env, err);
return nullptr;
}
if (!ParseInt32(env, mode, parameters[PARAM0])) {
HILOG_ERROR("blinkingMode parse failed");
napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
napi_throw(env, err);
return nullptr;
}
if (!ParseInt32(env, scenario, parameters[PARAM1])) {
HILOG_ERROR("scenario parse failed");
napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
napi_throw(env, err);
return nullptr;
}
auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
OHOS::Accessibility::BlinkResultCode blinkResult = OHOS::Accessibility::BlinkResultCode::BLINK_SUCCESS;
OHOS::Accessibility::RetError ret = instance.StartBlinking(mode, scenario, blinkResult);
if (ret != OHOS::Accessibility::RET_OK) {
napi_value err = CreateBusinessError(env, ret);
napi_throw(env, err);
return nullptr;
}
napi_value result = nullptr;
napi_create_int32(env, static_cast<int32_t>(blinkResult), &result);
return result;
}
napi_value NAccessibilityConfig::StopBlinking(napi_env env, napi_callback_info info)
{
HILOG_DEBUG();
size_t argc = ARGS_SIZE_TWO;
napi_value parameters[ARGS_SIZE_TWO] = {0};
napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
int32_t mode = 0;
int32_t scenario = 0;
if (argc < ARGS_SIZE_TWO) {
HILOG_ERROR("argc is invalid: %{public}zu", argc);
napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
napi_throw(env, err);
return nullptr;
}
if (!ParseInt32(env, mode, parameters[PARAM0])) {
HILOG_ERROR("blinkingMode parse failed");
napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
napi_throw(env, err);
return nullptr;
}
if (!ParseInt32(env, scenario, parameters[PARAM1])) {
HILOG_ERROR("scenario parse failed");
napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
napi_throw(env, err);
return nullptr;
}
auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
OHOS::Accessibility::BlinkResultCode blinkResult = OHOS::Accessibility::BlinkResultCode::BLINK_SUCCESS;
OHOS::Accessibility::RetError ret = instance.StopBlinking(mode, scenario, blinkResult);
if (ret != OHOS::Accessibility::RET_OK) {
napi_value err = CreateBusinessError(env, ret);
napi_throw(env, err);
return nullptr;
}
napi_value result = nullptr;
napi_create_int32(env, static_cast<int32_t>(blinkResult), &result);
return result;
}
@@ -616,6 +616,94 @@ static napi_value InitIgnoreRepeatClickTime(napi_env env)
return ignoreRepeatClickTimeValue;
}
static napi_value InitBlinkingMode(napi_env env)
{
napi_value blinkingModeValue = nullptr;
napi_create_object(env, &blinkingModeValue);
if (blinkingModeValue == nullptr) {
HILOG_ERROR("napi_create_object fail.");
return blinkingModeValue;
}
napi_value singleBlink = nullptr;
napi_create_int32(env, OHOS::Accessibility::SINGLE_BLINK, &singleBlink);
napi_set_named_property(env, blinkingModeValue, "SINGLE_BLINK", singleBlink);
napi_value continuousBlink = nullptr;
napi_create_int32(env, OHOS::Accessibility::CONTINUOUS_BLINK, &continuousBlink);
napi_set_named_property(env, blinkingModeValue, "CONTINUOUS_BLINK", continuousBlink);
return blinkingModeValue;
}
static napi_value InitBlinkingScenario(napi_env env)
{
napi_value blinkingScenarioValue = nullptr;
napi_create_object(env, &blinkingScenarioValue);
if (blinkingScenarioValue == nullptr) {
HILOG_ERROR("napi_create_object fail.");
return blinkingScenarioValue;
}
napi_value alarm = nullptr;
napi_create_int32(env, OHOS::Accessibility::ALARM, &alarm);
napi_set_named_property(env, blinkingScenarioValue, "ALARM", alarm);
napi_value notification = nullptr;
napi_create_int32(env, OHOS::Accessibility::NOTIFICATION, &notification);
napi_set_named_property(env, blinkingScenarioValue, "NOTIFICATION", notification);
napi_value call = nullptr;
napi_create_int32(env, OHOS::Accessibility::CALL, &call);
napi_set_named_property(env, blinkingScenarioValue, "CALL", call);
napi_value testing = nullptr;
napi_create_int32(env, OHOS::Accessibility::TESTING, &testing);
napi_set_named_property(env, blinkingScenarioValue, "TESTING", testing);
return blinkingScenarioValue;
}
static napi_value InitBlinkResultCode(napi_env env)
{
napi_value blinkResultCodeValue = nullptr;
napi_create_object(env, &blinkResultCodeValue);
if (blinkResultCodeValue == nullptr) {
HILOG_ERROR("napi_create_object fail.");
return blinkResultCodeValue;
}
napi_value success = nullptr;
napi_create_int32(env, OHOS::Accessibility::BlinkResultCode::BLINK_SUCCESS, &success);
napi_set_named_property(env, blinkResultCodeValue, "BLINK_SUCCESS", success);
napi_value alreadyFlashing = nullptr;
napi_create_int32(env, OHOS::Accessibility::BlinkResultCode::ALREADY_FLASHING, &alreadyFlashing);
napi_set_named_property(env, blinkResultCodeValue, "ALREADY_FLASHING", alreadyFlashing);
napi_value deviceInUse = nullptr;
napi_create_int32(env, OHOS::Accessibility::BlinkResultCode::DEVICE_IN_USE, &deviceInUse);
napi_set_named_property(env, blinkResultCodeValue, "DEVICE_IN_USE", deviceInUse);
napi_value flashBlinkingUnsupported = nullptr;
napi_create_int32(env,
OHOS::Accessibility::BlinkResultCode::FLASH_BLINKING_UNSUPPORTED, &flashBlinkingUnsupported);
napi_set_named_property(env, blinkResultCodeValue,
"FLASH_BLINKING_UNSUPPORTED", flashBlinkingUnsupported);
napi_value screenBlinkingUnsupported = nullptr;
napi_create_int32(env,
OHOS::Accessibility::BlinkResultCode::SCREEN_BLINKING_UNSUPPORTED, &screenBlinkingUnsupported);
napi_set_named_property(env, blinkResultCodeValue,
"SCREEN_BLINKING_UNSUPPORTED", screenBlinkingUnsupported);
napi_value featureDisable = nullptr;
napi_create_int32(env, OHOS::Accessibility::BlinkResultCode::FEATURE_DISABLE, &featureDisable);
napi_set_named_property(env, blinkResultCodeValue, "FEATURE_DISABLE", featureDisable);
return blinkResultCodeValue;
}
static napi_value InitConfigModule(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
@@ -625,6 +713,8 @@ static napi_value InitConfigModule(napi_env env, napi_value exports)
DECLARE_NAPI_FUNCTION(
"enableAbilityWithCallback", NAccessibilityConfig::EnableAbilityWithCallback),
DECLARE_NAPI_FUNCTION("disableAbility", NAccessibilityConfig::DisableAbility),
DECLARE_NAPI_FUNCTION("startBlinking", NAccessibilityConfig::StartBlinking),
DECLARE_NAPI_FUNCTION("stopBlinking", NAccessibilityConfig::StopBlinking),
DECLARE_NAPI_FUNCTION("setMagnificationState", NAccessibilityConfig::SetMagnificationState),
DECLARE_NAPI_FUNCTION("onSeniorModeStateChangeForApp", NAccessibilityConfig::SubscribeSelfSeniorMode),
DECLARE_NAPI_FUNCTION("offSeniorModeStateChangeForApp", NAccessibilityConfig::UnsubscribeSelfSeniorMode),
@@ -650,6 +740,9 @@ static napi_value InitConfigModule(napi_env env, napi_value exports)
DECLARE_NAPI_STATIC_PROPERTY("clickResponseTime", InitClickResponseTime(env)),
DECLARE_NAPI_STATIC_PROPERTY("ignoreRepeatClick", InitIgnoreRepeatClickState(env)),
DECLARE_NAPI_STATIC_PROPERTY("repeatClickInterval", InitIgnoreRepeatClickTime(env)),
DECLARE_NAPI_STATIC_PROPERTY("BlinkingMode", InitBlinkingMode(env)),
DECLARE_NAPI_STATIC_PROPERTY("BlinkingScenario", InitBlinkingScenario(env)),
DECLARE_NAPI_STATIC_PROPERTY("BlinkResultCode", InitBlinkResultCode(env)),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
+18 -1
View File
@@ -69,7 +69,8 @@ accessibleabilityms_files = [
"${services_path}/src/accessible_extend_manager_service_proxy.cpp",
"${services_path}/src/accessibility_element_operator_manager.cpp",
"${services_path}/src/accessible_ability_manager.cpp",
"${services_path}/src/element_operator_callback_impl.cpp"
"${services_path}/src/element_operator_callback_impl.cpp",
"${services_path}/src/accessibility_blinking_reminder_proxy.cpp"
]
ohos_shared_library("accessibleabilityms") {
@@ -149,6 +150,22 @@ ohos_shared_library("accessibleabilityms") {
external_deps += [ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
if (accessibility_feature_display_manager) {
external_deps += [ "display_manager:displaymgr" ]
}
install_enable = true
subsystem_name = "barrierfree"
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2026-2026 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.
*/
#ifndef ACCESSIBILITY_BLINKING_REMINDER_PROXY_H
#define ACCESSIBILITY_BLINKING_REMINDER_PROXY_H
#include "singleton.h"
#include "accessibility_def.h"
#include "ffrt.h"
namespace OHOS {
namespace Accessibility {
class AccessibilityBlinkingReminderProxy {
DECLARE_SINGLETON(AccessibilityBlinkingReminderProxy);
public:
void SetFlashReminderSwitch(bool state);
void SetFlashReminderMode(int32_t mode);
void SetFlashReminderFunctionEnabled(const std::string &enabled);
void SetFlashReminderUnlock(bool state);
BlinkResultCode StartBlinking(int32_t mode, int32_t scenario);
BlinkResultCode StopBlinking(int32_t mode, int32_t scenario);
private:
void LoadLibrary();
void UnLoadLibrary();
using SetFlashReminderSwitchFunc = void (*)(bool);
using SetFlashReminderModeFunc = void (*)(int32_t);
using SetFlashReminderFunctionEnabledFunc = void (*)(const char *);
using SetFlashReminderUnlockFunc = void (*)(bool);
using StartBlinkingFunc = BlinkResultCode (*)(int32_t, int32_t);
using StopBlinkingFunc = BlinkResultCode (*)(int32_t, int32_t);
SetFlashReminderSwitchFunc setSwitchFunc_ = nullptr;
SetFlashReminderModeFunc setModeFunc_ = nullptr;
SetFlashReminderFunctionEnabledFunc setEnabledFunc_ = nullptr;
SetFlashReminderUnlockFunc setUnlockFunc_ = nullptr;
StartBlinkingFunc startBlinkingFunc_ = nullptr;
StopBlinkingFunc stopBlinkingFunc_ = nullptr;
void *handle_ = nullptr;
bool loadFlag_ = false;
ffrt::mutex lock_;
};
} // namespace Accessibility
} // namespace OHOS
#endif // ACCESSIBILITY_BLINKING_REMINDER_PROXY_H
@@ -76,6 +76,9 @@ public:
RetError SetZoomGestureEnabledReconfirm(const bool state);
RetError SetColorModeState(const A11yDarkModeType &type);
RetError SetFlashReminderSwitch(const bool state);
RetError SetFlashReminderMode(const int32_t mode);
RetError SetFlashReminderFunctionEnabled(const std::string &enabled);
RetError SetFlashReminderUnlock(const bool state);
RetError SetSeniorModeState(const bool state);
RetError SetSeniorModeStateForApp(const std::string &bundleName, int32_t appIndex, const bool state);
@@ -110,6 +113,9 @@ public:
float GetScreenMagnificationScale() const;
int32_t GetScreenMagnificationTriggerMethod() const;
bool GetFlashReminderSwitch() const;
int32_t GetFlashReminderMode() const;
const std::string &GetFlashReminderFunctionEnabled() const;
bool GetFlashReminderUnlock() const;
bool GetSeniorModeState() const;
bool GetSeniorModeStateForApp(const std::string &bundleName, int32_t appIndex);
void SetSeniorModeStateForAppMap(const std::map<std::string, bool>& map);
@@ -178,6 +184,9 @@ private:
std::atomic<bool> animationOffState_ = false;
std::atomic<bool> audioMonoState_ = false;
std::atomic<bool> flashReminderSwitch_ = false;
std::atomic<int32_t> flashReminderMode_ = 0;
std::string flashReminderFunctionEnabled_ = "";
std::atomic<bool> flashReminderUnlock_ = false;
std::atomic<bool> daltonizationState_ = false;
std::atomic<bool> seniorModeState_ = false;
std::atomic<uint32_t> daltonizationColorFilter_ = 0;
@@ -42,6 +42,7 @@
#include "accessibility_security_component_manager.h"
#include "accessible_extend_manager_service_proxy.h"
#include "element_operator_callback_impl.h"
#include "accessibility_blinking_reminder_proxy.h"
namespace OHOS {
namespace Accessibility {
@@ -142,6 +143,8 @@ public:
ErrCode EnableAbility(const std::string &name, const uint32_t capabilities,
const bool connectCallBackFlag) override;
ErrCode StartBlinking(int32_t mode, int32_t scenario, int32_t& funcResult) override;
ErrCode StopBlinking(int32_t mode, int32_t scenario, int32_t& funcResult) override;
ErrCode GetEnabledAbilities(std::vector<std::string> &enabledAbilities) override;
RetError SetCurtainScreenUsingStatus(bool isEnable);
ErrCode CheckExtensionAbilityPermission(std::string& processName) override;
@@ -412,6 +415,12 @@ private:
void RegisterScreenMagnificationType();
void OnFlashReminderSwitchChanged();
void RegisterFlashReminderSwitch();
void OnFlashReminderModeChanged();
void RegisterFlashReminderMode();
void OnFlashReminderFunctionEnabledChanged();
void RegisterFlashReminderFunctionEnabled();
void OnFlashReminderUnlockChanged();
void RegisterFlashReminderUnlock();
void OnSeniorModeStateChanged();
void RegisterSeniorModeState();
@@ -0,0 +1,180 @@
/*
* Copyright (C) 2026-2026 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 "accessibility_blinking_reminder_proxy.h"
#include "hilog_wrapper.h"
#include <dlfcn.h>
namespace OHOS {
namespace Accessibility {
namespace {
const std::string_view blinkingReminderLibrary = "libaccessibleBlinking.z.so";
}
AccessibilityBlinkingReminderProxy::AccessibilityBlinkingReminderProxy()
{
}
AccessibilityBlinkingReminderProxy::~AccessibilityBlinkingReminderProxy()
{
}
void AccessibilityBlinkingReminderProxy::LoadLibrary()
{
handle_ = dlopen(std::string(blinkingReminderLibrary).c_str(), RTLD_LAZY);
if (!handle_) {
HILOG_ERROR("load %{public}s failed, %{public}s", blinkingReminderLibrary.data(), dlerror());
return;
}
setSwitchFunc_ = (SetFlashReminderSwitchFunc)dlsym(handle_, "SetFlashReminderSwitch");
if (!setSwitchFunc_) {
HILOG_ERROR("get SetFlashReminderSwitch failed, %{public}s", dlerror());
return;
}
setModeFunc_ = (SetFlashReminderModeFunc)dlsym(handle_, "SetFlashReminderMode");
if (!setModeFunc_) {
HILOG_ERROR("get SetFlashReminderMode failed, %{public}s", dlerror());
return;
}
setEnabledFunc_ = (SetFlashReminderFunctionEnabledFunc)dlsym(handle_, "SetFlashReminderFunctionEnabled");
if (!setEnabledFunc_) {
HILOG_ERROR("get SetFlashReminderFunctionEnabled failed, %{public}s", dlerror());
return;
}
setUnlockFunc_ = (SetFlashReminderUnlockFunc)dlsym(handle_, "SetFlashReminderUnlock");
if (!setUnlockFunc_) {
HILOG_ERROR("get SetFlashReminderUnlock failed, %{public}s", dlerror());
return;
}
startBlinkingFunc_ = (StartBlinkingFunc)dlsym(handle_, "StartBlinking");
if (!startBlinkingFunc_) {
HILOG_ERROR("get StartBlinking failed, %{public}s", dlerror());
return;
}
stopBlinkingFunc_ = (StopBlinkingFunc)dlsym(handle_, "StopBlinking");
if (!stopBlinkingFunc_) {
HILOG_ERROR("get StopBlinking failed, %{public}s", dlerror());
return;
}
loadFlag_ = true;
HILOG_INFO("load %{public}s success", blinkingReminderLibrary.data());
}
void AccessibilityBlinkingReminderProxy::UnLoadLibrary()
{
if (!loadFlag_) {
return;
}
int ret = dlclose(handle_);
char *error = dlerror();
if (error) {
HILOG_ERROR("dlclose error: %{public}s", error);
}
handle_ = nullptr;
setSwitchFunc_ = nullptr;
setModeFunc_ = nullptr;
setEnabledFunc_ = nullptr;
setUnlockFunc_ = nullptr;
startBlinkingFunc_ = nullptr;
stopBlinkingFunc_ = nullptr;
loadFlag_ = false;
HILOG_INFO("unload %{public}s done, ret=%{public}d", blinkingReminderLibrary.data(), ret);
}
void AccessibilityBlinkingReminderProxy::SetFlashReminderSwitch(bool state)
{
HILOG_INFO("state=%{public}d", state);
std::lock_guard<ffrt::mutex> lock(lock_);
if (!loadFlag_) {
LoadLibrary();
}
if (loadFlag_ && setSwitchFunc_) {
setSwitchFunc_(state);
}
}
void AccessibilityBlinkingReminderProxy::SetFlashReminderMode(int32_t mode)
{
HILOG_INFO("mode=%{public}d", mode);
std::lock_guard<ffrt::mutex> lock(lock_);
if (!loadFlag_) {
LoadLibrary();
}
if (loadFlag_ && setModeFunc_) {
setModeFunc_(mode);
}
}
void AccessibilityBlinkingReminderProxy::SetFlashReminderFunctionEnabled(const std::string &enabled)
{
HILOG_INFO("enabled=%{public}s", enabled.c_str());
std::lock_guard<ffrt::mutex> lock(lock_);
if (!loadFlag_) {
LoadLibrary();
}
if (loadFlag_ && setEnabledFunc_) {
setEnabledFunc_(enabled.c_str());
}
}
void AccessibilityBlinkingReminderProxy::SetFlashReminderUnlock(bool state)
{
HILOG_INFO("state=%{public}d", state);
std::lock_guard<ffrt::mutex> lock(lock_);
if (!loadFlag_) {
LoadLibrary();
}
if (loadFlag_ && setUnlockFunc_) {
setUnlockFunc_(state);
}
}
BlinkResultCode AccessibilityBlinkingReminderProxy::StartBlinking(int32_t mode, int32_t scenario)
{
HILOG_INFO("mode=%{public}d, scenario=%{public}d", mode, scenario);
std::lock_guard<ffrt::mutex> lock(lock_);
if (!loadFlag_) {
LoadLibrary();
}
if (loadFlag_ && startBlinkingFunc_) {
return startBlinkingFunc_(mode, scenario);
}
HILOG_ERROR("StartBlinking not available");
return BlinkResultCode::FEATURE_DISABLE;
}
BlinkResultCode AccessibilityBlinkingReminderProxy::StopBlinking(int32_t mode, int32_t scenario)
{
HILOG_INFO("mode=%{public}d, scenario=%{public}d", mode, scenario);
std::lock_guard<ffrt::mutex> lock(lock_);
if (!loadFlag_) {
LoadLibrary();
}
if (loadFlag_ && stopBlinkingFunc_) {
return stopBlinkingFunc_(mode, scenario);
}
HILOG_ERROR("StopBlinking not available");
return BlinkResultCode::FEATURE_DISABLE;
}
} // namespace Accessibility
} // namespace OHOS
@@ -87,6 +87,8 @@ namespace {
const char* ARKUI_ANIMATION_SCALE_NAME = "persist.sys.arkui.animationscale";
const char* FLASH_REMINDER_SWITCH_KEY = "accessibility_flash_reminder_switch";
const char* FLASH_REMINDER_ENABLED = "accessibility_reminder_function_enabled";
const char* FLASH_REMINDER_MODE_KEY = "accessibility_flash_reminder_mode";
const char* FLASH_REMINDER_UNLOCK_KEY = "accessibility_flash_reminder_unlock";
const char* VOICE_RECOGNITION_KEY = "accessibility_sound_recognition_switch";
const char* VOICE_RECOGNITION_TYPES = "accessibility_sound_recognition_enabled";
const char* IGNORE_REPEAT_CLICK_TIMESTAMP = "accessibility_ignore_repeat_click_timestamp";
@@ -233,6 +235,27 @@ RetError AccessibilitySettingsConfig::SetScreenMagnificationType(const uint32_t
return RET_OK;
}
RetError AccessibilitySettingsConfig::SetFlashReminderMode(const int32_t mode)
{
HILOG_DEBUG("mode = [%{public}d]", mode);
flashReminderMode_.store(mode);
return RET_OK;
}
RetError AccessibilitySettingsConfig::SetFlashReminderFunctionEnabled(const std::string &enabled)
{
HILOG_DEBUG("enabled = [%{public}s]", enabled.c_str());
flashReminderFunctionEnabled_ = enabled;
return RET_OK;
}
RetError AccessibilitySettingsConfig::SetFlashReminderUnlock(const bool state)
{
HILOG_DEBUG("state = [%{public}s]", state ? "True" : "False");
flashReminderUnlock_.store(state);
return RET_OK;
}
RetError AccessibilitySettingsConfig::SetFlashReminderSwitch(const bool state)
{
HILOG_DEBUG("state = [%{public}s]", state ? "True" : "False");
@@ -884,6 +907,21 @@ bool AccessibilitySettingsConfig::GetFlashReminderSwitch() const
return flashReminderSwitch_.load();
}
int32_t AccessibilitySettingsConfig::GetFlashReminderMode() const
{
return flashReminderMode_.load();
}
const std::string &AccessibilitySettingsConfig::GetFlashReminderFunctionEnabled() const
{
return flashReminderFunctionEnabled_;
}
bool AccessibilitySettingsConfig::GetFlashReminderUnlock() const
{
return flashReminderUnlock_.load();
}
bool AccessibilitySettingsConfig::GetSeniorModeState() const
{
return seniorModeState_.load();
@@ -1302,6 +1340,9 @@ void AccessibilitySettingsConfig::InitSetting()
datashare_->GetStringValue(VOICE_RECOGNITION_TYPES, "DEFAULT");
HandleIgnoreRepeatClickState();
flashReminderSwitch_.store(datashare_->GetBoolValue(FLASH_REMINDER_SWITCH_KEY, false));
flashReminderMode_.store(datashare_->GetIntValue(FLASH_REMINDER_MODE_KEY, 0));
flashReminderFunctionEnabled_ = datashare_->GetStringValue(FLASH_REMINDER_ENABLED, "");
flashReminderUnlock_.store(datashare_->GetBoolValue(FLASH_REMINDER_UNLOCK_KEY, false));
seniorModeState_.store(datashare_->GetBoolValue(ELDER_CARE_ENABLED_KEY, false));
}
@@ -57,6 +57,10 @@
#include "mem_mgr_proxy.h"
#include "common_event_manager.h"
#include "accessibility_notification_helper.h"
#ifdef OHOS_BUILD_ENABLE_SCREENLOCK_MANAGER
#include "screenlock_manager.h"
#endif
#include "accessibility_blinking_reminder_proxy.h"
#undef LOG_DOMAIN
#undef LOG_TAG
@@ -91,6 +95,9 @@ namespace {
const char* VOICE_RECOGNITION_KEY = "accessibility_sound_recognition_switch";
const char* VOICE_RECOGNITION_TYPES = "accessibility_sound_recognition_enabled";
const char* FLASH_REMINDER_SWITCH_KEY = "accessibility_flash_reminder_switch";
const char* FLASH_REMINDER_MODE_KEY = "accessibility_flash_reminder_mode";
const char* FLASH_REMINDER_ENABLED_KEY = "accessibility_reminder_function_enabled";
const char* FLASH_REMINDER_UNLOCK_KEY = "accessibility_flash_reminder_unlock";
#ifdef ACCESSIBILITY_WATCH_FEATURE
const char* DELAY_UNLOAD_TASK = "TASK_UNLOAD_ACCESSIBILITY_SA";
constexpr int32_t UNLOAD_TASK_INTERNAL = 3 * 60 * 1000; // ms
@@ -403,8 +410,12 @@ void AccessibleAbilityManagerService::OnAddSystemAbility(int32_t systemAbilityId
RegisterScreenMagnificationType();
RegisterVoiceRecognitionState();
RegisterFlashReminderSwitch();
RegisterFlashReminderMode();
RegisterFlashReminderFunctionEnabled();
RegisterFlashReminderUnlock();
RegisterSeniorModeState();
RegisterSeniorModeStateForAppObserver();
if (accessibilitySettings_) {
accessibilitySettings_->RegisterParamWatcher();
UpdateAccessibilityState();
@@ -1140,6 +1151,60 @@ ErrCode AccessibleAbilityManagerService::EnableAbility(const std::string &name,
return syncFuture.get();
}
ErrCode AccessibleAbilityManagerService::StartBlinking(int32_t mode, int32_t scenario, int32_t& funcResult)
{
HILOG_INFO("mode=%{public}d, scenario=%{public}d", mode, scenario);
if (!IsSystemApp()) {
HILOG_WARN("Not system app");
return RET_ERR_NOT_SYSTEM_APP;
}
if (!CheckPermission(OHOS_PERMISSION_WRITE_ACCESSIBILITY_CONFIG)) {
HILOG_WARN("StartBlinking permission denied.");
return RET_ERR_NO_PERMISSION;
}
if (mode < BlinkingMode::SINGLE_BLINK ||
mode > BlinkingMode::CONTINUOUS_BLINK) {
HILOG_ERROR("invalid mode %{public}d", mode);
return RET_ERR_INVALID_PARAM;
}
if (scenario < BlinkingScenario::ALARM ||
scenario > BlinkingScenario::TESTING) {
HILOG_ERROR("invalid scenario %{public}d", scenario);
return RET_ERR_INVALID_PARAM;
}
BlinkResultCode result = Singleton<AccessibilityBlinkingReminderProxy>::GetInstance().StartBlinking(mode, scenario);
funcResult = static_cast<int32_t>(result);
return ERR_OK;
}
ErrCode AccessibleAbilityManagerService::StopBlinking(int32_t mode, int32_t scenario, int32_t& funcResult)
{
HILOG_INFO("mode=%{public}d, scenario=%{public}d", mode, scenario);
if (!IsSystemApp()) {
HILOG_WARN("Not system app");
return RET_ERR_NOT_SYSTEM_APP;
}
if (!CheckPermission(OHOS_PERMISSION_WRITE_ACCESSIBILITY_CONFIG)) {
HILOG_WARN("StopBlinking permission denied.");
return RET_ERR_NO_PERMISSION;
}
if (mode < BlinkingMode::SINGLE_BLINK ||
mode > BlinkingMode::CONTINUOUS_BLINK) {
HILOG_ERROR("invalid mode %{public}d", mode);
return RET_ERR_INVALID_PARAM;
}
if (scenario < BlinkingScenario::ALARM ||
scenario > BlinkingScenario::TESTING) {
HILOG_ERROR("invalid scenario %{public}d", scenario);
return RET_ERR_INVALID_PARAM;
}
BlinkResultCode result = Singleton<AccessibilityBlinkingReminderProxy>::GetInstance().StopBlinking(mode, scenario);
funcResult = static_cast<int32_t>(result);
return ERR_OK;
}
bool AccessibleAbilityManagerService::SetHighContrastTextAbility(bool state)
{
HILOG_DEBUG();
@@ -1816,6 +1881,9 @@ void AccessibleAbilityManagerService::SwitchedUser(int32_t accountId)
RegisterNotificationState();
RegisterSeniorModeState();
RegisterSeniorModeStateForAppObserver();
RegisterFlashReminderMode();
RegisterFlashReminderFunctionEnabled();
RegisterFlashReminderUnlock();
}
// LCOV_EXCL_START
@@ -3311,6 +3379,8 @@ void AccessibleAbilityManagerService::OnFlashReminderSwitchChanged()
bool flashReminderSwitch = config->GetDbHandle()->GetBoolValue(FLASH_REMINDER_SWITCH_KEY, false);
config->SetFlashReminderSwitch(flashReminderSwitch);
UpdateAccessibilityState();
Singleton<AccessibilityBlinkingReminderProxy>::GetInstance().SetFlashReminderSwitch(flashReminderSwitch);
}
void AccessibleAbilityManagerService::RegisterFlashReminderSwitch()
@@ -3333,9 +3403,162 @@ void AccessibleAbilityManagerService::RegisterFlashReminderSwitch()
if (accountData->GetConfig()->GetDbHandle()) {
accountData->GetConfig()->GetDbHandle()->RegisterObserver(FLASH_REMINDER_SWITCH_KEY, func);
}
OnFlashReminderSwitchChanged();
}, "FLASH_REMINDER_SWITCH_KEY_OBSERVER");
}
void AccessibleAbilityManagerService::OnFlashReminderModeChanged()
{
HILOG_DEBUG();
sptr<AccessibilityAccountData> accountData = GetCurrentAccountData();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return;
}
std::shared_ptr<AccessibilitySettingsConfig> config = accountData->GetConfig();
if (config == nullptr) {
HILOG_ERROR("config is nullptr");
return;
}
if (config->GetDbHandle() == nullptr) {
HILOG_ERROR("datashareHelper is nullptr");
return;
}
int32_t flashReminderMode = config->GetDbHandle()->GetIntValue(FLASH_REMINDER_MODE_KEY, 0);
config->SetFlashReminderMode(flashReminderMode);
Singleton<AccessibilityBlinkingReminderProxy>::GetInstance().SetFlashReminderMode(flashReminderMode);
}
void AccessibleAbilityManagerService::RegisterFlashReminderMode()
{
HILOG_DEBUG();
if (handler_ == nullptr) {
HILOG_ERROR("handler_ is nullptr");
return;
}
handler_->PostTask([=]() {
sptr<AccessibilityAccountData> accountData = GetCurrentAccountData();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return;
}
AccessibilitySettingObserver::UpdateFunc func = [ = ](const std::string &state) {
Singleton<AccessibleAbilityManagerService>::GetInstance().OnFlashReminderModeChanged();
};
if (accountData->GetConfig()->GetDbHandle()) {
accountData->GetConfig()->GetDbHandle()->RegisterObserver(FLASH_REMINDER_MODE_KEY, func);
}
OnFlashReminderModeChanged();
}, "FLASH_REMINDER_MODE_KEY_OBSERVER");
}
void AccessibleAbilityManagerService::OnFlashReminderFunctionEnabledChanged()
{
HILOG_DEBUG();
sptr<AccessibilityAccountData> accountData = GetCurrentAccountData();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return;
}
std::shared_ptr<AccessibilitySettingsConfig> config = accountData->GetConfig();
if (config == nullptr) {
HILOG_ERROR("config is nullptr");
return;
}
if (config->GetDbHandle() == nullptr) {
HILOG_ERROR("datashareHelper is nullptr");
return;
}
std::string flashReminderEnabled = config->GetDbHandle()->GetStringValue(FLASH_REMINDER_ENABLED_KEY, "");
config->SetFlashReminderFunctionEnabled(flashReminderEnabled);
Singleton<AccessibilityBlinkingReminderProxy>::GetInstance().SetFlashReminderFunctionEnabled(flashReminderEnabled);
}
void AccessibleAbilityManagerService::RegisterFlashReminderFunctionEnabled()
{
HILOG_DEBUG();
if (handler_ == nullptr) {
HILOG_ERROR("handler_ is nullptr");
return;
}
handler_->PostTask([=]() {
sptr<AccessibilityAccountData> accountData = GetCurrentAccountData();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return;
}
AccessibilitySettingObserver::UpdateFunc func = [ = ](const std::string &state) {
Singleton<AccessibleAbilityManagerService>::GetInstance().OnFlashReminderFunctionEnabledChanged();
};
if (accountData->GetConfig()->GetDbHandle()) {
accountData->GetConfig()->GetDbHandle()->RegisterObserver(FLASH_REMINDER_ENABLED_KEY, func);
}
OnFlashReminderFunctionEnabledChanged();
}, "FLASH_REMINDER_ENABLED_KEY_OBSERVER");
}
void AccessibleAbilityManagerService::OnFlashReminderUnlockChanged()
{
HILOG_DEBUG();
#ifdef OHOS_BUILD_ENABLE_SCREENLOCK_MANAGER
sptr<AccessibilityAccountData> accountData = GetCurrentAccountData();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return;
}
std::shared_ptr<AccessibilitySettingsConfig> config = accountData->GetConfig();
if (config == nullptr) {
HILOG_ERROR("config is nullptr");
return;
}
if (config->GetDbHandle() == nullptr) {
HILOG_ERROR("datashareHelper is nullptr");
return;
}
bool flashReminderUnlock = config->GetDbHandle()->GetBoolValue(FLASH_REMINDER_UNLOCK_KEY, false);
config->SetFlashReminderUnlock(flashReminderUnlock);
Singleton<AccessibilityBlinkingReminderProxy>::GetInstance().SetFlashReminderUnlock(flashReminderUnlock);
#endif
}
void AccessibleAbilityManagerService::RegisterFlashReminderUnlock()
{
HILOG_DEBUG();
if (handler_ == nullptr) {
HILOG_ERROR("handler_ is nullptr");
return;
}
handler_->PostTask([=]() {
sptr<AccessibilityAccountData> accountData = GetCurrentAccountData();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return;
}
AccessibilitySettingObserver::UpdateFunc func = [ = ](const std::string &state) {
Singleton<AccessibleAbilityManagerService>::GetInstance().OnFlashReminderUnlockChanged();
};
if (accountData->GetConfig()->GetDbHandle()) {
accountData->GetConfig()->GetDbHandle()->RegisterObserver(FLASH_REMINDER_UNLOCK_KEY, func);
}
OnFlashReminderUnlockChanged();
}, "FLASH_REMINDER_UNLOCK_KEY_OBSERVER");
}
void AccessibleAbilityManagerService::OnSeniorModeStateChanged()
{
HILOG_DEBUG();
+23
View File
@@ -102,6 +102,18 @@ if (security_component_enable) {
[ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
test_external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
test_external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
test_external_deps += [ "sensor:sensor_interface_native" ]
}
################################################################################
ohos_unittest("accessibility_account_data_test") {
module_out_path = module_output_path
@@ -129,6 +141,7 @@ ohos_unittest("accessibility_account_data_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"mock/src/mock_accessibility_setting_provider.cpp",
"mock/src/mock_accessibility_settings_config.cpp",
"mock/src/mock_accessible_ability_client_stub_impl.cpp",
@@ -198,6 +211,7 @@ ohos_unittest("accessible_ability_manager_service_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"mock/src/aafwk/mock_bundle_manager.cpp",
"mock/src/mock_accessibility_element_operator_callback_stub.cpp",
"mock/src/mock_accessibility_short_key_dialog.cpp",
@@ -263,6 +277,7 @@ ohos_unittest("accessibility_common_event_registry_test") {
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_security_component_manager.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"mock/src/mock_accessibility_account_data.cpp",
"mock/src/mock_accessible_ability_manager_service.cpp",
"mock/src/mock_magnification_manager.cpp",
@@ -315,6 +330,7 @@ ohos_unittest("accessibility_window_manager_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"../src/accessibility_security_component_manager.cpp",
"mock/src/aafwk/mock_bundle_manager.cpp",
"mock/src/mock_accessibility_account_data.cpp",
@@ -378,6 +394,7 @@ ohos_unittest("accessible_ability_connection_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"mock/src/aafwk/mock_bundle_manager.cpp",
"mock/src/mock_accessibility_element_operator_callback_stub.cpp",
"mock/src/mock_accessibility_element_operator_stub.cpp",
@@ -429,6 +446,7 @@ ohos_unittest("accessibility_dumper_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"../src/accessibility_security_component_manager.cpp",
"mock/src/mock_accessibility_account_data.cpp",
"mock/src/mock_accessibility_common_event.cpp",
@@ -494,6 +512,7 @@ ohos_unittest("accessible_ability_channel_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"../src/accessibility_security_component_manager.cpp",
"mock/src/mock_accessibility_element_operator_proxy.cpp",
"mock/src/mock_accessibility_element_operator_stub.cpp",
@@ -558,6 +577,7 @@ ohos_unittest("accessibility_short_key_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"../src/accessibility_security_component_manager.cpp",
"mock/src/mock_accessibility_common_event.cpp",
"mock/src/mock_accessibility_event_transmission.cpp",
@@ -614,6 +634,7 @@ ohos_unittest("accessibility_short_key_dialog_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"../src/accessibility_security_component_manager.cpp",
"mock/src/mock_accessibility_common_event.cpp",
"mock/src/mock_accessibility_event_transmission.cpp",
@@ -683,6 +704,7 @@ ohos_unittest("accessible_ability_manager_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"mock/src/aafwk/mock_bundle_manager.cpp",
"mock/src/mock_accessibility_element_operator_callback_stub.cpp",
"mock/src/mock_accessibility_short_key_dialog.cpp",
@@ -749,6 +771,7 @@ ohos_unittest("accessibility_settings_config_test") {
"../src/accessible_ability_manager.cpp",
"../src/accessibility_element_operator_manager.cpp",
"../src/element_operator_callback_impl.cpp",
"../src/accessibility_blinking_reminder_proxy.cpp",
"mock/src/mock_magnification_manager.cpp",
"mock/src/mock_permission.cpp",
"unittest/accessibility_settings_config_test.cpp",
@@ -606,5 +606,6 @@ void AccessibilityAccountData::RemoveSeniorModeStateObserver(const wptr<IRemoteO
void AccessibilityAccountData::AddSeniorModeStateObserver(
const sptr<IAccessibilityAppSeniorModeStateObserver>& observer) {}
} // namespace Accessibility
} // namespace OHOS
@@ -588,5 +588,44 @@ std::map<std::string, bool> AccessibilitySettingsConfig::GetSeniorModeStateForAp
std::map<std::string, bool> ret;
return ret;
}
RetError AccessibilitySettingsConfig::SetFlashReminderMode(const int32_t mode)
{
HILOG_DEBUG("start.");
flashReminderMode_ = mode;
return RET_OK;
}
RetError AccessibilitySettingsConfig::SetFlashReminderFunctionEnabled(const std::string &enabled)
{
HILOG_DEBUG("start.");
flashReminderFunctionEnabled_ = enabled;
return RET_OK;
}
RetError AccessibilitySettingsConfig::SetFlashReminderUnlock(const bool state)
{
HILOG_DEBUG("start.");
flashReminderUnlock_ = state;
return RET_OK;
}
int32_t AccessibilitySettingsConfig::GetFlashReminderMode() const
{
HILOG_DEBUG("start.");
return flashReminderMode_;
}
const std::string &AccessibilitySettingsConfig::GetFlashReminderFunctionEnabled() const
{
HILOG_DEBUG("start.");
return flashReminderFunctionEnabled_;
}
bool AccessibilitySettingsConfig::GetFlashReminderUnlock() const
{
HILOG_DEBUG("start.");
return flashReminderUnlock_;
}
} // namespace Accessibility
} // namespace OHOS
@@ -919,5 +919,19 @@ ErrCode AccessibleAbilityManagerService::SetSeniorModeStateForApp(
{
return RET_OK;
}
ErrCode AccessibleAbilityManagerService::StartBlinking(int32_t mode, int32_t scenario, int32_t &funcResult)
{
HILOG_DEBUG("StartBlinking start.");
funcResult = RET_OK;
return RET_OK;
}
ErrCode AccessibleAbilityManagerService::StopBlinking(int32_t mode, int32_t scenario, int32_t &funcResult)
{
HILOG_DEBUG("StopBlinking start.");
funcResult = RET_OK;
return RET_OK;
}
} // namespace Accessibility
} // namespace OHOS
+12
View File
@@ -104,6 +104,10 @@ if (security_component_enable) {
[ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_sensor_support) {
test_external_deps += [ "sensor:sensor_interface_native" ]
}
################################################################################
ohos_unittest("accessibility_display_manager_test") {
module_out_path = module_output_path
@@ -183,6 +187,10 @@ ohos_unittest("accessibility_input_interceptor_test") {
]
external_deps = test_external_deps
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
}
################################################################################
@@ -402,6 +410,10 @@ ohos_unittest("accessibility_touchevent_injector_test") {
]
external_deps = test_external_deps
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
}
################################################################################
+105
View File
@@ -0,0 +1,105 @@
# Copyright (C) 2026-2026 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.
import("//build/ohos.gni")
import("../../accessibility_manager_service.gni")
blinking_reminder_path = "./"
config("blinking_reminder_config") {
visibility = [ ":*" ]
include_dirs = [
"inc",
"../aams/include",
"../../common/log/include",
"../../interfaces/innerkits/common/include",
]
defines = [
"AAMS_LOG_TAG = \"accessibility\"",
"AAMS_LOG_DOMAIN = 0xD001D00",
]
if (build_variant == "user") {
defines += [ "RELEASE_VERSION" ]
}
defines += accessibility_default_defines
}
blinking_reminder_files = [
"${blinking_reminder_path}/src/accessible_blinking_reminder_manager.cpp",
"${blinking_reminder_path}/src/export_api.cpp",
]
ohos_shared_library("accessibleBlinking") {
branch_protector_ret = "pac_ret"
sanitize = {
integer_overflow = true
ubsan = true
boundary_sanitize = true
cfi = true
cfi_cross_dso = true
debug = false
}
cflags = [
"-ffunction-sections",
"-fdata-sections",
]
ldflags = [
"-Wl,--gc-sections",
]
sources = blinking_reminder_files
configs = [
":blinking_reminder_config",
"../../resources/config/build:coverage_flags",
]
deps = [
"../../interfaces/innerkits/common:accessibility_common",
]
external_deps = [
"c_utils:utils",
"ffrt:libffrt",
"hilog:libhilog",
"ipc:ipc_single",
"power_manager:powermgr_client",
]
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
if (accessibility_feature_display_manager) {
external_deps += [ "display_manager:displaymgr" ]
}
install_enable = true
subsystem_name = "barrierfree"
part_name = "accessibility"
}
@@ -0,0 +1,173 @@
/*
* Copyright (C) 2026-2026 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.
*/
#ifndef ACCESSIBLE_BLINKING_REMINDER_MANAGER_H
#define ACCESSIBLE_BLINKING_REMINDER_MANAGER_H
#include <atomic>
#include <condition_variable>
#include <map>
#include <mutex>
#include <set>
#include <memory>
#include <string>
#include <thread>
#include "singleton.h"
#include "accessibility_def.h"
#ifdef OHOS_BUILD_ENABLE_SENSOR
#include "sensor_agent.h"
#endif
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
#include "display_power_mgr_client.h"
#include "display_brightness_listener_stub.h"
#endif
namespace OHOS {
namespace Accessibility {
class AccessibleBlinkingReminderManager;
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
class DisplayBlinkListener : public DisplayPowerMgr::DisplayBrightnessListenerStub {
public:
explicit DisplayBlinkListener(AccessibleBlinkingReminderManager *manager,
DisplayPowerMgr::DisplayDataChangeListenerType type)
: manager_(manager), listenerType_(type) {}
~DisplayBlinkListener() override = default;
void OnDataChanged(const std::string &params) override;
private:
AccessibleBlinkingReminderManager *manager_ = nullptr;
DisplayPowerMgr::DisplayDataChangeListenerType listenerType_;
};
#endif
class AccessibleBlinkingReminderManager {
DECLARE_SINGLETON(AccessibleBlinkingReminderManager);
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
friend class DisplayBlinkListener;
#endif
public:
void SetFlashReminderSwitch(bool state);
void SetFlashReminderMode(int32_t mode);
void SetFlashReminderFunctionEnabled(const std::string &enabled);
void SetFlashReminderUnlock(bool state);
BlinkResultCode StartBlinking(int32_t mode, int32_t scenario);
BlinkResultCode StopBlinking(int32_t mode, int32_t scenario);
private:
struct ScenarioState {
int32_t scenario = 0;
int64_t joinTimeMs = 0;
int64_t displayStartTimeMs = 0;
bool displayExpired = false;
bool flashlightExpired = false;
};
struct BlinkState {
bool flashReminderSwitch = false;
int32_t flashReminderMode = FlashReminderMode::NONE;
std::string flashReminderFunctionEnabled;
bool flashReminderUnlock = false;
bool isRunning = false;
int32_t currentMode = 0;
int32_t singleScenario = 0;
bool pausedByProximity = false;
bool proximityNear = false;
bool originalFlashlightState = false;
std::map<int32_t, ScenarioState> scenarioStates;
};
BlinkState state_;
std::mutex mutex_;
std::condition_variable cv_;
std::unique_ptr<std::thread> blinkingThread_;
bool flashlightSupported_ = false;
bool flashlightSupportChecked_ = false;
bool displayBlinkSupported_ = false;
bool displayBlinkSupportChecked_ = false;
bool sensorSubscribed_ = false;
#ifdef OHOS_BUILD_ENABLE_SENSOR
SensorUser sensorUser_ {};
#endif
bool brightnessListenerRegistered_ = false;
bool faceDetectionListenerRegistered_ = false;
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
sptr<DisplayPowerMgr::IDisplayBrightnessListener> displayBlinkListener_;
sptr<DisplayPowerMgr::IDisplayBrightnessListener> faceDetectionListener_;
#endif
int64_t lastDisplayBusyTimeMs_ = 0;
bool brightnessAdjusting_ = false;
bool faceDetectionAdjusting_ = false;
static std::atomic<AccessibleBlinkingReminderManager*> callbackInstance_;
static bool IsDisplayEnabled(int32_t mode);
static bool IsFlashlightEnabled(int32_t mode);
static int64_t GetCurrentTimeMs();
static ScenarioState MakeScenarioState(int32_t scenario, int32_t mode, bool displayBlocked);
bool IsScreenLocked();
bool IsScenarioEnabled(int32_t scenario);
bool IsFlashlightSupported();
bool IsDisplaySupported();
static int32_t ComputeEffectiveMode(const BlinkState &state);
void JoinFinishedThread(std::unique_lock<std::mutex> &lock);
void ForceStopBlinkingInternal(std::unique_lock<std::mutex> &lock, int32_t cleanupMode);
void ForceStopAll();
void ResetRuntimeState();
void BlinkingWorkSingle();
void BlinkingWorkContinuous();
void ExecuteBlinkCycle(std::unique_lock<std::mutex> &lock, int32_t mode, bool isOn);
void CleanupBlinking(int32_t flashReminderMode);
void RemoveExpiredScenarios();
bool SetFlashlightMode(bool isOn);
void SetDisplayBlinkMode(bool isOn);
void SaveOriginalFlashlightState();
void SubscribeProximitySensor();
void UnsubscribeProximitySensor();
void RegisterDisplayListener();
void UnregisterDisplayListener();
static void OnProximitySensorEvent(SensorEvent *event);
void HandleProximityStateChange(bool isNear);
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
void HandleBrightnessSliderEvent(const std::string &params);
void HandleFaceDetectionEvent(const std::string &params);
#endif
void ExpireFlashlightForAll(std::unique_lock<std::mutex> &lock);
void ExpireDisplayForAll(std::unique_lock<std::mutex> &lock);
bool HasAnyActiveComponent();
void StopByUnlockDisabled(std::unique_lock<std::mutex> &lock);
BlinkResultCode HandleStartSingleBlink(int32_t scenario, int32_t mode, bool displayBlocked);
BlinkResultCode HandleStartContinuousBlink(std::unique_lock<std::mutex> &lock,
int32_t scenario, int32_t mode, bool displayBlocked);
BlinkResultCode HandleStopSingleBlink(std::unique_lock<std::mutex> &lock, int32_t scenario);
BlinkResultCode HandleStopContinuousBlink(std::unique_lock<std::mutex> &lock, int32_t scenario);
BlinkResultCode ValidateStartBlinking(int32_t scenario, int32_t &flashReminderMode, bool &displayBlocked);
};
} // namespace Accessibility
} // namespace OHOS
#endif // ACCESSIBLE_BLINKING_REMINDER_MANAGER_H
@@ -0,0 +1,897 @@
/*
* Copyright (C) 2026-2026 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 "accessible_blinking_reminder_manager.h"
#include "hilog_wrapper.h"
#include <chrono>
#include <memory>
#include <thread>
#include <vector>
#ifdef OHOS_BUILD_ENABLE_CAMERA
#include "input/camera_manager.h"
#endif
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
#include "display_power_mgr_client.h"
#endif
#ifdef OHOS_BUILD_ENABLE_SCREENLOCK_MANAGER
#include "screenlock_manager.h"
#endif
#include <securec.h>
namespace OHOS {
namespace Accessibility {
namespace {
struct ScenarioMapping {
int32_t scenario;
const char *name;
};
const ScenarioMapping SCENARIO_MAPPINGS[] = {
{BlinkingScenario::ALARM, "ALARM_CLOCK"},
{BlinkingScenario::NOTIFICATION, "NOTIFY"},
{BlinkingScenario::CALL, "INCOMING_CALL"},
};
std::set<int32_t> ParseEnabledScenarios(const std::string &enabled)
{
std::set<int32_t> scenarios;
for (const auto &mapping : SCENARIO_MAPPINGS) {
if (enabled.find(mapping.name) != std::string::npos) {
scenarios.insert(mapping.scenario);
}
}
return scenarios;
}
const char *GetScenarioName(int32_t scenario)
{
for (const auto &mapping : SCENARIO_MAPPINGS) {
if (mapping.scenario == scenario) {
return mapping.name;
}
}
return nullptr;
}
} // namespace
constexpr int32_t SINGLE_BLINK_PHASE_COUNT = 4;
constexpr int32_t BLINK_INTERVAL_MS = 250;
constexpr int32_t FLASH_BLINK_MAX_DURATION_MS = 1800000;
constexpr int32_t DISPLAY_BLINK_MAX_DURATION_MS = 10000;
constexpr uint32_t DEFAULT_DISPLAY_ID = 0;
constexpr uint32_t BRIGHTNESS_TRANSITION_DURATION_MS = 0;
constexpr double FORCED_BRIGHTNESS_ON_VALUE = 1.0;
constexpr double FORCED_BRIGHTNESS_OFF_VALUE = -1.0;
constexpr int32_t BLINKING_MODE_IDLE = 0;
constexpr int32_t BLINKING_SCENARIO_IDLE = 0;
constexpr int64_t PROXIMITY_SENSOR_SAMPLING_PERIOD_NS = 100000000;
constexpr float PROXIMITY_THRESHOLD = 1.0f;
constexpr int64_t DISPLAY_BUSY_THRESHOLD_MS = 1000;
AccessibleBlinkingReminderManager::AccessibleBlinkingReminderManager() {}
AccessibleBlinkingReminderManager::~AccessibleBlinkingReminderManager()
{
{
std::unique_lock<std::mutex> lock(mutex_);
state_.isRunning = false;
}
cv_.notify_all();
if (blinkingThread_ && blinkingThread_->joinable()) {
blinkingThread_->join();
}
blinkingThread_.reset();
}
bool AccessibleBlinkingReminderManager::IsDisplayEnabled(int32_t mode)
{
return (mode & FlashReminderMode::DISPLAY) != 0;
}
bool AccessibleBlinkingReminderManager::IsFlashlightEnabled(int32_t mode)
{
return (mode & FlashReminderMode::FLASHLIGHT) != 0;
}
int64_t AccessibleBlinkingReminderManager::GetCurrentTimeMs()
{
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count();
}
AccessibleBlinkingReminderManager::ScenarioState
AccessibleBlinkingReminderManager::MakeScenarioState(
int32_t scenario, int32_t mode, bool displayBlocked)
{
ScenarioState scenarioState;
scenarioState.scenario = scenario;
scenarioState.joinTimeMs = GetCurrentTimeMs();
scenarioState.displayExpired = displayBlocked || !IsDisplayEnabled(mode);
scenarioState.flashlightExpired = !IsFlashlightEnabled(mode);
if (!scenarioState.displayExpired) {
scenarioState.displayStartTimeMs = scenarioState.joinTimeMs;
}
return scenarioState;
}
bool AccessibleBlinkingReminderManager::IsScreenLocked()
{
#ifdef OHOS_BUILD_ENABLE_SCREENLOCK_MANAGER
return ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked();
#else
return false;
#endif
}
bool AccessibleBlinkingReminderManager::IsScenarioEnabled(int32_t scenario)
{
const std::string &enabled = state_.flashReminderFunctionEnabled;
if (enabled.empty()) {
return false;
}
const char *name = GetScenarioName(scenario);
return name != nullptr && enabled.find(name) != std::string::npos;
}
bool AccessibleBlinkingReminderManager::IsFlashlightSupported()
{
#ifdef OHOS_BUILD_ENABLE_CAMERA
if (flashlightSupportChecked_) {
return flashlightSupported_;
}
sptr<CameraStandard::CameraManager> cameraManager = CameraStandard::CameraManager::GetInstance();
if (!cameraManager) {
HILOG_ERROR("Failed to get camera manager");
return false;
}
flashlightSupported_ = cameraManager->IsTorchSupported();
flashlightSupportChecked_ = true;
return flashlightSupported_;
#else
return false;
#endif
}
bool AccessibleBlinkingReminderManager::IsDisplaySupported()
{
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
if (displayBlinkSupportChecked_) {
return displayBlinkSupported_;
}
displayBlinkSupported_ = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetFeatureSupport(
DisplayPowerMgr::BrightnessFeatureType::SCREEN_FLASH);
displayBlinkSupportChecked_ = true;
return displayBlinkSupported_;
#else
return false;
#endif
}
int32_t AccessibleBlinkingReminderManager::ComputeEffectiveMode(const BlinkState &state)
{
if (state.scenarioStates.empty()) {
return FlashReminderMode::NONE;
}
bool anyDisplay = false;
bool anyFlash = false;
for (const auto &[_, scenarioState] : state.scenarioStates) {
if (!scenarioState.displayExpired) {
anyDisplay = true;
}
if (!scenarioState.flashlightExpired) {
anyFlash = true;
}
}
int32_t active = FlashReminderMode::NONE;
if (anyDisplay) {
active |= FlashReminderMode::DISPLAY;
}
if (anyFlash) {
active |= FlashReminderMode::FLASHLIGHT;
}
return active & state.flashReminderMode;
}
void AccessibleBlinkingReminderManager::ResetRuntimeState()
{
state_.currentMode = BLINKING_MODE_IDLE;
state_.singleScenario = BLINKING_SCENARIO_IDLE;
state_.scenarioStates.clear();
state_.pausedByProximity = false;
}
void AccessibleBlinkingReminderManager::JoinFinishedThread(std::unique_lock<std::mutex> &lock)
{
if (!state_.isRunning && blinkingThread_ && blinkingThread_->joinable()) {
lock.unlock();
blinkingThread_->join();
lock.lock();
blinkingThread_.reset();
ResetRuntimeState();
}
}
void AccessibleBlinkingReminderManager::ForceStopBlinkingInternal(
std::unique_lock<std::mutex> &lock, int32_t cleanupMode)
{
HILOG_INFO("cleanupMode=%{public}d", cleanupMode);
state_.isRunning = false;
cv_.notify_all();
lock.unlock();
if (blinkingThread_ && blinkingThread_->joinable()) {
blinkingThread_->join();
}
blinkingThread_.reset();
lock.lock();
CleanupBlinking(cleanupMode);
ResetRuntimeState();
}
void AccessibleBlinkingReminderManager::ForceStopAll()
{
HILOG_INFO("ForceStopAll");
std::unique_lock<std::mutex> lock(mutex_);
if (!state_.isRunning) {
return;
}
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
}
void AccessibleBlinkingReminderManager::ExecuteBlinkCycle(
std::unique_lock<std::mutex> &lock, int32_t mode, bool isOn)
{
bool doFlash = IsFlashlightEnabled(mode);
bool doDisplay = !state_.pausedByProximity && IsDisplayEnabled(mode);
lock.unlock();
if (doFlash) {
SetFlashlightMode(isOn);
}
if (doDisplay) {
SetDisplayBlinkMode(isOn);
}
lock.lock();
}
void AccessibleBlinkingReminderManager::RemoveExpiredScenarios()
{
int64_t nowMs = GetCurrentTimeMs();
std::vector<int32_t> toRemove;
for (auto &[scenario, scenarioState] : state_.scenarioStates) {
if (!scenarioState.displayExpired && scenarioState.displayStartTimeMs > 0 &&
(nowMs - scenarioState.displayStartTimeMs) >= DISPLAY_BLINK_MAX_DURATION_MS) {
scenarioState.displayExpired = true;
}
if (!scenarioState.flashlightExpired &&
(nowMs - scenarioState.joinTimeMs) >= FLASH_BLINK_MAX_DURATION_MS) {
scenarioState.flashlightExpired = true;
}
if (scenarioState.displayExpired && scenarioState.flashlightExpired) {
toRemove.push_back(scenario);
}
}
for (int32_t scenario : toRemove) {
HILOG_INFO("Removing expired scenario %{public}d", scenario);
state_.scenarioStates.erase(scenario);
}
}
void AccessibleBlinkingReminderManager::CleanupBlinking(int32_t flashReminderMode)
{
if (IsDisplayEnabled(flashReminderMode)) {
SetDisplayBlinkMode(false);
}
if (IsFlashlightEnabled(flashReminderMode)) {
SetFlashlightMode(state_.originalFlashlightState);
}
}
void AccessibleBlinkingReminderManager::BlinkingWorkSingle()
{
HILOG_INFO("Single blinking work start");
std::unique_lock<std::mutex> lock(mutex_);
for (int32_t i = 0; i < SINGLE_BLINK_PHASE_COUNT; ++i) {
if (!state_.isRunning) {
return;
}
int32_t effectiveMode = ComputeEffectiveMode(state_);
ExecuteBlinkCycle(lock, effectiveMode, i % 2 == 0);
if (cv_.wait_for(lock, std::chrono::milliseconds(BLINK_INTERVAL_MS),
[this] { return !state_.isRunning; })) {
return;
}
}
int32_t cleanupMode = state_.flashReminderMode;
state_.isRunning = false;
ResetRuntimeState();
lock.unlock();
CleanupBlinking(cleanupMode);
}
void AccessibleBlinkingReminderManager::BlinkingWorkContinuous()
{
HILOG_INFO("Continuous blinking work start");
bool isOn = true;
std::unique_lock<std::mutex> lock(mutex_);
while (state_.isRunning) {
RemoveExpiredScenarios();
int32_t effectiveMode = ComputeEffectiveMode(state_);
if (effectiveMode == FlashReminderMode::NONE || state_.scenarioStates.empty()) {
break;
}
ExecuteBlinkCycle(lock, effectiveMode, isOn);
isOn = !isOn;
if (!state_.isRunning) {
break;
}
if (cv_.wait_for(lock, std::chrono::milliseconds(BLINK_INTERVAL_MS),
[this] { return !state_.isRunning; })) {
break;
}
}
int32_t cleanupMode = state_.flashReminderMode;
state_.isRunning = false;
ResetRuntimeState();
lock.unlock();
CleanupBlinking(cleanupMode);
}
void AccessibleBlinkingReminderManager::SaveOriginalFlashlightState()
{
#ifdef OHOS_BUILD_ENABLE_CAMERA
sptr<CameraStandard::CameraManager> cameraManager = CameraStandard::CameraManager::GetInstance();
if (!cameraManager) {
HILOG_ERROR("Failed to get camera manager");
return;
}
state_.originalFlashlightState =
(cameraManager->GetTorchMode() == CameraStandard::TORCH_MODE_ON);
#endif
}
bool AccessibleBlinkingReminderManager::SetFlashlightMode(bool isOn)
{
#ifdef OHOS_BUILD_ENABLE_CAMERA
sptr<CameraStandard::CameraManager> cameraManager = CameraStandard::CameraManager::GetInstance();
if (!cameraManager) {
HILOG_ERROR("Failed to get camera manager");
return false;
}
auto torchMode = isOn ? CameraStandard::TORCH_MODE_ON : CameraStandard::TORCH_MODE_OFF;
int32_t ret = cameraManager->SetTorchMode(torchMode);
if (ret != 0) {
HILOG_ERROR("SetTorchMode failed, mode=%{public}d, ret=%{public}d", torchMode, ret);
return false;
}
#else
(void)isOn;
#endif
return true;
}
void AccessibleBlinkingReminderManager::SetDisplayBlinkMode(bool isOn)
{
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
auto &client = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance();
double value = isOn ? FORCED_BRIGHTNESS_ON_VALUE : FORCED_BRIGHTNESS_OFF_VALUE;
client.SetForcedBrightness(value, DEFAULT_DISPLAY_ID, BRIGHTNESS_TRANSITION_DURATION_MS,
DisplayPowerMgr::BrightnessValueType::RELATIVE_TO_MAX_RANGE);
#else
(void)isOn;
#endif
}
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
void DisplayBlinkListener::OnDataChanged(const std::string &params)
{
HILOG_INFO("params=%{public}s, type=%{public}d",
params.c_str(), static_cast<int32_t>(listenerType_));
if (manager_ == nullptr) {
HILOG_ERROR("manager_ is null");
return;
}
if (listenerType_ == DisplayPowerMgr::DisplayDataChangeListenerType::BRIGHTNESS_SLIDER) {
manager_->HandleBrightnessSliderEvent(params);
} else if (listenerType_ == DisplayPowerMgr::DisplayDataChangeListenerType::FACE_DETECTION_STATE) {
manager_->HandleFaceDetectionEvent(params);
}
}
void AccessibleBlinkingReminderManager::HandleBrightnessSliderEvent(const std::string &params)
{
bool isDown = params.find("down") != std::string::npos;
bool isUp = params.find("up") != std::string::npos;
std::unique_lock<std::mutex> lock(mutex_);
if (isDown) {
brightnessAdjusting_ = true;
ExpireDisplayForAll(lock);
} else if (isUp) {
brightnessAdjusting_ = false;
}
}
void AccessibleBlinkingReminderManager::HandleFaceDetectionEvent(const std::string &params)
{
bool isEnter = params.find("enter") != std::string::npos;
bool isExit = params.find("exit") != std::string::npos;
std::unique_lock<std::mutex> lock(mutex_);
if (isEnter) {
faceDetectionAdjusting_ = true;
ExpireDisplayForAll(lock);
} else if (isExit) {
faceDetectionAdjusting_ = false;
}
}
#endif
void AccessibleBlinkingReminderManager::RegisterDisplayListener()
{
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
auto &client = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance();
if (!brightnessListenerRegistered_) {
displayBlinkListener_ = new DisplayBlinkListener(this,
DisplayPowerMgr::DisplayDataChangeListenerType::BRIGHTNESS_SLIDER);
ErrCode err = client.RegisterDataChangeListener(displayBlinkListener_,
DisplayPowerMgr::DisplayDataChangeListenerType::BRIGHTNESS_SLIDER,
"Accessibility_BrightnessSlider", "");
if (err != ERR_OK) {
HILOG_ERROR("Register BRIGHTNESS_SLIDER failed, err=%{public}d", err);
displayBlinkListener_ = nullptr;
} else {
HILOG_INFO("Register BRIGHTNESS_SLIDER success");
brightnessListenerRegistered_ = true;
}
}
if (!faceDetectionListenerRegistered_) {
faceDetectionListener_ = new DisplayBlinkListener(this,
DisplayPowerMgr::DisplayDataChangeListenerType::FACE_DETECTION_STATE);
ErrCode err = client.RegisterDataChangeListener(faceDetectionListener_,
DisplayPowerMgr::DisplayDataChangeListenerType::FACE_DETECTION_STATE,
"Accessibility_FaceDetection", "");
if (err != ERR_OK) {
HILOG_ERROR("Register FACE_DETECTION failed, err=%{public}d", err);
faceDetectionListener_ = nullptr;
} else {
HILOG_INFO("Register FACE_DETECTION success");
faceDetectionListenerRegistered_ = true;
}
}
#endif
}
void AccessibleBlinkingReminderManager::UnregisterDisplayListener()
{
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
auto &client = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance();
if (brightnessListenerRegistered_) {
client.UnregisterDataChangeListener(
DisplayPowerMgr::DisplayDataChangeListenerType::BRIGHTNESS_SLIDER,
"Accessibility_BrightnessSlider");
displayBlinkListener_ = nullptr;
brightnessListenerRegistered_ = false;
}
if (faceDetectionListenerRegistered_) {
client.UnregisterDataChangeListener(
DisplayPowerMgr::DisplayDataChangeListenerType::FACE_DETECTION_STATE,
"Accessibility_FaceDetection");
faceDetectionListener_ = nullptr;
faceDetectionListenerRegistered_ = false;
}
#endif
}
std::atomic<AccessibleBlinkingReminderManager*>
AccessibleBlinkingReminderManager::callbackInstance_{nullptr};
void AccessibleBlinkingReminderManager::SubscribeProximitySensor()
{
if (sensorSubscribed_) {
return;
}
if (strcpy_s(sensorUser_.name, sizeof(sensorUser_.name), "Accessibility") != EOK) {
HILOG_ERROR("strcpy_s error");
return;
}
sensorUser_.userData = nullptr;
sensorUser_.callback = OnProximitySensorEvent;
callbackInstance_.store(this);
int32_t ret = SubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
if (ret != 0) {
HILOG_ERROR("SubscribeSensor failed, ret=%{public}d", ret);
callbackInstance_.store(nullptr);
return;
}
ret = SetBatch(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_,
PROXIMITY_SENSOR_SAMPLING_PERIOD_NS, PROXIMITY_SENSOR_SAMPLING_PERIOD_NS);
if (ret != 0) {
HILOG_ERROR("SetBatch failed, ret=%{public}d", ret);
UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
callbackInstance_.store(nullptr);
return;
}
ret = ActivateSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
if (ret != 0) {
HILOG_ERROR("ActivateSensor failed, ret=%{public}d", ret);
UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
callbackInstance_.store(nullptr);
return;
}
ret = SetMode(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_, SENSOR_ON_CHANGE);
if (ret != 0) {
HILOG_ERROR("SetMode failed, ret=%{public}d", ret);
DeactivateSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
callbackInstance_.store(nullptr);
return;
}
sensorSubscribed_ = true;
}
void AccessibleBlinkingReminderManager::UnsubscribeProximitySensor()
{
if (!sensorSubscribed_) {
return;
}
DeactivateSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &sensorUser_);
sensorSubscribed_ = false;
callbackInstance_.store(nullptr);
}
void AccessibleBlinkingReminderManager::OnProximitySensorEvent(SensorEvent *event)
{
if (event == nullptr || event->data == nullptr) {
return;
}
auto *data = reinterpret_cast<ProximityData*>(event->data);
bool isNear = (data->distance < PROXIMITY_THRESHOLD);
auto *instance = callbackInstance_.load();
if (instance != nullptr) {
instance->HandleProximityStateChange(isNear);
}
}
void AccessibleBlinkingReminderManager::HandleProximityStateChange(bool isNear)
{
std::unique_lock<std::mutex> lock(mutex_);
if (isNear && !state_.proximityNear) {
state_.proximityNear = true;
if (state_.isRunning && !state_.pausedByProximity) {
state_.pausedByProximity = true;
lock.unlock();
SetDisplayBlinkMode(false);
}
} else if (!isNear && state_.proximityNear) {
state_.proximityNear = false;
bool anyDisplayActive = false;
for (const auto &[_, scenarioState] : state_.scenarioStates) {
if (!scenarioState.displayExpired) {
anyDisplayActive = true;
break;
}
}
if (anyDisplayActive && state_.pausedByProximity) {
state_.pausedByProximity = false;
}
}
}
void AccessibleBlinkingReminderManager::ExpireFlashlightForAll(std::unique_lock<std::mutex> &lock)
{
HILOG_INFO();
bool anyActive = false;
for (auto &[_, scenarioState] : state_.scenarioStates) {
if (!scenarioState.flashlightExpired) {
scenarioState.flashlightExpired = true;
anyActive = true;
}
}
if (anyActive) {
lock.unlock();
SetFlashlightMode(state_.originalFlashlightState);
lock.lock();
}
}
void AccessibleBlinkingReminderManager::ExpireDisplayForAll(std::unique_lock<std::mutex> &lock)
{
HILOG_INFO();
bool anyActive = false;
for (auto &[_, scenarioState] : state_.scenarioStates) {
if (!scenarioState.displayExpired) {
scenarioState.displayExpired = true;
anyActive = true;
}
}
if (anyActive) {
lock.unlock();
SetDisplayBlinkMode(false);
lock.lock();
}
}
bool AccessibleBlinkingReminderManager::HasAnyActiveComponent()
{
for (const auto &[_, scenarioState] : state_.scenarioStates) {
if (!scenarioState.displayExpired || !scenarioState.flashlightExpired) {
return true;
}
}
return false;
}
void AccessibleBlinkingReminderManager::StopByUnlockDisabled(std::unique_lock<std::mutex> &lock)
{
if (!state_.isRunning) {
return;
}
if (state_.currentMode == BlinkingMode::SINGLE_BLINK &&
state_.singleScenario != BlinkingScenario::TESTING) {
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
} else if (state_.currentMode == BlinkingMode::CONTINUOUS_BLINK) {
std::vector<int32_t> toRemove;
for (const auto &[scenario, _] : state_.scenarioStates) {
if (scenario != BlinkingScenario::TESTING) {
toRemove.push_back(scenario);
}
}
for (int32_t scenario : toRemove) {
state_.scenarioStates.erase(scenario);
}
if (state_.scenarioStates.empty()) {
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
}
}
}
BlinkResultCode AccessibleBlinkingReminderManager::ValidateStartBlinking(
int32_t scenario, int32_t &flashReminderMode, bool &displayBlocked)
{
if (!state_.flashReminderSwitch) {
return BlinkResultCode::FEATURE_DISABLE;
}
flashReminderMode = state_.flashReminderMode;
if (flashReminderMode == FlashReminderMode::NONE) {
return BlinkResultCode::FEATURE_DISABLE;
}
if (scenario != BlinkingScenario::TESTING) {
if (!state_.flashReminderUnlock && !IsScreenLocked()) {
return BlinkResultCode::FEATURE_DISABLE;
}
if (!IsScenarioEnabled(scenario)) {
return BlinkResultCode::FEATURE_DISABLE;
}
}
if (IsDisplayEnabled(flashReminderMode) && !IsDisplaySupported()) {
return BlinkResultCode::SCREEN_BLINKING_UNSUPPORTED;
}
if (IsFlashlightEnabled(flashReminderMode) && !IsFlashlightSupported()) {
return BlinkResultCode::FLASH_BLINKING_UNSUPPORTED;
}
if (IsDisplayEnabled(flashReminderMode)) {
bool blocked = state_.proximityNear || brightnessAdjusting_ || faceDetectionAdjusting_;
if (blocked) {
if (flashReminderMode == FlashReminderMode::DISPLAY) {
return BlinkResultCode::DEVICE_IN_USE;
}
displayBlocked = true;
}
}
return BlinkResultCode::BLINK_SUCCESS;
}
BlinkResultCode AccessibleBlinkingReminderManager::HandleStartSingleBlink(
int32_t scenario, int32_t mode, bool displayBlocked)
{
HILOG_INFO("scenario=%{public}d, mode=%{public}d, displayBlocked=%{public}d",
scenario, mode, displayBlocked);
if (state_.isRunning) {
return BlinkResultCode::ALREADY_FLASHING;
}
state_.currentMode = BlinkingMode::SINGLE_BLINK;
state_.singleScenario = scenario;
state_.flashReminderMode = mode;
state_.scenarioStates[scenario] = MakeScenarioState(scenario, mode, displayBlocked);
state_.isRunning = true;
blinkingThread_ = std::make_unique<std::thread>(
&AccessibleBlinkingReminderManager::BlinkingWorkSingle, this);
return BlinkResultCode::BLINK_SUCCESS;
}
BlinkResultCode AccessibleBlinkingReminderManager::HandleStartContinuousBlink(
std::unique_lock<std::mutex> &lock, int32_t scenario, int32_t mode, bool displayBlocked)
{
HILOG_INFO("scenario=%{public}d, mode=%{public}d, displayBlocked=%{public}d",
scenario, mode, displayBlocked);
if (state_.isRunning && state_.currentMode == BlinkingMode::SINGLE_BLINK) {
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
}
if (state_.isRunning && state_.currentMode == BlinkingMode::CONTINUOUS_BLINK) {
if (state_.scenarioStates.find(scenario) != state_.scenarioStates.end()) {
return BlinkResultCode::BLINK_SUCCESS;
}
state_.scenarioStates[scenario] = MakeScenarioState(scenario, mode, displayBlocked);
return BlinkResultCode::BLINK_SUCCESS;
}
state_.currentMode = BlinkingMode::CONTINUOUS_BLINK;
state_.flashReminderMode = mode;
state_.scenarioStates[scenario] = MakeScenarioState(scenario, mode, displayBlocked);
state_.isRunning = true;
blinkingThread_ = std::make_unique<std::thread>(
&AccessibleBlinkingReminderManager::BlinkingWorkContinuous, this);
return BlinkResultCode::BLINK_SUCCESS;
}
BlinkResultCode AccessibleBlinkingReminderManager::HandleStopSingleBlink(
std::unique_lock<std::mutex> &lock, int32_t scenario)
{
HILOG_INFO("scenario=%{public}d", scenario);
if (state_.currentMode != BlinkingMode::SINGLE_BLINK) {
return BlinkResultCode::BLINK_SUCCESS;
}
if (scenario != state_.singleScenario) {
return BlinkResultCode::BLINK_SUCCESS;
}
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
return BlinkResultCode::BLINK_SUCCESS;
}
BlinkResultCode AccessibleBlinkingReminderManager::HandleStopContinuousBlink(
std::unique_lock<std::mutex> &lock, int32_t scenario)
{
HILOG_INFO("scenario=%{public}d", scenario);
if (state_.currentMode != BlinkingMode::CONTINUOUS_BLINK) {
return BlinkResultCode::BLINK_SUCCESS;
}
auto it = state_.scenarioStates.find(scenario);
if (it == state_.scenarioStates.end()) {
return BlinkResultCode::BLINK_SUCCESS;
}
state_.scenarioStates.erase(it);
if (state_.scenarioStates.empty()) {
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
}
return BlinkResultCode::BLINK_SUCCESS;
}
void AccessibleBlinkingReminderManager::SetFlashReminderSwitch(bool state)
{
HILOG_INFO("state=%{public}d", state);
{
std::unique_lock<std::mutex> lock(mutex_);
state_.flashReminderSwitch = state;
}
if (state) {
SubscribeProximitySensor();
RegisterDisplayListener();
} else {
ForceStopAll();
UnsubscribeProximitySensor();
UnregisterDisplayListener();
}
}
void AccessibleBlinkingReminderManager::SetFlashReminderMode(int32_t mode)
{
HILOG_INFO("mode=%{public}d", mode);
std::unique_lock<std::mutex> lock(mutex_);
int32_t oldMode = state_.flashReminderMode;
if (state_.isRunning) {
if (mode == FlashReminderMode::NONE) {
ForceStopBlinkingInternal(lock, oldMode);
} else {
if (!IsFlashlightEnabled(mode)) {
ExpireFlashlightForAll(lock);
}
if (!IsDisplayEnabled(mode)) {
ExpireDisplayForAll(lock);
}
if (!HasAnyActiveComponent()) {
ForceStopBlinkingInternal(lock, oldMode);
}
}
}
state_.flashReminderMode = mode;
}
void AccessibleBlinkingReminderManager::SetFlashReminderFunctionEnabled(const std::string &enabled)
{
HILOG_INFO("enabled=%{public}s", enabled.c_str());
auto enabledScenarios = ParseEnabledScenarios(enabled);
std::unique_lock<std::mutex> lock(mutex_);
state_.flashReminderFunctionEnabled = enabled;
if (!state_.isRunning) {
return;
}
if (state_.currentMode == BlinkingMode::SINGLE_BLINK &&
state_.singleScenario != BlinkingScenario::TESTING &&
enabledScenarios.find(state_.singleScenario) == enabledScenarios.end()) {
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
} else if (state_.currentMode == BlinkingMode::CONTINUOUS_BLINK) {
std::vector<int32_t> toRemove;
for (const auto &[scenario, _] : state_.scenarioStates) {
if (scenario != BlinkingScenario::TESTING &&
enabledScenarios.find(scenario) == enabledScenarios.end()) {
toRemove.push_back(scenario);
}
}
for (int32_t scenario : toRemove) {
state_.scenarioStates.erase(scenario);
}
if (state_.scenarioStates.empty()) {
ForceStopBlinkingInternal(lock, state_.flashReminderMode);
}
}
}
void AccessibleBlinkingReminderManager::SetFlashReminderUnlock(bool state)
{
HILOG_INFO("state=%{public}d", state);
{
std::unique_lock<std::mutex> lock(mutex_);
state_.flashReminderUnlock = state;
}
#ifdef OHOS_BUILD_ENABLE_SCREENLOCK_MANAGER
if (!state && !IsScreenLocked()) {
std::unique_lock<std::mutex> lock(mutex_);
StopByUnlockDisabled(lock);
}
#else
(void)state;
#endif
}
BlinkResultCode AccessibleBlinkingReminderManager::StartBlinking(int32_t mode, int32_t scenario)
{
HILOG_INFO("mode=%{public}d, scenario=%{public}d", mode, scenario);
std::unique_lock<std::mutex> lock(mutex_);
int32_t flashReminderMode = FlashReminderMode::NONE;
bool displayBlocked = false;
BlinkResultCode ret = ValidateStartBlinking(scenario, flashReminderMode, displayBlocked);
if (ret != BlinkResultCode::BLINK_SUCCESS) {
return ret;
}
if (!state_.isRunning && IsFlashlightEnabled(flashReminderMode)) {
SaveOriginalFlashlightState();
}
JoinFinishedThread(lock);
if (mode == BlinkingMode::SINGLE_BLINK) {
return HandleStartSingleBlink(scenario, flashReminderMode, displayBlocked);
} else if (mode == BlinkingMode::CONTINUOUS_BLINK) {
return HandleStartContinuousBlink(lock, scenario, flashReminderMode, displayBlocked);
}
return BlinkResultCode::BLINK_SUCCESS;
}
BlinkResultCode AccessibleBlinkingReminderManager::StopBlinking(int32_t mode, int32_t scenario)
{
HILOG_INFO("mode=%{public}d, scenario=%{public}d", mode, scenario);
std::unique_lock<std::mutex> lock(mutex_);
JoinFinishedThread(lock);
if (!state_.isRunning) {
return BlinkResultCode::BLINK_SUCCESS;
}
if (state_.currentMode != mode) {
return BlinkResultCode::BLINK_SUCCESS;
}
if (mode == BlinkingMode::SINGLE_BLINK) {
return HandleStopSingleBlink(lock, scenario);
} else if (mode == BlinkingMode::CONTINUOUS_BLINK) {
return HandleStopContinuousBlink(lock, scenario);
}
return BlinkResultCode::BLINK_SUCCESS;
}
} // namespace Accessibility
} // namespace OHOS
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2026-2026 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 "accessible_blinking_reminder_manager.h"
#define API_EXPORT __attribute__((visibility("default")))
extern "C" {
API_EXPORT void SetFlashReminderSwitch(bool state)
{
OHOS::Singleton<OHOS::Accessibility::AccessibleBlinkingReminderManager>::GetInstance()
.SetFlashReminderSwitch(state);
}
API_EXPORT void SetFlashReminderMode(int32_t mode)
{
OHOS::Singleton<OHOS::Accessibility::AccessibleBlinkingReminderManager>::GetInstance()
.SetFlashReminderMode(mode);
}
API_EXPORT void SetFlashReminderFunctionEnabled(const char* enabled)
{
std::string enabledStr(enabled ? enabled : "");
OHOS::Singleton<OHOS::Accessibility::AccessibleBlinkingReminderManager>::GetInstance()
.SetFlashReminderFunctionEnabled(enabledStr);
}
API_EXPORT void SetFlashReminderUnlock(bool state)
{
OHOS::Singleton<OHOS::Accessibility::AccessibleBlinkingReminderManager>::GetInstance()
.SetFlashReminderUnlock(state);
}
API_EXPORT OHOS::Accessibility::BlinkResultCode StartBlinking(int32_t mode, int32_t scenario)
{
return OHOS::Singleton<OHOS::Accessibility::AccessibleBlinkingReminderManager>::GetInstance()
.StartBlinking(mode, scenario);
}
API_EXPORT OHOS::Accessibility::BlinkResultCode StopBlinking(int32_t mode, int32_t scenario)
{
return OHOS::Singleton<OHOS::Accessibility::AccessibleBlinkingReminderManager>::GetInstance()
.StopBlinking(mode, scenario);
}
}
+64 -4
View File
@@ -172,6 +172,18 @@ ohos_moduletest("aams_accessibility_touch_exploration_test") {
if (security_component_enable) {
external_deps += [ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
}
################################################################################
@@ -300,6 +312,7 @@ ohos_moduletest("aams_accessible_ability_channel_test") {
sources = [
"../aams/src/accessibility_account_data.cpp",
"../aams/src/accessibility_blinking_reminder_proxy.cpp",
"../aams/src/accessibility_common_event.cpp",
"../aams/src/accessibility_datashare_helper.cpp",
"../aams/src/accessibility_dumper.cpp",
@@ -414,6 +427,7 @@ ohos_moduletest("aams_server_test") {
sources = [
"../aams/src/accessibility_account_data.cpp",
"../aams/src/accessibility_blinking_reminder_proxy.cpp",
"../aams/src/accessibility_common_event.cpp",
"../aams/src/accessibility_datashare_helper.cpp",
"../aams/src/accessibility_dumper.cpp",
@@ -518,6 +532,22 @@ ohos_moduletest("aams_server_test") {
if (security_component_enable) {
external_deps += [ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
if (accessibility_feature_display_manager) {
external_deps += [ "display_manager:displaymgr" ]
}
}
################################################################################
@@ -526,6 +556,7 @@ ohos_moduletest("aams_accessibility_keyevent_filter_test") {
sources = [
"../aams/src/accessibility_account_data.cpp",
"../aams/src/accessibility_blinking_reminder_proxy.cpp",
"../aams/src/accessibility_common_event.cpp",
"../aams/src/accessibility_datashare_helper.cpp",
"../aams/src/accessibility_dumper.cpp",
@@ -630,6 +661,22 @@ ohos_moduletest("aams_accessibility_keyevent_filter_test") {
if (security_component_enable) {
external_deps += [ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
if (accessibility_feature_display_manager) {
external_deps += [ "display_manager:displaymgr" ]
}
}
################################################################################
@@ -638,6 +685,7 @@ ohos_moduletest("aams_common_event_registry_test") {
sources = [
"../aams/src/accessibility_account_data.cpp",
"../aams/src/accessibility_blinking_reminder_proxy.cpp",
"../aams/src/accessibility_common_event.cpp",
"../aams/src/accessibility_datashare_helper.cpp",
"../aams/src/accessibility_dumper.cpp",
@@ -744,13 +792,25 @@ ohos_moduletest("aams_common_event_registry_test") {
"window_manager:libwm_lite",
]
if (accessibility_feature_display_manager) {
external_deps += [ "display_manager:displaymgr" ]
}
if (security_component_enable) {
external_deps += [ "security_component_manager:libsecurity_component_sdk" ]
}
if (accessibility_camera_support) {
external_deps += [ "camera_framework:camera_framework" ]
}
if (accessibility_screenlock_manager) {
external_deps += [ "screenlock_mgr:screenlock_client" ]
}
if (accessibility_sensor_support) {
external_deps += [ "sensor:sensor_interface_native" ]
}
if (accessibility_feature_display_manager) {
external_deps += [ "display_manager:displaymgr" ]
}
}
################################################################################
@@ -641,5 +641,23 @@ ErrCode MockAccessibleAbilityManagerServiceStub::SetSeniorModeStateForApp(
{
return RET_OK;
}
ErrCode MockAccessibleAbilityManagerServiceStub::StartBlinking(int32_t mode, int32_t scenario,
int32_t &funcResult)
{
(void)mode;
(void)scenario;
funcResult = 0;
return RET_OK;
}
ErrCode MockAccessibleAbilityManagerServiceStub::StopBlinking(int32_t mode, int32_t scenario,
int32_t &funcResult)
{
(void)mode;
(void)scenario;
funcResult = 0;
return RET_OK;
}
} // namespace Accessibility
} // namespace OHOS
@@ -150,6 +150,8 @@ public:
ErrCode SetSeniorModeStateForApp(const bool state) override;
ErrCode GetSeniorModeStateForApp(const std::string &bundleName, int32_t appIndex, bool &state) override;
ErrCode SetSeniorModeStateForApp(const std::vector<AccessibilityBundleSeniorModeInfoParcel> &infos) override;
ErrCode StartBlinking(int32_t mode, int32_t scenario, int32_t &funcResult) override;
ErrCode StopBlinking(int32_t mode, int32_t scenario, int32_t &funcResult) override;
private:
std::shared_ptr<AppExecFwk::EventRunner> runner_;