1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "accessibility_utils.h"
17 #include "accessibility_config_observer.h"
18 
19 #include <uv.h>
20 
21 #include "hilog_wrapper.h"
22 #include "napi/native_api.h"
23 #include "napi/native_node_api.h"
24 
25 using namespace OHOS;
26 using namespace OHOS::Accessibility;
27 using namespace OHOS::AccessibilityNapi;
28 using namespace OHOS::AccessibilityConfig;
29 
30 namespace OHOS {
31 namespace Accessibility {
32 namespace {
33     constexpr int ROUND_STEP = 10;
34 }
35 
TmpOpenScope(napi_env env)36 napi_handle_scope TmpOpenScope(napi_env env)
37 {
38     napi_handle_scope scope = nullptr;
39     NAPI_CALL(env, napi_open_handle_scope(env, &scope));
40     return scope;
41 }
42 } // namespace Accessibility
43 } // namespace OHOS
44 
OnConfigChangedExtra(const ConfigValue & value)45 void NAccessibilityConfigObserver::OnConfigChangedExtra(const ConfigValue &value)
46 {
47     HILOG_INFO("id = [%{public}d]", static_cast<int32_t>(configId_));
48     if (configId_ == CONFIG_CONTENT_TIMEOUT) {
49         NotifyIntChanged2JS(static_cast<int32_t>(value.contentTimeout));
50     } else if (configId_ == CONFIG_BRIGHTNESS_DISCOUNT) {
51         NotifyDoubleChanged2JS(static_cast<double>(value.brightnessDiscount));
52     } else if (configId_ == CONFIG_AUDIO_BALANCE) {
53         float audioBalance = value.audioBalance;
54         double value = static_cast<double>(audioBalance);
55         value = round(value * ROUND_STEP) / ROUND_STEP;
56         NotifyDoubleChanged2JS(value);
57     } else if (configId_ ==  CONFIG_HIGH_CONTRAST_TEXT) {
58         NotifyStateChanged2JS(value.highContrastText);
59     } else if (configId_ ==  CONFIG_DALTONIZATION_STATE) {
60         NotifyStateChanged2JS(value.daltonizationState);
61     } else if (configId_ == CONFIG_INVERT_COLOR) {
62         NotifyStateChanged2JS(value.invertColor);
63     } else if (configId_ == CONFIG_ANIMATION_OFF) {
64         NotifyStateChanged2JS(value.animationOff);
65     } else if (configId_ == CONFIG_AUDIO_MONO) {
66         NotifyStateChanged2JS(value.audioMono);
67     } else if (configId_ == CONIFG_CLICK_RESPONSE_TIME) {
68         NotifyStringChanged2JS(ConvertClickResponseTimeTypeToString(value.clickResponseTime));
69     } else if (configId_ == CONFIG_IGNORE_REPEAT_CLICK_TIME) {
70         NotifyStringChanged2JS(ConvertIgnoreRepeatClickTimeTypeToString(value.ignoreRepeatClickTime));
71     } else if (configId_ == CONFIG_IGNORE_REPEAT_CLICK_STATE) {
72         NotifyStateChanged2JS(value.ignoreRepeatClickState);
73     }
74 }
75 
OnConfigChanged(const ConfigValue & value)76 void NAccessibilityConfigObserver::OnConfigChanged(const ConfigValue &value)
77 {
78     HILOG_INFO("id = [%{public}d]", static_cast<int32_t>(configId_));
79     if (configId_ == CONFIG_CAPTION_STATE) {
80         NotifyStateChanged2JS(value.captionState);
81     } else if (configId_ == CONFIG_CAPTION_STYLE) {
82         NotifyPropertyChanged2JS(value.captionStyle);
83     } else if (configId_ == CONFIG_SCREEN_MAGNIFICATION) {
84         NotifyStateChanged2JS(value.screenMagnifier);
85     } else if (configId_ == CONFIG_MOUSE_KEY) {
86         NotifyStateChanged2JS(value.mouseKey);
87     } else if (configId_ == CONFIG_SHORT_KEY) {
88         NotifyStateChanged2JS(value.shortkey);
89     } else if (configId_ == CONFIG_SHORT_KEY_TARGET) {
90         NotifyStringChanged2JS(value.shortkey_target);
91     } else if (configId_ == CONFIG_SHORT_KEY_MULTI_TARGET) {
92         NotifyStringVectorChanged2JS(value.shortkeyMultiTarget);
93     } else if (configId_ == CONFIG_MOUSE_AUTOCLICK) {
94         NotifyIntChanged2JS(value.mouseAutoClick);
95     } else if (configId_ == CONFIG_DALTONIZATION_COLOR_FILTER) {
96         OnDaltonizationColorFilterConfigChanged();
97     } else {
98         OnConfigChangedExtra(value);
99     }
100 }
101 
OnDaltonizationColorFilterConfigChanged()102 void NAccessibilityConfigObserver::OnDaltonizationColorFilterConfigChanged()
103 {
104     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
105     DALTONIZATION_TYPE type = Normal;
106     RetError ret = instance.GetDaltonizationColorFilter(type);
107     if (ret == RET_OK) {
108         NotifyStringChanged2JS(ConvertDaltonizationTypeToString(type));
109     } else {
110         NotifyStringChanged2JS(ConvertDaltonizationTypeToString(type));
111         HILOG_ERROR("get DaltonizationColorFilter failed: %{public}d", ret);
112     }
113 }
114 
NotifyStateChanged(uv_work_t * work)115 int NAccessibilityConfigObserver::NotifyStateChanged(uv_work_t *work)
116 {
117     uv_loop_s *loop = nullptr;
118     napi_get_uv_event_loop(env_, &loop);
119     if (loop == nullptr || work == nullptr) {
120         HILOG_ERROR("loop or work is nullptr.");
121         return RET_ERR_FAILED;
122     }
123     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
124         [](uv_work_t *work, int status) {
125             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
126             napi_env env = callbackInfo->env_;
127             auto closeScope = [env](napi_handle_scope scope) {
128                 napi_close_handle_scope(env, scope);
129             };
130             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
131                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
132             napi_value jsEvent = nullptr;
133             napi_create_object(callbackInfo->env_, &jsEvent);
134             if (jsEvent == nullptr) {
135                 HILOG_ERROR("napi_create_object fail.");
136                 return;
137             }
138             napi_get_boolean(callbackInfo->env_, callbackInfo->state_, &jsEvent);
139 
140             napi_value handler = nullptr;
141             napi_value callResult = nullptr;
142             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
143             napi_value undefined = nullptr;
144             napi_get_undefined(callbackInfo->env_, &undefined);
145             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
146             int32_t result;
147             napi_get_value_int32(callbackInfo->env_, callResult, &result);
148             HILOG_INFO("NotifyStateChangedJS napi_call_function result[%{public}d]", result);
149             delete callbackInfo;
150             callbackInfo = nullptr;
151             delete work;
152             work = nullptr;
153         },
154         uv_qos_default);
155     return ret;
156 }
157 
NotifyPropertyChanged(uv_work_t * work)158 int NAccessibilityConfigObserver::NotifyPropertyChanged(uv_work_t *work)
159 {
160     uv_loop_s *loop = nullptr;
161     napi_get_uv_event_loop(env_, &loop);
162     if (loop == nullptr || work == nullptr) {
163         HILOG_ERROR("loop or work is nullptr.");
164         return RET_ERR_FAILED;
165     }
166     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
167         [](uv_work_t *work, int status) {
168             CaptionCallbackInfo *callbackInfo = static_cast<CaptionCallbackInfo*>(work->data);
169             napi_env env = callbackInfo->env_;
170             auto closeScope = [env](napi_handle_scope scope) {
171                 napi_close_handle_scope(env, scope);
172             };
173             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
174                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
175             napi_value jsEvent = nullptr;
176             napi_create_object(callbackInfo->env_, &jsEvent);
177             if (jsEvent == nullptr) {
178                 HILOG_ERROR("napi_create_object fail.");
179                 return;
180             }
181             ConvertCaptionPropertyToJS(callbackInfo->env_, jsEvent, callbackInfo->caption_);
182 
183             napi_value handler = nullptr;
184             napi_value callResult = nullptr;
185             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
186             napi_value undefined = nullptr;
187             napi_get_undefined(callbackInfo->env_, &undefined);
188             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
189             int32_t result;
190             napi_get_value_int32(callbackInfo->env_, callResult, &result);
191             HILOG_INFO("NotifyPropertyChangedJS napi_call_function result[%{public}d]", result);
192             delete callbackInfo;
193             callbackInfo = nullptr;
194             delete work;
195             work = nullptr;
196         },
197         uv_qos_default);
198     return ret;
199 }
200 
NotifyStringChanged(uv_work_t * work)201 int NAccessibilityConfigObserver::NotifyStringChanged(uv_work_t *work)
202 {
203     uv_loop_s *loop = nullptr;
204     napi_get_uv_event_loop(env_, &loop);
205     if (loop == nullptr || work == nullptr) {
206         HILOG_ERROR("loop or work is nullptr.");
207         return RET_ERR_FAILED;
208     }
209     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
210         [](uv_work_t *work, int status) {
211             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
212             napi_env env = callbackInfo->env_;
213             auto closeScope = [env](napi_handle_scope scope) {
214                 napi_close_handle_scope(env, scope);
215             };
216             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
217                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
218             napi_value jsEvent = nullptr;
219             napi_create_string_utf8(callbackInfo->env_, callbackInfo->stringValue_.c_str(),
220                 callbackInfo->stringValue_.length(), &jsEvent);
221             napi_value handler = nullptr;
222             napi_value callResult = nullptr;
223             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
224             napi_value undefined = nullptr;
225             napi_get_undefined(callbackInfo->env_, &undefined);
226             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
227             size_t result;
228             const uint32_t BUF_SIZE = 1024;
229             char buf[BUF_SIZE] = {0};
230             napi_get_value_string_utf8(callbackInfo->env_, callResult, buf, BUF_SIZE, &result);
231             HILOG_INFO("NotifyStringChanged2JSInner napi_call_function result[%{public}zu]", result);
232             delete callbackInfo;
233             callbackInfo = nullptr;
234             delete work;
235             work = nullptr;
236         },
237         uv_qos_default);
238     return ret;
239 }
240 
NotifyStringVectorChanged(uv_work_t * work)241 int NAccessibilityConfigObserver::NotifyStringVectorChanged(uv_work_t *work)
242 {
243     uv_loop_s *loop = nullptr;
244     napi_get_uv_event_loop(env_, &loop);
245     if (loop == nullptr || work == nullptr) {
246         HILOG_ERROR("loop or work is nullptr.");
247         return RET_ERR_FAILED;
248     }
249     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
250         [](uv_work_t *work, int status) {
251             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
252             napi_env env = callbackInfo->env_;
253             auto closeScope = [env](napi_handle_scope scope) {
254                 napi_close_handle_scope(env, scope);
255             };
256             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
257                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
258             napi_value jsEvent = nullptr;
259             napi_create_array(callbackInfo->env_, &jsEvent);
260             ConvertStringVecToJS(callbackInfo->env_, jsEvent, callbackInfo->stringVector_);
261 
262             napi_value handler = nullptr;
263             napi_value callResult = nullptr;
264             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
265             napi_value undefined = nullptr;
266             napi_get_undefined(callbackInfo->env_, &undefined);
267             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
268             size_t result;
269             const uint32_t BUF_SIZE = 1024;
270             char buf[BUF_SIZE] = {0};
271             napi_get_value_string_utf8(callbackInfo->env_, callResult, buf, BUF_SIZE, &result);
272             HILOG_DEBUG("NotifyStringVectorChanged napi_call_function result[%{public}zu]", result);
273             delete callbackInfo;
274             callbackInfo = nullptr;
275             delete work;
276             work = nullptr;
277         },
278         uv_qos_default);
279     return ret;
280 }
281 
NotifyIntChanged(uv_work_t * work)282 int NAccessibilityConfigObserver::NotifyIntChanged(uv_work_t *work)
283 {
284     uv_loop_s *loop = nullptr;
285     napi_get_uv_event_loop(env_, &loop);
286     if (loop == nullptr || work == nullptr) {
287         HILOG_ERROR("loop or work is nullptr.");
288         return RET_ERR_FAILED;
289     }
290     int ret = uv_queue_work_with_qos(
291         loop,
292         work,
293         [](uv_work_t *work) {},
294         [](uv_work_t *work, int status) {
295             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
296             napi_env env = callbackInfo->env_;
297             auto closeScope = [env](napi_handle_scope scope) {
298                 napi_close_handle_scope(env, scope);
299             };
300             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
301                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
302             napi_value jsEvent = nullptr;
303             napi_create_int32(callbackInfo->env_, callbackInfo->int32Value_, &jsEvent);
304 
305             napi_value handler = nullptr;
306             napi_value callResult = nullptr;
307             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
308             napi_value undefined = nullptr;
309             napi_get_undefined(callbackInfo->env_, &undefined);
310             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
311             int32_t result;
312             napi_get_value_int32(callbackInfo->env_, callResult, &result);
313             HILOG_INFO("NotifyIntChanged2JSInner napi_call_function result[%{public}d]", result);
314             delete callbackInfo;
315             callbackInfo = nullptr;
316             delete work;
317             work = nullptr;
318         },
319         uv_qos_default);
320     return ret;
321 }
322 
NotifyUintChanged(uv_work_t * work)323 int NAccessibilityConfigObserver::NotifyUintChanged(uv_work_t *work)
324 {
325     uv_loop_s *loop = nullptr;
326     napi_get_uv_event_loop(env_, &loop);
327     if (loop == nullptr || work == nullptr) {
328         HILOG_ERROR("loop or work is nullptr.");
329         return RET_ERR_FAILED;
330     }
331     int ret = uv_queue_work_with_qos(
332         loop,
333         work,
334         [](uv_work_t *work) {},
335         [](uv_work_t *work, int status) {
336             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
337             napi_env env = callbackInfo->env_;
338             auto closeScope = [env](napi_handle_scope scope) {
339                 napi_close_handle_scope(env, scope);
340             };
341             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
342                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
343             napi_value jsEvent = nullptr;
344             napi_create_uint32(callbackInfo->env_, callbackInfo->uint32Value_, &jsEvent);
345 
346             napi_value handler = nullptr;
347             napi_value callResult = nullptr;
348             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
349             napi_value undefined = nullptr;
350             napi_get_undefined(callbackInfo->env_, &undefined);
351             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
352             uint32_t result;
353             napi_get_value_uint32(callbackInfo->env_, callResult, &result);
354             HILOG_INFO("NotifyUintChanged2JSInner napi_call_function result[%{public}d]", result);
355             delete callbackInfo;
356             callbackInfo = nullptr;
357             delete work;
358             work = nullptr;
359         },
360         uv_qos_default);
361     return ret;
362 }
363 
NotifyDoubleChanged(uv_work_t * work)364 int NAccessibilityConfigObserver::NotifyDoubleChanged(uv_work_t *work)
365 {
366     uv_loop_s *loop = nullptr;
367     napi_get_uv_event_loop(env_, &loop);
368     if (loop == nullptr || work == nullptr) {
369         HILOG_ERROR("loop or work is nullptr.");
370         return RET_ERR_FAILED;
371     }
372     int ret = uv_queue_work_with_qos(
373         loop,
374         work,
375         [](uv_work_t *work) {},
376         [](uv_work_t *work, int status) {
377             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
378             napi_env env = callbackInfo->env_;
379             auto closeScope = [env](napi_handle_scope scope) {
380                 napi_close_handle_scope(env, scope);
381             };
382             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
383                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
384             napi_value jsEvent = nullptr;
385             napi_create_double(callbackInfo->env_, callbackInfo->doubleValue_, &jsEvent);
386 
387             napi_value handler = nullptr;
388             napi_value callResult = nullptr;
389             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
390             napi_value undefined = nullptr;
391             napi_get_undefined(callbackInfo->env_, &undefined);
392             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
393             int32_t result;
394             napi_get_value_int32(callbackInfo->env_, callResult, &result);
395             HILOG_INFO("NotifyDoubleChanged2JSInner napi_call_function result[%{public}d]", result);
396             delete callbackInfo;
397             callbackInfo = nullptr;
398             delete work;
399             work = nullptr;
400         },
401         uv_qos_default);
402     return ret;
403 }
404 
NotifyStateChanged2JS(bool enabled)405 void NAccessibilityConfigObserver::NotifyStateChanged2JS(bool enabled)
406 {
407     HILOG_INFO("id = [%{public}d] enabled = [%{public}s]", static_cast<int32_t>(configId_), enabled ? "true" : "false");
408 
409     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
410     if (callbackInfo == nullptr) {
411         HILOG_ERROR("Failed to create callbackInfo.");
412         return;
413     }
414     callbackInfo->state_ = enabled;
415     callbackInfo->env_ = env_;
416     callbackInfo->ref_ = handlerRef_;
417     uv_work_t *work = new(std::nothrow) uv_work_t;
418     if (!work) {
419         HILOG_ERROR("NotifyStateChanged2JS Failed to create work.");
420         delete callbackInfo;
421         callbackInfo = nullptr;
422         return;
423     }
424     work->data = static_cast<void*>(callbackInfo);
425     int ret = NotifyStateChanged(work);
426     if (ret != 0) {
427         HILOG_ERROR("Failed to execute NotifyStateChanged2JS work queue");
428         delete callbackInfo;
429         callbackInfo = nullptr;
430         delete work;
431         work = nullptr;
432     }
433 }
434 
NotifyPropertyChanged2JS(const OHOS::AccessibilityConfig::CaptionProperty & caption)435 void NAccessibilityConfigObserver::NotifyPropertyChanged2JS(const OHOS::AccessibilityConfig::CaptionProperty &caption)
436 {
437     HILOG_INFO("id = [%{public}d]", static_cast<int32_t>(configId_));
438 
439     CaptionCallbackInfo *callbackInfo = new(std::nothrow) CaptionCallbackInfo();
440     if (callbackInfo == nullptr) {
441         HILOG_ERROR("Failed to create callbackInfo.");
442         return;
443     }
444     callbackInfo->caption_ = caption;
445     callbackInfo->env_ = env_;
446     callbackInfo->ref_ = handlerRef_;
447     uv_work_t *work = new(std::nothrow) uv_work_t;
448     if (!work) {
449         HILOG_ERROR("NotifyPropertyChanged2JS Failed to create work.");
450         delete callbackInfo;
451         callbackInfo = nullptr;
452         return;
453     }
454     work->data = static_cast<void*>(callbackInfo);
455     int ret = NotifyPropertyChanged(work);
456     if (ret != 0) {
457         HILOG_ERROR("Failed to execute NotifyPropertyChanged2JS work queue");
458         delete callbackInfo;
459         callbackInfo = nullptr;
460         delete work;
461         work = nullptr;
462     }
463 }
464 
NotifyStringChanged2JS(const std::string & value)465 void NAccessibilityConfigObserver::NotifyStringChanged2JS(const std::string& value)
466 {
467     HILOG_INFO("value = [%{public}s]", value.c_str());
468 
469     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
470     if (callbackInfo == nullptr) {
471         HILOG_ERROR("Failed to create callbackInfo.");
472         return;
473     }
474     callbackInfo->stringValue_ = value;
475     callbackInfo->env_ = env_;
476     callbackInfo->ref_ = handlerRef_;
477     uv_work_t *work = new(std::nothrow) uv_work_t;
478     if (!work) {
479         HILOG_ERROR("NotifyStringChanged2JS Failed to create work.");
480         delete callbackInfo;
481         callbackInfo = nullptr;
482         return;
483     }
484     work->data = static_cast<void*>(callbackInfo);
485     int ret = NotifyStringChanged(work);
486     if (ret != 0) {
487         HILOG_ERROR("Failed to execute NotifyStringChanged2JS work queue");
488         delete callbackInfo;
489         callbackInfo = nullptr;
490         delete work;
491         work = nullptr;
492     }
493 }
494 
NotifyStringVectorChanged2JS(std::vector<std::string> value)495 void NAccessibilityConfigObserver::NotifyStringVectorChanged2JS(std::vector<std::string> value)
496 {
497     HILOG_DEBUG();
498 
499     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
500     if (callbackInfo == nullptr) {
501         HILOG_ERROR("Failed to create callbackInfo.");
502         return;
503     }
504     callbackInfo->stringVector_ = value;
505     callbackInfo->env_ = env_;
506     callbackInfo->ref_ = handlerRef_;
507     uv_work_t *work = new(std::nothrow) uv_work_t;
508     if (!work) {
509         HILOG_ERROR("NotifyStringVectorChanged2JS Failed to create work.");
510         delete callbackInfo;
511         callbackInfo = nullptr;
512         return;
513     }
514     work->data = static_cast<void*>(callbackInfo);
515     int ret = NotifyStringVectorChanged(work);
516     if (ret != 0) {
517         HILOG_ERROR("Failed to execute NotifyStringVectorChanged2JS work queue");
518         delete callbackInfo;
519         callbackInfo = nullptr;
520         delete work;
521         work = nullptr;
522     }
523 }
524 
NotifyIntChanged2JS(int32_t value)525 void NAccessibilityConfigObserver::NotifyIntChanged2JS(int32_t value)
526 {
527     HILOG_INFO("id = [%{public}d] value = [%{public}d]", static_cast<int32_t>(configId_), value);
528 
529     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
530     if (callbackInfo == nullptr) {
531         HILOG_ERROR("Failed to create callbackInfo.");
532         return;
533     }
534     callbackInfo->int32Value_ = value;
535     callbackInfo->env_ = env_;
536     callbackInfo->ref_ = handlerRef_;
537     uv_work_t *work = new(std::nothrow) uv_work_t;
538     if (!work) {
539         HILOG_ERROR("NotifyIntChanged2JS Failed to create work.");
540         delete callbackInfo;
541         callbackInfo = nullptr;
542         return;
543     }
544     work->data = static_cast<void*>(callbackInfo);
545     int ret = NotifyIntChanged(work);
546     if (ret != 0) {
547         HILOG_ERROR("Failed to execute NotifyIntChanged2JS work queue");
548         delete callbackInfo;
549         callbackInfo = nullptr;
550         delete work;
551         work = nullptr;
552     }
553 }
554 
NotifyUintChanged2JS(uint32_t value)555 void NAccessibilityConfigObserver::NotifyUintChanged2JS(uint32_t value)
556 {
557     HILOG_INFO("id = [%{public}d] value = [%{public}u]", static_cast<int32_t>(configId_), value);
558 
559     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
560     if (callbackInfo == nullptr) {
561         HILOG_ERROR("Failed to create callbackInfo.");
562         return;
563     }
564     callbackInfo->uint32Value_ = value;
565     callbackInfo->env_ = env_;
566     callbackInfo->ref_ = handlerRef_;
567     uv_work_t *work = new(std::nothrow) uv_work_t;
568     if (!work) {
569         HILOG_ERROR("NotifyUintChanged2JS Failed to create work.");
570         delete callbackInfo;
571         callbackInfo = nullptr;
572         return;
573     }
574     work->data = static_cast<void*>(callbackInfo);
575     int ret = NotifyUintChanged(work);
576     if (ret != 0) {
577         HILOG_ERROR("Failed to execute NotifyUintChanged2JS work queue");
578         delete callbackInfo;
579         callbackInfo = nullptr;
580         delete work;
581         work = nullptr;
582     }
583 }
584 
NotifyDoubleChanged2JS(double value)585 void NAccessibilityConfigObserver::NotifyDoubleChanged2JS(double value)
586 {
587     HILOG_INFO("id = [%{public}d] value = [%{public}f]", static_cast<int32_t>(configId_), value);
588 
589     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
590     if (callbackInfo == nullptr) {
591         HILOG_ERROR("Failed to create callbackInfo.");
592         return;
593     }
594     callbackInfo->doubleValue_ = value;
595     callbackInfo->env_ = env_;
596     callbackInfo->ref_ = handlerRef_;
597     uv_work_t *work = new(std::nothrow) uv_work_t;
598     if (!work) {
599         HILOG_ERROR("NotifyDoubleChanged2JS Failed to create work.");
600         delete callbackInfo;
601         callbackInfo = nullptr;
602         return;
603     }
604     work->data = static_cast<void*>(callbackInfo);
605     int ret = NotifyDoubleChanged(work);
606     if (ret != 0) {
607         HILOG_ERROR("Failed to execute NotifyDoubleChanged2JS work queue");
608         delete callbackInfo;
609         callbackInfo = nullptr;
610         delete work;
611         work = nullptr;
612     }
613 }
614 
SubscribeToFramework()615 void NAccessibilityConfigObserverImpl::SubscribeToFramework()
616 {
617     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
618     for (int32_t index = 0; index < static_cast<int32_t>(CONFIG_ID_MAX); index ++) {
619         instance.SubscribeConfigObserver(static_cast<CONFIG_ID>(index), shared_from_this(), false);
620     }
621 }
622 
OnConfigChanged(const OHOS::AccessibilityConfig::CONFIG_ID id,const OHOS::AccessibilityConfig::ConfigValue & value)623 void NAccessibilityConfigObserverImpl::OnConfigChanged(
624     const OHOS::AccessibilityConfig::CONFIG_ID id, const OHOS::AccessibilityConfig::ConfigValue& value)
625 {
626     HILOG_INFO();
627     std::lock_guard<ffrt::mutex> lock(mutex_);
628     for (auto &observer : observers_) {
629         if (observer && observer->configId_ == id) {
630             observer->OnConfigChanged(value);
631         }
632     }
633 }
634 
SubscribeObserver(napi_env env,OHOS::AccessibilityConfig::CONFIG_ID id,napi_value observer)635 void NAccessibilityConfigObserverImpl::SubscribeObserver(napi_env env,
636     OHOS::AccessibilityConfig::CONFIG_ID id, napi_value observer)
637 {
638     HILOG_INFO();
639     std::lock_guard<ffrt::mutex> lock(mutex_);
640     for (auto iter = observers_.begin(); iter != observers_.end();) {
641         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) {
642             HILOG_DEBUG("SubscribeObserver Observer exist");
643             return;
644         } else {
645             iter++;
646         }
647     }
648 
649     napi_ref handler = nullptr;
650     napi_create_reference(env, observer, 1, &handler);
651     std::shared_ptr<NAccessibilityConfigObserver> observerPtr =
652         std::make_shared<NAccessibilityConfigObserver>(env, handler, id);
653 
654     observers_.emplace_back(observerPtr);
655 }
656 
UnsubscribeObserver(napi_env env,OHOS::AccessibilityConfig::CONFIG_ID id,napi_value observer)657 void NAccessibilityConfigObserverImpl::UnsubscribeObserver(napi_env env,
658     OHOS::AccessibilityConfig::CONFIG_ID id, napi_value observer)
659 {
660     HILOG_INFO();
661     std::lock_guard<ffrt::mutex> lock(mutex_);
662     for (auto iter = observers_.begin(); iter != observers_.end();) {
663         if ((*iter)->configId_ == id) {
664             if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) {
665                 observers_.erase(iter);
666                 return;
667             } else {
668                 iter++;
669             }
670         } else {
671             iter++;
672         }
673     }
674 }
675 
UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID id)676 void NAccessibilityConfigObserverImpl::UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID id)
677 {
678     HILOG_INFO();
679     std::lock_guard<ffrt::mutex> lock(mutex_);
680     for (auto iter = observers_.begin(); iter != observers_.end();) {
681         if ((*iter)->configId_ == id) {
682             iter = observers_.erase(iter);
683         } else {
684             iter++;
685         }
686     }
687 }
688