1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_accessibility_config.h"
17 
18 #include <uv.h>
19 #include "hilog_wrapper.h"
20 #include "ipc_skeleton.h"
21 #include "accessibility_utils.h"
22 #include "tokenid_kit.h"
23 #include "accesstoken_kit.h"
24 
25 using namespace OHOS;
26 using namespace OHOS::Accessibility;
27 using namespace OHOS::AccessibilityNapi;
28 using namespace OHOS::AccessibilityConfig;
29 using namespace Security::AccessToken;
30 
31 namespace OHOS {
32 namespace Accessibility {
33 namespace {
34     constexpr int ROUND_STEP = 10;
35 }
36 
TmpOpenScope(napi_env env)37 napi_handle_scope TmpOpenScope(napi_env env)
38 {
39     napi_handle_scope scope = nullptr;
40     NAPI_CALL(env, napi_open_handle_scope(env, &scope));
41     return scope;
42 }
43 } // namespace Accessibility
44 } // namespace OHOS
45 
46 std::shared_ptr<NAccessibilityConfigObserverImpl> NAccessibilityConfig::configObservers_ =
47     std::make_shared<NAccessibilityConfigObserverImpl>();
48 std::shared_ptr<EnableAbilityListsObserverImpl> NAccessibilityConfig::enableAbilityListsObservers_ =
49     std::make_shared<EnableAbilityListsObserverImpl>();
50 
EnableAbilityError(size_t & argc,OHOS::Accessibility::RetError & errCode,napi_env env,napi_value * parameters,NAccessibilityConfigData * callbackInfo)51 void NAccessibilityConfig::EnableAbilityError(size_t& argc, OHOS::Accessibility::RetError& errCode,
52     napi_env env, napi_value* parameters, NAccessibilityConfigData* callbackInfo)
53 {
54     if (argc < ARGS_SIZE_THREE - 1) {
55         HILOG_ERROR("argc is invalid: %{public}zu", argc);
56         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
57     }
58 
59     if (errCode == OHOS::Accessibility::RET_OK) {
60         // parse name
61         std::string ability = "";
62         if (ParseString(env, ability, parameters[PARAM0])) {
63             HILOG_DEBUG("ability = %{private}s", ability.c_str());
64             callbackInfo->abilityName_ = ability;
65         } else {
66             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
67         }
68 
69         // parse capability
70         if (!ConvertJSToCapabilities(env, parameters[PARAM1], callbackInfo->capabilities_)) {
71             HILOG_ERROR("convert capabilities failed");
72             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
73         }
74     }
75 }
76 
DisableAbilityError(size_t & argc,OHOS::Accessibility::RetError & errCode,napi_env env,napi_value * parameters,NAccessibilityConfigData * callbackInfo)77 void NAccessibilityConfig::DisableAbilityError(size_t& argc, OHOS::Accessibility::RetError& errCode,
78     napi_env env, napi_value* parameters, NAccessibilityConfigData* callbackInfo)
79 {
80     if (argc < ARGS_SIZE_TWO - 1) {
81         HILOG_ERROR("argc is invalid: %{public}zu", argc);
82         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
83     }
84 
85     if (errCode == OHOS::Accessibility::RET_OK) {
86         // parse name
87         std::string ability = "";
88         if (ParseString(env, ability, parameters[PARAM0])) {
89             HILOG_DEBUG("ability = %{private}s", ability.c_str());
90             callbackInfo->abilityName_ = ability;
91         } else {
92             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
93         }
94     }
95 }
96 
EnableAbility(napi_env env,napi_callback_info info)97 napi_value NAccessibilityConfig::EnableAbility(napi_env env, napi_callback_info info)
98 {
99     HILOG_DEBUG();
100     NAccessibilityConfigData* callbackInfo = new(std::nothrow) NAccessibilityConfigData();
101     if (callbackInfo == nullptr) {
102         HILOG_ERROR("callbackInfo is nullptr");
103         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
104         napi_throw(env, err);
105         return nullptr;
106     }
107 
108     size_t argc = ARGS_SIZE_THREE;
109     napi_value parameters[ARGS_SIZE_THREE] = {0};
110     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
111 
112     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
113     EnableAbilityError(argc, errCode, env, parameters, callbackInfo);
114 
115     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
116         delete callbackInfo;
117         callbackInfo = nullptr;
118         napi_value err = CreateBusinessError(env, errCode);
119         HILOG_ERROR("invalid param");
120         napi_throw(env, err);
121         return nullptr;
122     }
123 
124     napi_value promise = nullptr;
125     if (argc > ARGS_SIZE_THREE - 1 && CheckJsFunction(env, parameters[PARAM2])) {
126         napi_create_reference(env, parameters[PARAM2], 1, &callbackInfo->callback_);
127         napi_get_undefined(env, &promise);
128     } else {
129         napi_create_promise(env, &callbackInfo->deferred_, &promise);
130     }
131 
132     napi_value resource = nullptr;
133     napi_create_string_utf8(env, "EnableAbility", NAPI_AUTO_LENGTH, &resource);
134 
135     napi_create_async_work(env, nullptr, resource,
136         // Execute async to call c++ function
137         [](napi_env env, void* data) {
138             NAccessibilityConfigData* callbackInfo = static_cast<NAccessibilityConfigData*>(data);
139             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
140             if (callbackInfo->capabilities_ != 0) {
141                 callbackInfo->ret_ = instance.EnableAbility(
142                     callbackInfo->abilityName_, callbackInfo->capabilities_);
143             }
144         }, NAccessibilityConfig::AsyncWorkComplete, reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
145     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
146     return promise;
147 }
148 
DisableAbility(napi_env env,napi_callback_info info)149 napi_value NAccessibilityConfig::DisableAbility(napi_env env, napi_callback_info info)
150 {
151     HILOG_DEBUG();
152     NAccessibilityConfigData* callbackInfo = new(std::nothrow) NAccessibilityConfigData();
153     if (callbackInfo == nullptr) {
154         HILOG_ERROR("DisableAbility callbackInfo is nullptr");
155         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
156         napi_throw(env, err);
157         return nullptr;
158     }
159 
160     size_t argc = ARGS_SIZE_TWO;
161     napi_value parameters[ARGS_SIZE_TWO] = {0};
162     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
163 
164     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
165     DisableAbilityError(argc, errCode, env, parameters, callbackInfo);
166 
167     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
168         delete callbackInfo;
169         callbackInfo = nullptr;
170         napi_value err = CreateBusinessError(env, errCode);
171         HILOG_ERROR("DisableAbility invalid param");
172         napi_throw(env, err);
173         return nullptr;
174     }
175 
176     napi_value promise = nullptr;
177     if (argc > ARGS_SIZE_TWO - 1 && CheckJsFunction(env, parameters[PARAM1])) {
178         napi_create_reference(env, parameters[PARAM1], 1, &callbackInfo->callback_);
179         napi_get_undefined(env, &promise);
180     } else {
181         napi_create_promise(env, &callbackInfo->deferred_, &promise);
182     }
183 
184     napi_value resource = nullptr;
185     napi_create_string_utf8(env, "DisableAbility", NAPI_AUTO_LENGTH, &resource);
186 
187     napi_create_async_work(env, nullptr, resource,
188         // Execute async to call c++ function
189         [](napi_env env, void* data) {
190             NAccessibilityConfigData* callbackInfo = static_cast<NAccessibilityConfigData*>(data);
191             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
192             if (callbackInfo) {
193                 callbackInfo->ret_ = instance.DisableAbility(callbackInfo->abilityName_);
194             }
195         }, NAccessibilityConfig::AsyncWorkComplete,
196         reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
197     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
198     return promise;
199 }
200 
CheckReadPermission(const std::string & permission)201 bool NAccessibilityConfig::CheckReadPermission(const std::string &permission)
202 {
203     HILOG_DEBUG();
204     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
205     int result = TypePermissionState::PERMISSION_GRANTED;
206     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
207     if (tokenType == TOKEN_INVALID) {
208         HILOG_WARN("AccessToken type invalid!");
209         return false;
210     } else {
211         result = AccessTokenKit::VerifyAccessToken(tokenId, permission);
212     }
213     if (result == TypePermissionState::PERMISSION_DENIED) {
214         HILOG_WARN("AccessTokenID denied!");
215         return false;
216     }
217     HILOG_DEBUG("tokenType %{private}d dAccessTokenID:%{private}u, permission:%{private}s matched!",
218         tokenType, tokenId, permission.c_str());
219     return true;
220 }
221 
IsAvailable(napi_env env,napi_callback_info info)222 bool NAccessibilityConfig::IsAvailable(napi_env env, napi_callback_info info)
223 {
224     HILOG_DEBUG();
225     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) {
226         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NOT_SYSTEM_APP);
227         napi_throw(env, err);
228         HILOG_ERROR("is not system app");
229         return false;
230     }
231 
232     if (!CheckReadPermission(OHOS_PERMISSION_READ_ACCESSIBILITY_CONFIG)) {
233         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NO_PERMISSION);
234         napi_throw(env, err);
235         HILOG_ERROR("have no read permission");
236         return false;
237     }
238 
239     return true;
240 }
241 
SubscribeState(napi_env env,napi_callback_info info)242 napi_value NAccessibilityConfig::SubscribeState(napi_env env, napi_callback_info info)
243 {
244     HILOG_DEBUG();
245     if (!IsAvailable(env, info)) {
246         return nullptr;
247     }
248     size_t argc = ARGS_SIZE_TWO;
249     napi_value args[ARGS_SIZE_TWO] = {0};
250     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
251     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
252     if (argc < ARGS_SIZE_TWO) {
253         HILOG_ERROR("argc is invalid: %{public}zu", argc);
254         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
255     }
256     std::string observerType = "";
257     if (errCode == OHOS::Accessibility::RET_OK) {
258         if (!ParseString(env, observerType, args[PARAM0])) {
259             HILOG_ERROR("observer type parse failed");
260             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
261         } else {
262             if (std::strcmp(observerType.c_str(), "enabledAccessibilityExtensionListChange") != 0 &&
263                 std::strcmp(observerType.c_str(), "installedAccessibilityListChange") != 0) {
264                 HILOG_ERROR("args[PARAM0] is wrong[%{public}s", observerType.c_str());
265                 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
266             }
267         }
268     }
269 
270     if (errCode == OHOS::Accessibility::RET_OK) {
271         napi_valuetype valueType = napi_null;
272         napi_typeof(env, args[PARAM1], &valueType);
273         if (valueType != napi_function) {
274             HILOG_ERROR("SubscribeState args[PARAM1] format is wrong");
275             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
276         }
277     }
278 
279     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
280         napi_value err = CreateBusinessError(env, errCode);
281         HILOG_ERROR("invalid param");
282         napi_throw(env, err);
283         return nullptr;
284     }
285     if (enableAbilityListsObservers_ == nullptr) {
286         HILOG_ERROR("enableAbilityListsObservers_ is null");
287         return nullptr;
288     }
289     if (std::strcmp(observerType.c_str(), "enabledAccessibilityExtensionListChange") == 0) {
290         enableAbilityListsObservers_->SubscribeObserver(env, args[PARAM1]);
291     }
292     if (std::strcmp(observerType.c_str(), "installedAccessibilityListChange") == 0) {
293         enableAbilityListsObservers_->SubscribeInstallObserver(env, args[PARAM1]);
294     }
295     return nullptr;
296 }
297 
UnsubscribeState(napi_env env,napi_callback_info info)298 napi_value NAccessibilityConfig::UnsubscribeState(napi_env env, napi_callback_info info)
299 {
300     HILOG_DEBUG();
301     if (!IsAvailable(env, info)) {
302         return nullptr;
303     }
304     size_t argc = ARGS_SIZE_TWO;
305     napi_value args[ARGS_SIZE_TWO] = {0};
306     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
307 
308     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
309     if (argc < ARGS_SIZE_TWO - 1) {
310         HILOG_ERROR("argc is invalid: %{public}zu", argc);
311         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
312     }
313     std::string observerType = "";
314     if (errCode == OHOS::Accessibility::RET_OK) {
315         if (!ParseString(env, observerType, args[PARAM0])) {
316             HILOG_ERROR("observer type parse failed");
317             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
318         } else {
319             if (std::strcmp(observerType.c_str(), "enabledAccessibilityExtensionListChange") != 0 &&
320                 std::strcmp(observerType.c_str(), "installedAccessibilityListChange") != 0) {
321                 HILOG_ERROR("args[PARAM0] is wrong[%{public}s", observerType.c_str());
322                 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
323             }
324         }
325     }
326 
327     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
328         napi_value err = CreateBusinessError(env, errCode);
329         HILOG_ERROR("UnsubscribeState invalid param");
330         napi_throw(env, err);
331         return nullptr;
332     }
333     if (enableAbilityListsObservers_ == nullptr) {
334         HILOG_ERROR("enableAbilityListsObservers_ is null");
335         return nullptr;
336     }
337     if (argc > ARGS_SIZE_TWO - 1 && CheckJsFunction(env, args[PARAM1])) {
338         if (std::strcmp(observerType.c_str(), "enabledAccessibilityExtensionListChange") == 0) {
339             enableAbilityListsObservers_->UnsubscribeObserver(env, args[PARAM1]);
340         } else {
341             enableAbilityListsObservers_->UnsubscribeInstallObserver(env, args[PARAM1]);
342         }
343     } else {
344         if (std::strcmp(observerType.c_str(), "enabledAccessibilityExtensionListChange") == 0) {
345             enableAbilityListsObservers_->UnsubscribeObservers();
346         } else {
347             enableAbilityListsObservers_->UnsubscribeInstallObservers();
348         }
349     }
350     return nullptr;
351 }
352 
AsyncWorkComplete(napi_env env,napi_status status,void * data)353 void NAccessibilityConfig::AsyncWorkComplete(napi_env env, napi_status status, void* data)
354 {
355     HILOG_DEBUG();
356     NAccessibilityConfigData* callbackInfo = static_cast<NAccessibilityConfigData*>(data);
357     if (callbackInfo == nullptr) {
358         HILOG_ERROR("callbackInfo is nullptr");
359         return;
360     }
361     napi_value result[ARGS_SIZE_ONE] = {0};
362     napi_value callback = 0;
363     napi_value returnVal = 0;
364     napi_value undefined = 0;
365     napi_get_undefined(env, &undefined);
366     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
367     if (callbackInfo->callback_) {
368         napi_get_reference_value(env, callbackInfo->callback_, &callback);
369         napi_call_function(env, undefined, callback, ARGS_SIZE_ONE, result, &returnVal);
370         napi_delete_reference(env, callbackInfo->callback_);
371         HILOG_DEBUG("complete function callback mode");
372     } else {
373         if (callbackInfo->ret_ == OHOS::Accessibility::RET_OK) {
374             napi_resolve_deferred(env, callbackInfo->deferred_, undefined);
375         } else {
376             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
377         }
378         HILOG_DEBUG("complete function promise mode");
379     }
380     napi_delete_async_work(env, callbackInfo->work_);
381     delete callbackInfo;
382     callbackInfo = nullptr;
383 }
384 
SetScreenTouchConfigExecute(NAccessibilityConfigData * callbackInfo)385 void NAccessibilityConfig::SetScreenTouchConfigExecute(NAccessibilityConfigData* callbackInfo)
386 {
387     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
388     if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONIFG_CLICK_RESPONSE_TIME) {
389         auto time = ConvertStringToClickResponseTimeTypes(callbackInfo->stringConfig_);
390         callbackInfo->ret_ = instance.SetClickResponseTime(time);
391     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_TIME) {
392         auto time = ConvertStringToIgnoreRepeatClickTimeTypes(callbackInfo->stringConfig_);
393         callbackInfo->ret_ = instance.SetIgnoreRepeatClickTime(time);
394     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_STATE) {
395         callbackInfo->ret_ = instance.SetIgnoreRepeatClickState(callbackInfo->boolConfig_);
396     }
397 }
398 
SetConfigExecute(napi_env env,void * data)399 void NAccessibilityConfig::SetConfigExecute(napi_env env, void* data)
400 {
401     NAccessibilityConfigData* callbackInfo = static_cast<NAccessibilityConfigData*>(data);
402     if (callbackInfo == nullptr) {
403         HILOG_ERROR("callbackInfo is nullptr");
404         return;
405     }
406 
407     HILOG_DEBUG("callbackInfo->id_ = %{public}d", callbackInfo->id_);
408     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
409 
410     if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT) {
411         callbackInfo->ret_ = instance.SetHighContrastTextState(callbackInfo->boolConfig_);
412     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_STATE) {
413         callbackInfo->ret_ = instance.SetDaltonizationState(callbackInfo->boolConfig_);
414     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_INVERT_COLOR) {
415         callbackInfo->ret_ = instance.SetInvertColorState(callbackInfo->boolConfig_);
416     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_ANIMATION_OFF) {
417         callbackInfo->ret_ = instance.SetAnimationOffState(callbackInfo->boolConfig_);
418     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SCREEN_MAGNIFICATION) {
419         callbackInfo->ret_ = instance.SetScreenMagnificationState(callbackInfo->boolConfig_);
420     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_MONO) {
421         callbackInfo->ret_ = instance.SetAudioMonoState(callbackInfo->boolConfig_);
422     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_KEY) {
423         callbackInfo->ret_ = instance.SetMouseKeyState(callbackInfo->boolConfig_);
424     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY) {
425         callbackInfo->ret_ = instance.SetShortKeyState(callbackInfo->boolConfig_);
426     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE) {
427         callbackInfo->ret_ = instance.SetCaptionsState(callbackInfo->boolConfig_);
428     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CONTENT_TIMEOUT) {
429         callbackInfo->ret_ = instance.SetContentTimeout(callbackInfo->uint32Config_);
430     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_AUTOCLICK) {
431         callbackInfo->ret_ = instance.SetMouseAutoClick(callbackInfo->int32Config_);
432     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_BALANCE) {
433         callbackInfo->ret_ = instance.SetAudioBalance(callbackInfo->floatConfig_);
434     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_BRIGHTNESS_DISCOUNT) {
435         callbackInfo->ret_ = instance.SetBrightnessDiscount(callbackInfo->floatConfig_);
436     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_TARGET) {
437         callbackInfo->ret_ = instance.SetShortkeyTarget(callbackInfo->stringConfig_);
438     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_MULTI_TARGET) {
439         callbackInfo->ret_ = instance.SetShortkeyMultiTarget(callbackInfo->stringVectorConfig_);
440     }  else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE) {
441         callbackInfo->ret_ = instance.SetCaptionsProperty(callbackInfo->captionProperty_);
442     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
443         auto filter = ConvertStringToDaltonizationTypes(callbackInfo->stringConfig_);
444         callbackInfo->ret_ = instance.SetDaltonizationColorFilter(filter);
445     }
446 
447     SetScreenTouchConfigExecute(callbackInfo);
448 }
449 
ConfigCompleteInfoById(napi_env env,NAccessibilityConfigData * callbackInfo,napi_value * result,size_t len)450 void NAccessibilityConfig::ConfigCompleteInfoById(napi_env env, NAccessibilityConfigData* callbackInfo,
451     napi_value* result, size_t len)
452 {
453     double value = 0.0;
454     switch (callbackInfo->id_) {
455         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT:
456         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_INVERT_COLOR:
457         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_ANIMATION_OFF:
458         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SCREEN_MAGNIFICATION:
459         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_MONO:
460         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_KEY:
461         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY:
462         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE:
463         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_STATE:
464         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_STATE:
465             napi_get_boolean(env, callbackInfo->boolConfig_, &result[PARAM1]);
466             break;
467         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CONTENT_TIMEOUT:
468         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_AUTOCLICK:
469             napi_create_int32(env, callbackInfo->int32Config_, &result[PARAM1]);
470             break;
471         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_BALANCE:
472             value = static_cast<double>(callbackInfo->floatConfig_);
473             value = round(value * ROUND_STEP) / ROUND_STEP;
474             napi_create_double(env, value, &result[PARAM1]);
475             break;
476         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_BRIGHTNESS_DISCOUNT:
477             napi_create_double(env, static_cast<double>(callbackInfo->floatConfig_), &result[PARAM1]);
478             break;
479         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER:
480         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_TARGET:
481         case OHOS::AccessibilityConfig::CONFIG_ID::CONIFG_CLICK_RESPONSE_TIME:
482         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_TIME:
483             napi_create_string_utf8(env, callbackInfo->stringConfig_.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
484             break;
485         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_MULTI_TARGET:
486             napi_create_array(env, &result[PARAM1]);
487             ConvertStringVecToJS(env, result[PARAM1], callbackInfo->stringVectorConfig_);
488             break;
489         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE:
490             napi_create_object(env, &result[PARAM1]);
491             ConvertCaptionPropertyToJS(env, result[PARAM1], callbackInfo->captionProperty_);
492             break;
493         default:
494             break;
495     }
496 }
497 
GetConfigComplete(napi_env env,napi_status status,void * data)498 void NAccessibilityConfig::GetConfigComplete(napi_env env, napi_status status, void* data)
499 {
500     HILOG_DEBUG();
501     NAccessibilityConfigData* callbackInfo = static_cast<NAccessibilityConfigData*>(data);
502     if (callbackInfo == nullptr) {
503         HILOG_ERROR("callbackInfo is nullptr");
504         return;
505     }
506     HILOG_DEBUG("callbackInfo->id_ = %{public}d", callbackInfo->id_);
507     napi_value result[ARGS_SIZE_TWO] = {0};
508     ConfigCompleteInfoById(env, callbackInfo, result, ARGS_SIZE_TWO);
509 
510     napi_value returnVal = 0;
511     napi_value callback = 0;
512     napi_value undefined = 0;
513     napi_get_undefined(env, &undefined);
514     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
515     if (callbackInfo->callback_) {
516         napi_get_reference_value(env, callbackInfo->callback_, &callback);
517         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
518         napi_delete_reference(env, callbackInfo->callback_);
519         HILOG_DEBUG("complete function callback mode");
520     } else {
521         if (callbackInfo->ret_ == OHOS::Accessibility::RET_OK) {
522             HILOG_DEBUG("GetConfigComplete callbackInfo->ret_ is RET_OK");
523             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
524         } else {
525             HILOG_DEBUG("GetConfigComplete callbackInfo->ret_ is not RET_OK");
526             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
527         }
528     }
529     napi_delete_async_work(env, callbackInfo->work_);
530     delete callbackInfo;
531     callbackInfo = nullptr;
532 }
533 
GetScreenTouchConfigExecute(NAccessibilityConfigData * callbackInfo)534 void NAccessibilityConfig::GetScreenTouchConfigExecute(NAccessibilityConfigData* callbackInfo)
535 {
536     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
537     if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONIFG_CLICK_RESPONSE_TIME) {
538         OHOS::AccessibilityConfig::CLICK_RESPONSE_TIME time;
539         callbackInfo->ret_ = instance.GetClickResponseTime(time);
540         callbackInfo->stringConfig_ = ConvertClickResponseTimeTypeToString(time);
541     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_TIME) {
542         OHOS::AccessibilityConfig::IGNORE_REPEAT_CLICK_TIME time;
543         callbackInfo->ret_ = instance.GetIgnoreRepeatClickTime(time);
544         callbackInfo->stringConfig_ = ConvertIgnoreRepeatClickTimeTypeToString(time);
545     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_STATE) {
546         callbackInfo->ret_ = instance.GetIgnoreRepeatClickState(callbackInfo->boolConfig_);
547     }
548 }
549 
GetConfigExecute(napi_env env,void * data)550 void NAccessibilityConfig::GetConfigExecute(napi_env env, void* data)
551 {
552     NAccessibilityConfigData* callbackInfo = static_cast<NAccessibilityConfigData*>(data);
553     if (callbackInfo == nullptr) {
554         HILOG_ERROR("callbackInfo is nullptr");
555         return;
556     }
557 
558     HILOG_DEBUG("callbackInfo->id_ = %{public}d", callbackInfo->id_);
559     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
560     if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT) {
561         callbackInfo->ret_ = instance.GetHighContrastTextState(callbackInfo->boolConfig_);
562     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_STATE) {
563         callbackInfo->ret_ = instance.GetDaltonizationState(callbackInfo->boolConfig_);
564     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_INVERT_COLOR) {
565         callbackInfo->ret_ = instance.GetInvertColorState(callbackInfo->boolConfig_);
566     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_ANIMATION_OFF) {
567         callbackInfo->ret_ = instance.GetAnimationOffState(callbackInfo->boolConfig_);
568     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SCREEN_MAGNIFICATION) {
569         callbackInfo->ret_ = instance.GetScreenMagnificationState(callbackInfo->boolConfig_);
570     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_MONO) {
571         callbackInfo->ret_ = instance.GetAudioMonoState(callbackInfo->boolConfig_);
572     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_KEY) {
573         callbackInfo->ret_ = instance.GetMouseKeyState(callbackInfo->boolConfig_);
574     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY) {
575         callbackInfo->ret_ = instance.GetShortKeyState(callbackInfo->boolConfig_);
576     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE) {
577         callbackInfo->ret_ = instance.GetCaptionsState(callbackInfo->boolConfig_);
578     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_AUTOCLICK) {
579         callbackInfo->ret_ = instance.GetMouseAutoClick(callbackInfo->int32Config_);
580     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_BALANCE) {
581         callbackInfo->ret_ = instance.GetAudioBalance(callbackInfo->floatConfig_);
582     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_BRIGHTNESS_DISCOUNT) {
583         callbackInfo->ret_ = instance.GetBrightnessDiscount(callbackInfo->floatConfig_);
584     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_TARGET) {
585         callbackInfo->ret_ = instance.GetShortkeyTarget(callbackInfo->stringConfig_);
586     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_MULTI_TARGET) {
587         callbackInfo->ret_ = instance.GetShortkeyMultiTarget(callbackInfo->stringVectorConfig_);
588     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE) {
589         callbackInfo->ret_ = instance.GetCaptionsProperty(callbackInfo->captionProperty_);
590     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CONTENT_TIMEOUT) {
591         uint32_t timeout = 0;
592         callbackInfo->ret_ = instance.GetContentTimeout(timeout);
593         callbackInfo->int32Config_ = static_cast<int32_t>(timeout);
594     } else if (callbackInfo->id_ == OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
595         OHOS::AccessibilityConfig::DALTONIZATION_TYPE type;
596         callbackInfo->ret_ = instance.GetDaltonizationColorFilter(type);
597         callbackInfo->stringConfig_ = ConvertDaltonizationTypeToString(type);
598     }
599 
600     GetScreenTouchConfigExecute(callbackInfo);
601 }
602 
GetCallbackInfo(napi_env env,napi_callback_info info,napi_value * parameters,size_t & argc,NAccessibilityConfigClass * & obj)603 NAccessibilityConfigData* NAccessibilityConfig::GetCallbackInfo(napi_env env, napi_callback_info info,
604     napi_value* parameters, size_t& argc, NAccessibilityConfigClass*& obj)
605 {
606     napi_value jsthis = nullptr;
607     napi_get_cb_info(env, info, &argc, parameters, &jsthis, nullptr);
608 
609     napi_status status = napi_unwrap(env, jsthis, reinterpret_cast<void**>(&obj));
610     if (status != napi_ok) {
611         HILOG_ERROR("Failed to get unwrap obj");
612         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
613         napi_throw(env, err);
614         return nullptr;
615     }
616     if (!obj) {
617         HILOG_ERROR("obj is nullptr");
618         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
619         napi_throw(env, err);
620         return nullptr;
621     }
622     HILOG_DEBUG("ConfigID = %{public}d", obj->GetConfigId());
623     NAccessibilityConfigData* callbackInfo = new(std::nothrow) NAccessibilityConfigData();
624     if (callbackInfo == nullptr) {
625         HILOG_ERROR("callbackInfo is nullptr");
626         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
627         napi_throw(env, err);
628         return nullptr;
629     }
630     return callbackInfo;
631 }
632 
ParseConnectTimeoutData(napi_env env,NAccessibilityConfigData * callbackInfo,napi_value * parameters)633 bool NAccessibilityConfig::ParseConnectTimeoutData(napi_env env, NAccessibilityConfigData* callbackInfo,
634     napi_value* parameters)
635 {
636     int32_t timeout = 0;
637     bool ret = ParseInt32(env, timeout, parameters[PARAM0]);
638     callbackInfo->uint32Config_ = static_cast<uint32_t>(timeout);
639     return ret;
640 }
641 
ParseMouseAutoClickData(napi_env env,NAccessibilityConfigData * callbackInfo,napi_value * parameters)642 bool NAccessibilityConfig::ParseMouseAutoClickData(napi_env env, NAccessibilityConfigData* callbackInfo,
643     napi_value* parameters)
644 {
645     int32_t time = 0;
646     bool ret = ParseInt32(env, time, parameters[PARAM0]);
647     callbackInfo->int32Config_ = time;
648     return ret;
649 }
650 
SetConfigParseBoolData(napi_env env,NAccessibilityConfigData * callbackInfo,napi_value * parameters)651 bool NAccessibilityConfig::SetConfigParseBoolData(napi_env env, NAccessibilityConfigData* callbackInfo,
652     napi_value* parameters)
653 {
654     bool state = false;
655     bool ret = ParseBool(env, state, parameters[PARAM0]);
656     callbackInfo->boolConfig_ = state;
657     return ret;
658 }
659 
SetConfigParseData(napi_env env,NAccessibilityConfigClass * obj,NAccessibilityConfigData * callbackInfo,napi_value * parameters,size_t argc)660 bool NAccessibilityConfig::SetConfigParseData(napi_env env, NAccessibilityConfigClass* obj,
661     NAccessibilityConfigData* callbackInfo, napi_value* parameters, size_t argc)
662 {
663     bool ret = false;
664     switch (obj->GetConfigId()) {
665         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT:
666         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_INVERT_COLOR:
667         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_ANIMATION_OFF:
668         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SCREEN_MAGNIFICATION:
669         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_MONO:
670         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_KEY:
671         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY:
672         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STATE:
673         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_STATE:
674         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_STATE:
675             return SetConfigParseBoolData(env, callbackInfo, parameters);
676         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CONTENT_TIMEOUT:
677             return ParseConnectTimeoutData(env, callbackInfo, parameters);
678         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_MOUSE_AUTOCLICK:
679             return ParseMouseAutoClickData(env, callbackInfo, parameters);
680         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_AUDIO_BALANCE:
681         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_BRIGHTNESS_DISCOUNT:
682             {
683                 double doubleTemp = 0;
684                 ret = ParseDouble(env, doubleTemp, parameters[PARAM0]);
685                 callbackInfo->floatConfig_ = static_cast<float>(doubleTemp);
686             }
687             break;
688         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER:
689         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_TARGET:
690         case OHOS::AccessibilityConfig::CONFIG_ID::CONIFG_CLICK_RESPONSE_TIME:
691         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_IGNORE_REPEAT_CLICK_TIME:
692             {
693                 std::string target = "";
694                 ret = ParseString(env, target, parameters[PARAM0]) && target.length() > 0;
695                 callbackInfo->stringConfig_ = target;
696             }
697             break;
698         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_SHORT_KEY_MULTI_TARGET:
699             {
700                 std::vector<std::string> stringArray;
701                 ConvertStringArrayJSToNAPICommon(env, parameters[PARAM0], stringArray);
702                 callbackInfo->stringVectorConfig_ = stringArray;
703                 return true;
704             }
705         case OHOS::AccessibilityConfig::CONFIG_ID::CONFIG_CAPTION_STYLE:
706             return ConvertObjToCaptionProperty(env, parameters[PARAM0], &callbackInfo->captionProperty_);
707         default:
708             break;
709     }
710     return ret;
711 }
712 
SetConfig(napi_env env,napi_callback_info info)713 napi_value NAccessibilityConfig::SetConfig(napi_env env, napi_callback_info info)
714 {
715     HILOG_DEBUG();
716     NAccessibilityConfigClass* obj;
717     size_t argc = ARGS_SIZE_TWO;
718     napi_value parameters[ARGS_SIZE_TWO] = {0};
719     NAccessibilityConfigData* callbackInfo = GetCallbackInfo(env, info, parameters, argc, obj);
720     if (callbackInfo == nullptr) {
721         return nullptr;
722     }
723 
724     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
725     if (argc < ARGS_SIZE_TWO - 1) {
726         HILOG_ERROR("argc is invalid: %{public}zu", argc);
727         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
728     }
729 
730     if (errCode == OHOS::Accessibility::RET_OK) {
731         if (!SetConfigParseData(env, obj, callbackInfo, parameters, argc)) {
732             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
733         }
734     }
735 
736     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
737         delete callbackInfo;
738         callbackInfo = nullptr;
739         napi_value err = CreateBusinessError(env, errCode);
740         HILOG_ERROR("SetConfig invalid param");
741         napi_throw(env, err);
742         return nullptr;
743     }
744     callbackInfo->id_ = obj->GetConfigId();
745 
746     // parse function if it needs
747     napi_value promise = nullptr;
748     if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, parameters[PARAM1])) {
749         napi_create_reference(env, parameters[PARAM1], 1, &callbackInfo->callback_);
750         napi_get_undefined(env, &promise);
751     } else {
752         napi_create_promise(env, &callbackInfo->deferred_, &promise);
753     }
754     napi_value resource = nullptr;
755     napi_create_string_utf8(env, "SetConfig", NAPI_AUTO_LENGTH, &resource);
756 
757     napi_create_async_work(env, nullptr, resource,
758         // Execute async to call c++ function
759         NAccessibilityConfig::SetConfigExecute,
760         // Execute the complete function
761         NAccessibilityConfig::AsyncWorkComplete,
762         reinterpret_cast<void*>(callbackInfo),
763         &callbackInfo->work_);
764     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
765     return promise;
766 }
767 
GetConfig(napi_env env,napi_callback_info info)768 napi_value NAccessibilityConfig::GetConfig(napi_env env, napi_callback_info info)
769 {
770     HILOG_DEBUG();
771     size_t argc = ARGS_SIZE_ONE;
772     napi_value parameters[ARGS_SIZE_ONE] = {0};
773     napi_value jsthis = nullptr;
774     napi_get_cb_info(env, info, &argc, parameters, &jsthis, nullptr);
775 
776     NAccessibilityConfigClass* obj;
777     napi_status status = napi_unwrap(env, jsthis, reinterpret_cast<void**>(&obj));
778     if (status != napi_ok) {
779         HILOG_ERROR("Failed to get unwrap obj");
780         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
781         napi_throw(env, err);
782         return nullptr;
783     }
784     if (!obj) {
785         HILOG_ERROR("obj is nullptr");
786         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
787         napi_throw(env, err);
788         return nullptr;
789     }
790     HILOG_DEBUG("ConfigID = %{public}d", obj->GetConfigId());
791 
792     NAccessibilityConfigData* callbackInfo = new(std::nothrow) NAccessibilityConfigData();
793     if (callbackInfo == nullptr) {
794         HILOG_ERROR("callbackInfo is nullptr");
795         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
796         napi_throw(env, err);
797         return nullptr;
798     }
799     callbackInfo->id_ = obj->GetConfigId();
800 
801     // parse function if it needs
802     napi_value promise = nullptr;
803     if (argc >= ARGS_SIZE_ONE && CheckJsFunction(env, parameters[PARAM0])) {
804         napi_create_reference(env, parameters[PARAM0], 1, &callbackInfo->callback_);
805         napi_get_undefined(env, &promise);
806     } else {
807         napi_create_promise(env, &callbackInfo->deferred_, &promise);
808     }
809     napi_value resource = nullptr;
810     napi_create_string_utf8(env, "GetConfig", NAPI_AUTO_LENGTH, &resource);
811 
812     napi_create_async_work(env, nullptr, resource,
813         // Execute async to call c++ function
814         NAccessibilityConfig::GetConfigExecute,
815         // Execute the complete function
816         NAccessibilityConfig::GetConfigComplete,
817         reinterpret_cast<void*>(callbackInfo),
818         &callbackInfo->work_);
819     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
820     return promise;
821 }
822 
SubscribeConfigObserver(napi_env env,napi_callback_info info)823 napi_value NAccessibilityConfig::SubscribeConfigObserver(napi_env env, napi_callback_info info)
824 {
825     HILOG_DEBUG();
826     if (!IsAvailable(env, info)) {
827         return nullptr;
828     }
829     size_t argc = ARGS_SIZE_ONE;
830     napi_value parameters[ARGS_SIZE_ONE] = {0};
831     napi_value jsthis = nullptr;
832     napi_get_cb_info(env, info, &argc, parameters, &jsthis, nullptr);
833     NAccessibilityConfigClass* obj;
834     napi_status status = napi_unwrap(env, jsthis, reinterpret_cast<void**>(&obj));
835     if (status != napi_ok) {
836         HILOG_ERROR("Failed to get unwrap obj");
837         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
838         napi_throw(env, err);
839         return nullptr;
840     }
841     if (!obj) {
842         HILOG_ERROR("obj is nullptr");
843         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
844         napi_throw(env, err);
845         return nullptr;
846     }
847 
848     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
849     if (argc < ARGS_SIZE_ONE) {
850         HILOG_ERROR("argc is invalid: %{public}zu", argc);
851         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
852     }
853 
854     if (errCode == OHOS::Accessibility::RET_OK) {
855         napi_valuetype valueType = napi_null;
856         napi_typeof(env, parameters[PARAM0], &valueType);
857         if (valueType != napi_function) {
858             HILOG_ERROR("parameters[PARAM1] format is wrong");
859             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
860         }
861     }
862 
863     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
864         napi_value err = CreateBusinessError(env, errCode);
865         HILOG_ERROR("invalid param");
866         napi_throw(env, err);
867         return nullptr;
868     }
869 
870     configObservers_->SubscribeObserver(env, obj->GetConfigId(), parameters[PARAM0]);
871     return nullptr;
872 }
873 
UnSubscribeConfigObserver(napi_env env,napi_callback_info info)874 napi_value NAccessibilityConfig::UnSubscribeConfigObserver(napi_env env, napi_callback_info info)
875 {
876     HILOG_DEBUG();
877     if (!IsAvailable(env, info)) {
878         return nullptr;
879     }
880     napi_value jsthis = nullptr;
881     size_t argc = ARGS_SIZE_ONE;
882     napi_value parameters[ARGS_SIZE_ONE] = {0};
883     napi_get_cb_info(env, info, &argc, parameters, &jsthis, nullptr);
884     NAccessibilityConfigClass* obj;
885     napi_status status = napi_unwrap(env, jsthis, reinterpret_cast<void**>(&obj));
886     if (status != napi_ok) {
887         HILOG_ERROR("Failed to get unwrap obj");
888         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
889         napi_throw(env, err);
890         return nullptr;
891     }
892     if (!obj) {
893         HILOG_ERROR("obj is nullptr");
894         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
895         napi_throw(env, err);
896         return nullptr;
897     }
898     if (argc >= ARGS_SIZE_ONE && CheckJsFunction(env, parameters[PARAM0])) {
899         configObservers_->UnsubscribeObserver(env, obj->GetConfigId(), parameters[PARAM0]);
900     } else {
901         configObservers_->UnsubscribeObservers(obj->GetConfigId());
902     }
903 
904     return nullptr;
905 }
906 
OnEnableAbilityListsStateChanged()907 void EnableAbilityListsObserver::OnEnableAbilityListsStateChanged()
908 {
909     HILOG_DEBUG();
910 
911     AccessibilityCallbackInfo *callbackInfo = new(std::nothrow) AccessibilityCallbackInfo();
912     if (callbackInfo == nullptr) {
913         HILOG_ERROR("callbackInfo is nullptr");
914         return;
915     }
916 
917     uv_work_t *work = new(std::nothrow) uv_work_t;
918     if (!work) {
919         HILOG_ERROR("Failed to create work.");
920         delete callbackInfo;
921         callbackInfo = nullptr;
922         return;
923     }
924 
925     callbackInfo->env_ = env_;
926     callbackInfo->ref_ = callback_;
927     work->data = static_cast<void*>(callbackInfo);
928 
929     int ret = OnEnableAbilityListsStateChangedWork(work);
930     if (ret != 0) {
931         HILOG_ERROR("Failed to execute OnEnableAbilityListsStateChanged work queue");
932         delete callbackInfo;
933         callbackInfo = nullptr;
934         delete work;
935         work = nullptr;
936     }
937 }
938 
OnEnableAbilityListsStateChangedWork(uv_work_t * work)939 int EnableAbilityListsObserver::OnEnableAbilityListsStateChangedWork(uv_work_t *work)
940 {
941     uv_loop_s *loop = nullptr;
942     napi_get_uv_event_loop(env_, &loop);
943     if (loop == nullptr || work == nullptr) {
944         HILOG_ERROR("loop or work is nullptr.");
945         return RET_ERR_FAILED;
946     }
947     int ret = uv_queue_work_with_qos(
948         loop,
949         work,
950         [](uv_work_t *work) {},
951         [](uv_work_t *work, int status) {
952             AccessibilityCallbackInfo *callbackInfo = static_cast<AccessibilityCallbackInfo*>(work->data);
953             napi_env env = callbackInfo->env_;
954             auto closeScope = [env](napi_handle_scope scope) {
955                 napi_close_handle_scope(env, scope);
956             };
957             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
958                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
959             napi_value handler = nullptr;
960             napi_value callResult = nullptr;
961             napi_value jsEvent = nullptr;
962             napi_value undefined = nullptr;
963             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
964             napi_get_undefined(callbackInfo->env_, &undefined);
965             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
966             delete callbackInfo;
967             callbackInfo = nullptr;
968             delete work;
969             work = nullptr;
970         },
971         uv_qos_default);
972     return ret;
973 }
974 
SubscribeToFramework()975 void EnableAbilityListsObserverImpl::SubscribeToFramework()
976 {
977     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
978     instance.SubscribeEnableAbilityListsObserver(shared_from_this());
979 }
980 
OnEnableAbilityListsStateChanged()981 void EnableAbilityListsObserverImpl::OnEnableAbilityListsStateChanged()
982 {
983     HILOG_DEBUG();
984     std::lock_guard<ffrt::mutex> lock(mutex_);
985     for (auto &observer : enableAbilityListsObservers_) {
986         observer->OnEnableAbilityListsStateChanged();
987     }
988 }
989 
OnInstallAbilityListsStateChanged()990 void EnableAbilityListsObserverImpl::OnInstallAbilityListsStateChanged()
991 {
992     HILOG_DEBUG();
993     std::lock_guard<ffrt::mutex> lock(mutex_);
994     for (auto &observer : installAbilityListsObservers_) {
995         if (observer) {
996             observer->OnEnableAbilityListsStateChanged();
997         } else {
998             HILOG_ERROR("observer is null");
999         }
1000     }
1001 }
1002 
SubscribeObserver(napi_env env,napi_value observer)1003 void EnableAbilityListsObserverImpl::SubscribeObserver(napi_env env, napi_value observer)
1004 {
1005     HILOG_DEBUG();
1006     std::lock_guard<ffrt::mutex> lock(mutex_);
1007     for (auto iter = enableAbilityListsObservers_.begin(); iter != enableAbilityListsObservers_.end();) {
1008         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) {
1009             HILOG_DEBUG("Observer exist");
1010             return;
1011         } else {
1012             iter++;
1013         }
1014     }
1015 
1016     napi_ref callback = nullptr;
1017     napi_create_reference(env, observer, 1, &callback);
1018     std::shared_ptr<EnableAbilityListsObserver> observerPtr =
1019         std::make_shared<EnableAbilityListsObserver>(env, callback);
1020 
1021     enableAbilityListsObservers_.emplace_back(observerPtr);
1022     HILOG_DEBUG("observer size%{public}zu", enableAbilityListsObservers_.size());
1023 }
1024 
SubscribeInstallObserver(napi_env env,napi_value observer)1025 void EnableAbilityListsObserverImpl::SubscribeInstallObserver(napi_env env, napi_value observer)
1026 {
1027     HILOG_DEBUG();
1028     std::lock_guard<ffrt::mutex> lock(mutex_);
1029     for (auto iter = installAbilityListsObservers_.begin(); iter != installAbilityListsObservers_.end(); iter++) {
1030         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) {
1031             HILOG_DEBUG("Observer exist");
1032             return;
1033         }
1034     }
1035 
1036     napi_ref callback = nullptr;
1037     napi_create_reference(env, observer, 1, &callback);
1038     std::shared_ptr<EnableAbilityListsObserver> observerPtr =
1039         std::make_shared<EnableAbilityListsObserver>(env, callback);
1040 
1041     installAbilityListsObservers_.emplace_back(observerPtr);
1042     HILOG_DEBUG("observer size%{public}zu", installAbilityListsObservers_.size());
1043 }
1044 
UnsubscribeObserver(napi_env env,napi_value observer)1045 void EnableAbilityListsObserverImpl::UnsubscribeObserver(napi_env env, napi_value observer)
1046 {
1047     HILOG_DEBUG();
1048     std::lock_guard<ffrt::mutex> lock(mutex_);
1049     for (auto iter = enableAbilityListsObservers_.begin(); iter != enableAbilityListsObservers_.end();) {
1050         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) {
1051             enableAbilityListsObservers_.erase(iter);
1052             return;
1053         } else {
1054             iter++;
1055         }
1056     }
1057 }
1058 
UnsubscribeObservers()1059 void EnableAbilityListsObserverImpl::UnsubscribeObservers()
1060 {
1061     HILOG_DEBUG();
1062     std::lock_guard<ffrt::mutex> lock(mutex_);
1063     enableAbilityListsObservers_.clear();
1064 }
1065 
UnsubscribeInstallObserver(napi_env env,napi_value observer)1066 void EnableAbilityListsObserverImpl::UnsubscribeInstallObserver(napi_env env, napi_value observer)
1067 {
1068     HILOG_DEBUG();
1069     std::lock_guard<ffrt::mutex> lock(mutex_);
1070     for (auto iter = installAbilityListsObservers_.begin(); iter != installAbilityListsObservers_.end(); iter++) {
1071         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) {
1072             installAbilityListsObservers_.erase(iter);
1073             return;
1074         }
1075     }
1076 }
1077 
UnsubscribeInstallObservers()1078 void EnableAbilityListsObserverImpl::UnsubscribeInstallObservers()
1079 {
1080     HILOG_DEBUG();
1081     std::lock_guard<ffrt::mutex> lock(mutex_);
1082     installAbilityListsObservers_.clear();
1083 }
1084