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 {
TmpOpenScope(napi_env env)32 napi_handle_scope TmpOpenScope(napi_env env)
33 {
34     napi_handle_scope scope = nullptr;
35     NAPI_CALL(env, napi_open_handle_scope(env, &scope));
36     return scope;
37 }
38 } // namespace Accessibility
39 } // namespace OHOS
40 
OnConfigChangedExtra(const ConfigValue &value)41 void NAccessibilityConfigObserver::OnConfigChangedExtra(const ConfigValue &value)
42 {
43     HILOG_INFO("id = [%{public}d]", static_cast<int32_t>(configId_));
44     if (configId_ == CONFIG_CONTENT_TIMEOUT) {
45         NotifyIntChanged2JS(static_cast<int32_t>(value.contentTimeout));
46     } else if (configId_ == CONFIG_BRIGHTNESS_DISCOUNT) {
47         NotifyFloatChanged2JS(value.brightnessDiscount);
48     } else if (configId_ == CONFIG_AUDIO_BALANCE) {
49         NotifyFloatChanged2JS(value.audioBalance);
50     } else if (configId_ ==  CONFIG_HIGH_CONTRAST_TEXT) {
51         NotifyStateChanged2JS(value.highContrastText);
52     } else if (configId_ ==  CONFIG_DALTONIZATION_STATE) {
53         NotifyStateChanged2JS(value.daltonizationState);
54     } else if (configId_ == CONFIG_INVERT_COLOR) {
55         NotifyStateChanged2JS(value.invertColor);
56     } else if (configId_ == CONFIG_ANIMATION_OFF) {
57         NotifyStateChanged2JS(value.animationOff);
58     } else if (configId_ == CONFIG_AUDIO_MONO) {
59         NotifyStateChanged2JS(value.audioMono);
60     } else if (configId_ == CONIFG_CLICK_RESPONSE_TIME) {
61         NotifyStringChanged2JS(ConvertClickResponseTimeTypeToString(value.clickResponseTime));
62     } else if (configId_ == CONFIG_IGNORE_REPEAT_CLICK_TIME) {
63         NotifyStringChanged2JS(ConvertIgnoreRepeatClickTimeTypeToString(value.ignoreRepeatClickTime));
64     } else if (configId_ == CONFIG_IGNORE_REPEAT_CLICK_STATE) {
65         NotifyStateChanged2JS(value.ignoreRepeatClickState);
66     }
67 }
68 
OnConfigChanged(const ConfigValue &value)69 void NAccessibilityConfigObserver::OnConfigChanged(const ConfigValue &value)
70 {
71     HILOG_INFO("id = [%{public}d]", static_cast<int32_t>(configId_));
72     if (configId_ == CONFIG_CAPTION_STATE) {
73         NotifyStateChanged2JS(value.captionState);
74     } else if (configId_ == CONFIG_CAPTION_STYLE) {
75         NotifyPropertyChanged2JS(value.captionStyle);
76     } else if (configId_ == CONFIG_SCREEN_MAGNIFICATION) {
77         NotifyStateChanged2JS(value.screenMagnifier);
78     } else if (configId_ == CONFIG_MOUSE_KEY) {
79         NotifyStateChanged2JS(value.mouseKey);
80     } else if (configId_ == CONFIG_SHORT_KEY) {
81         NotifyStateChanged2JS(value.shortkey);
82     } else if (configId_ == CONFIG_SHORT_KEY_TARGET) {
83         NotifyStringChanged2JS(value.shortkey_target);
84     } else if (configId_ == CONFIG_SHORT_KEY_MULTI_TARGET) {
85         NotifyStringVectorChanged2JS(value.shortkeyMultiTarget);
86     } else if (configId_ == CONFIG_MOUSE_AUTOCLICK) {
87         NotifyIntChanged2JS(value.mouseAutoClick);
88     } else if (configId_ == CONFIG_DALTONIZATION_COLOR_FILTER) {
89         OnDaltonizationColorFilterConfigChanged();
90     } else {
91         OnConfigChangedExtra(value);
92     }
93 }
94 
OnDaltonizationColorFilterConfigChanged()95 void NAccessibilityConfigObserver::OnDaltonizationColorFilterConfigChanged()
96 {
97     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
98     DALTONIZATION_TYPE type = Normal;
99     RetError ret = instance.GetDaltonizationColorFilter(type);
100     NotifyStringChanged2JS(ConvertDaltonizationTypeToString(type));
101     if (ret != RET_OK) {
102         HILOG_ERROR("get DaltonizationColorFilter failed: %{public}d", ret);
103     }
104 }
105 
NotifyStateChanged(uv_work_t *work)106 int NAccessibilityConfigObserver::NotifyStateChanged(uv_work_t *work)
107 {
108     uv_loop_s *loop = nullptr;
109     napi_get_uv_event_loop(env_, &loop);
110     if (loop == nullptr || work == nullptr) {
111         HILOG_ERROR("loop or work is nullptr.");
112         return RET_ERR_FAILED;
113     }
114     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
115         [](uv_work_t *work, int status) {
116             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
117             napi_env env = callbackInfo->env_;
118             auto closeScope = [env](napi_handle_scope scope) {
119                 napi_close_handle_scope(env, scope);
120             };
121             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
122                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
123             napi_value jsEvent = nullptr;
124             napi_create_object(callbackInfo->env_, &jsEvent);
125             if (jsEvent == nullptr) {
126                 HILOG_ERROR("napi_create_object fail.");
127                 return;
128             }
129             napi_get_boolean(callbackInfo->env_, callbackInfo->state_, &jsEvent);
130 
131             napi_value handler = nullptr;
132             napi_value callResult = nullptr;
133             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
134             napi_value undefined = nullptr;
135             napi_get_undefined(callbackInfo->env_, &undefined);
136             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
137             int32_t result;
138             napi_get_value_int32(callbackInfo->env_, callResult, &result);
139             HILOG_INFO("NotifyStateChangedJS napi_call_function result[%{public}d]", result);
140             delete callbackInfo;
141             callbackInfo = nullptr;
142             delete work;
143             work = nullptr;
144         },
145         uv_qos_default);
146     return ret;
147 }
148 
NotifyPropertyChanged(uv_work_t *work)149 int NAccessibilityConfigObserver::NotifyPropertyChanged(uv_work_t *work)
150 {
151     uv_loop_s *loop = nullptr;
152     napi_get_uv_event_loop(env_, &loop);
153     if (loop == nullptr || work == nullptr) {
154         HILOG_ERROR("loop or work is nullptr.");
155         return RET_ERR_FAILED;
156     }
157     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
158         [](uv_work_t *work, int status) {
159             CaptionCallbackInfo *callbackInfo = static_cast<CaptionCallbackInfo*>(work->data);
160             napi_env env = callbackInfo->env_;
161             auto closeScope = [env](napi_handle_scope scope) {
162                 napi_close_handle_scope(env, scope);
163             };
164             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
165                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
166             napi_value jsEvent = nullptr;
167             napi_create_object(callbackInfo->env_, &jsEvent);
168             if (jsEvent == nullptr) {
169                 HILOG_ERROR("napi_create_object fail.");
170                 return;
171             }
172             ConvertCaptionPropertyToJS(callbackInfo->env_, jsEvent, callbackInfo->caption_);
173 
174             napi_value handler = nullptr;
175             napi_value callResult = nullptr;
176             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
177             napi_value undefined = nullptr;
178             napi_get_undefined(callbackInfo->env_, &undefined);
179             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
180             int32_t result;
181             napi_get_value_int32(callbackInfo->env_, callResult, &result);
182             HILOG_INFO("NotifyPropertyChangedJS napi_call_function result[%{public}d]", result);
183             delete callbackInfo;
184             callbackInfo = nullptr;
185             delete work;
186             work = nullptr;
187         },
188         uv_qos_default);
189     return ret;
190 }
191 
NotifyStringChanged(uv_work_t *work)192 int NAccessibilityConfigObserver::NotifyStringChanged(uv_work_t *work)
193 {
194     uv_loop_s *loop = nullptr;
195     napi_get_uv_event_loop(env_, &loop);
196     if (loop == nullptr || work == nullptr) {
197         HILOG_ERROR("loop or work is nullptr.");
198         return RET_ERR_FAILED;
199     }
200     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
201         [](uv_work_t *work, int status) {
202             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
203             napi_env env = callbackInfo->env_;
204             auto closeScope = [env](napi_handle_scope scope) {
205                 napi_close_handle_scope(env, scope);
206             };
207             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
208                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
209             napi_value jsEvent = nullptr;
210             napi_create_string_utf8(callbackInfo->env_, callbackInfo->stringValue_.c_str(),
211                 callbackInfo->stringValue_.length(), &jsEvent);
212             napi_value handler = nullptr;
213             napi_value callResult = nullptr;
214             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
215             napi_value undefined = nullptr;
216             napi_get_undefined(callbackInfo->env_, &undefined);
217             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
218             size_t result;
219             const uint32_t BUF_SIZE = 1024;
220             char buf[BUF_SIZE] = {0};
221             napi_get_value_string_utf8(callbackInfo->env_, callResult, buf, BUF_SIZE, &result);
222             HILOG_INFO("NotifyStringChanged2JSInner napi_call_function result[%{public}zu]", result);
223             delete callbackInfo;
224             callbackInfo = nullptr;
225             delete work;
226             work = nullptr;
227         },
228         uv_qos_default);
229     return ret;
230 }
231 
NotifyStringVectorChanged(uv_work_t *work)232 int NAccessibilityConfigObserver::NotifyStringVectorChanged(uv_work_t *work)
233 {
234     uv_loop_s *loop = nullptr;
235     napi_get_uv_event_loop(env_, &loop);
236     if (loop == nullptr || work == nullptr) {
237         HILOG_ERROR("loop or work is nullptr.");
238         return RET_ERR_FAILED;
239     }
240     int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
241         [](uv_work_t *work, int status) {
242             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
243             napi_env env = callbackInfo->env_;
244             auto closeScope = [env](napi_handle_scope scope) {
245                 napi_close_handle_scope(env, scope);
246             };
247             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
248                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
249             napi_value jsEvent = nullptr;
250             napi_create_array(callbackInfo->env_, &jsEvent);
251             ConvertStringVecToJS(callbackInfo->env_, jsEvent, callbackInfo->stringVector_);
252 
253             napi_value handler = nullptr;
254             napi_value callResult = nullptr;
255             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
256             napi_value undefined = nullptr;
257             napi_get_undefined(callbackInfo->env_, &undefined);
258             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
259             size_t result;
260             const uint32_t BUF_SIZE = 1024;
261             char buf[BUF_SIZE] = {0};
262             napi_get_value_string_utf8(callbackInfo->env_, callResult, buf, BUF_SIZE, &result);
263             HILOG_DEBUG("NotifyStringVectorChanged napi_call_function result[%{public}zu]", result);
264             delete callbackInfo;
265             callbackInfo = nullptr;
266             delete work;
267             work = nullptr;
268         },
269         uv_qos_default);
270     return ret;
271 }
272 
NotifyIntChanged(uv_work_t *work)273 int NAccessibilityConfigObserver::NotifyIntChanged(uv_work_t *work)
274 {
275     uv_loop_s *loop = nullptr;
276     napi_get_uv_event_loop(env_, &loop);
277     if (loop == nullptr || work == nullptr) {
278         HILOG_ERROR("loop or work is nullptr.");
279         return RET_ERR_FAILED;
280     }
281     int ret = uv_queue_work_with_qos(
282         loop,
283         work,
284         [](uv_work_t *work) {},
285         [](uv_work_t *work, int status) {
286             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
287             napi_env env = callbackInfo->env_;
288             auto closeScope = [env](napi_handle_scope scope) {
289                 napi_close_handle_scope(env, scope);
290             };
291             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
292                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
293             napi_value jsEvent = nullptr;
294             napi_create_int32(callbackInfo->env_, callbackInfo->int32Value_, &jsEvent);
295 
296             napi_value handler = nullptr;
297             napi_value callResult = nullptr;
298             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
299             napi_value undefined = nullptr;
300             napi_get_undefined(callbackInfo->env_, &undefined);
301             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
302             int32_t result;
303             napi_get_value_int32(callbackInfo->env_, callResult, &result);
304             HILOG_INFO("NotifyIntChanged2JSInner napi_call_function result[%{public}d]", result);
305             delete callbackInfo;
306             callbackInfo = nullptr;
307             delete work;
308             work = nullptr;
309         },
310         uv_qos_default);
311     return ret;
312 }
313 
NotifyUintChanged(uv_work_t *work)314 int NAccessibilityConfigObserver::NotifyUintChanged(uv_work_t *work)
315 {
316     uv_loop_s *loop = nullptr;
317     napi_get_uv_event_loop(env_, &loop);
318     if (loop == nullptr || work == nullptr) {
319         HILOG_ERROR("loop or work is nullptr.");
320         return RET_ERR_FAILED;
321     }
322     int ret = uv_queue_work_with_qos(
323         loop,
324         work,
325         [](uv_work_t *work) {},
326         [](uv_work_t *work, int status) {
327             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
328             napi_env env = callbackInfo->env_;
329             auto closeScope = [env](napi_handle_scope scope) {
330                 napi_close_handle_scope(env, scope);
331             };
332             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
333                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
334             napi_value jsEvent = nullptr;
335             napi_create_uint32(callbackInfo->env_, callbackInfo->uint32Value_, &jsEvent);
336 
337             napi_value handler = nullptr;
338             napi_value callResult = nullptr;
339             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
340             napi_value undefined = nullptr;
341             napi_get_undefined(callbackInfo->env_, &undefined);
342             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
343             uint32_t result;
344             napi_get_value_uint32(callbackInfo->env_, callResult, &result);
345             HILOG_INFO("NotifyUintChanged2JSInner napi_call_function result[%{public}d]", result);
346             delete callbackInfo;
347             callbackInfo = nullptr;
348             delete work;
349             work = nullptr;
350         },
351         uv_qos_default);
352     return ret;
353 }
354 
NotifyFloatChanged(uv_work_t *work)355 int NAccessibilityConfigObserver::NotifyFloatChanged(uv_work_t *work)
356 {
357     uv_loop_s *loop = nullptr;
358     napi_get_uv_event_loop(env_, &loop);
359     if (loop == nullptr || work == nullptr) {
360         HILOG_ERROR("loop or work is nullptr.");
361         return RET_ERR_FAILED;
362     }
363     int ret = uv_queue_work_with_qos(
364         loop,
365         work,
366         [](uv_work_t *work) {},
367         [](uv_work_t *work, int status) {
368             StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
369             napi_env env = callbackInfo->env_;
370             auto closeScope = [env](napi_handle_scope scope) {
371                 napi_close_handle_scope(env, scope);
372             };
373             std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
374                 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
375             napi_value jsEvent = nullptr;
376             napi_create_double(callbackInfo->env_, double(callbackInfo->floatValue_), &jsEvent);
377 
378             napi_value handler = nullptr;
379             napi_value callResult = nullptr;
380             napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
381             napi_value undefined = nullptr;
382             napi_get_undefined(callbackInfo->env_, &undefined);
383             napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
384             int32_t result;
385             napi_get_value_int32(callbackInfo->env_, callResult, &result);
386             HILOG_INFO("NotifyFloatChanged2JSInner napi_call_function result[%{public}d]", result);
387             delete callbackInfo;
388             callbackInfo = nullptr;
389             delete work;
390             work = nullptr;
391         },
392         uv_qos_default);
393     return ret;
394 }
395 
NotifyStateChanged2JS(bool enabled)396 void NAccessibilityConfigObserver::NotifyStateChanged2JS(bool enabled)
397 {
398     HILOG_INFO("id = [%{public}d] enabled = [%{public}s]", static_cast<int32_t>(configId_), enabled ? "true" : "false");
399 
400     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
401     if (callbackInfo == nullptr) {
402         HILOG_ERROR("Failed to create callbackInfo.");
403         return;
404     }
405     callbackInfo->state_ = enabled;
406     callbackInfo->env_ = env_;
407     callbackInfo->ref_ = handlerRef_;
408     uv_work_t *work = new(std::nothrow) uv_work_t;
409     if (!work) {
410         HILOG_ERROR("NotifyStateChanged2JS Failed to create work.");
411         delete callbackInfo;
412         callbackInfo = nullptr;
413         return;
414     }
415     work->data = static_cast<void*>(callbackInfo);
416     int ret = NotifyStateChanged(work);
417     if (ret != 0) {
418         HILOG_ERROR("Failed to execute NotifyStateChanged2JS work queue");
419         delete callbackInfo;
420         callbackInfo = nullptr;
421         delete work;
422         work = nullptr;
423     }
424 }
425 
NotifyPropertyChanged2JS(const OHOS::AccessibilityConfig::CaptionProperty &caption)426 void NAccessibilityConfigObserver::NotifyPropertyChanged2JS(const OHOS::AccessibilityConfig::CaptionProperty &caption)
427 {
428     HILOG_INFO("id = [%{public}d]", static_cast<int32_t>(configId_));
429 
430     CaptionCallbackInfo *callbackInfo = new(std::nothrow) CaptionCallbackInfo();
431     if (callbackInfo == nullptr) {
432         HILOG_ERROR("Failed to create callbackInfo.");
433         return;
434     }
435     callbackInfo->caption_ = caption;
436     callbackInfo->env_ = env_;
437     callbackInfo->ref_ = handlerRef_;
438     uv_work_t *work = new(std::nothrow) uv_work_t;
439     if (!work) {
440         HILOG_ERROR("NotifyPropertyChanged2JS Failed to create work.");
441         delete callbackInfo;
442         callbackInfo = nullptr;
443         return;
444     }
445     work->data = static_cast<void*>(callbackInfo);
446     int ret = NotifyPropertyChanged(work);
447     if (ret != 0) {
448         HILOG_ERROR("Failed to execute NotifyPropertyChanged2JS work queue");
449         delete callbackInfo;
450         callbackInfo = nullptr;
451         delete work;
452         work = nullptr;
453     }
454 }
455 
NotifyStringChanged2JS(const std::string& value)456 void NAccessibilityConfigObserver::NotifyStringChanged2JS(const std::string& value)
457 {
458     HILOG_INFO("value = [%{public}s]", value.c_str());
459 
460     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
461     if (callbackInfo == nullptr) {
462         HILOG_ERROR("Failed to create callbackInfo.");
463         return;
464     }
465     callbackInfo->stringValue_ = value;
466     callbackInfo->env_ = env_;
467     callbackInfo->ref_ = handlerRef_;
468     uv_work_t *work = new(std::nothrow) uv_work_t;
469     if (!work) {
470         HILOG_ERROR("NotifyStringChanged2JS Failed to create work.");
471         delete callbackInfo;
472         callbackInfo = nullptr;
473         return;
474     }
475     work->data = static_cast<void*>(callbackInfo);
476     int ret = NotifyStringChanged(work);
477     if (ret != 0) {
478         HILOG_ERROR("Failed to execute NotifyStringChanged2JS work queue");
479         delete callbackInfo;
480         callbackInfo = nullptr;
481         delete work;
482         work = nullptr;
483     }
484 }
485 
NotifyStringVectorChanged2JS(std::vector<std::string> value)486 void NAccessibilityConfigObserver::NotifyStringVectorChanged2JS(std::vector<std::string> value)
487 {
488     HILOG_DEBUG();
489 
490     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
491     if (callbackInfo == nullptr) {
492         HILOG_ERROR("Failed to create callbackInfo.");
493         return;
494     }
495     callbackInfo->stringVector_ = value;
496     callbackInfo->env_ = env_;
497     callbackInfo->ref_ = handlerRef_;
498     uv_work_t *work = new(std::nothrow) uv_work_t;
499     if (!work) {
500         HILOG_ERROR("NotifyStringVectorChanged2JS Failed to create work.");
501         delete callbackInfo;
502         callbackInfo = nullptr;
503         return;
504     }
505     work->data = static_cast<void*>(callbackInfo);
506     int ret = NotifyStringVectorChanged(work);
507     if (ret != 0) {
508         HILOG_ERROR("Failed to execute NotifyStringVectorChanged2JS work queue");
509         delete callbackInfo;
510         callbackInfo = nullptr;
511         delete work;
512         work = nullptr;
513     }
514 }
515 
NotifyIntChanged2JS(int32_t value)516 void NAccessibilityConfigObserver::NotifyIntChanged2JS(int32_t value)
517 {
518     HILOG_INFO("id = [%{public}d] value = [%{public}d]", static_cast<int32_t>(configId_), value);
519 
520     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
521     if (callbackInfo == nullptr) {
522         HILOG_ERROR("Failed to create callbackInfo.");
523         return;
524     }
525     callbackInfo->int32Value_ = value;
526     callbackInfo->env_ = env_;
527     callbackInfo->ref_ = handlerRef_;
528     uv_work_t *work = new(std::nothrow) uv_work_t;
529     if (!work) {
530         HILOG_ERROR("NotifyIntChanged2JS Failed to create work.");
531         delete callbackInfo;
532         callbackInfo = nullptr;
533         return;
534     }
535     work->data = static_cast<void*>(callbackInfo);
536     int ret = NotifyIntChanged(work);
537     if (ret != 0) {
538         HILOG_ERROR("Failed to execute NotifyIntChanged2JS work queue");
539         delete callbackInfo;
540         callbackInfo = nullptr;
541         delete work;
542         work = nullptr;
543     }
544 }
545 
NotifyUintChanged2JS(uint32_t value)546 void NAccessibilityConfigObserver::NotifyUintChanged2JS(uint32_t value)
547 {
548     HILOG_INFO("id = [%{public}d] value = [%{public}u]", static_cast<int32_t>(configId_), value);
549 
550     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
551     if (callbackInfo == nullptr) {
552         HILOG_ERROR("Failed to create callbackInfo.");
553         return;
554     }
555     callbackInfo->uint32Value_ = value;
556     callbackInfo->env_ = env_;
557     callbackInfo->ref_ = handlerRef_;
558     uv_work_t *work = new(std::nothrow) uv_work_t;
559     if (!work) {
560         HILOG_ERROR("NotifyUintChanged2JS Failed to create work.");
561         delete callbackInfo;
562         callbackInfo = nullptr;
563         return;
564     }
565     work->data = static_cast<void*>(callbackInfo);
566     int ret = NotifyUintChanged(work);
567     if (ret != 0) {
568         HILOG_ERROR("Failed to execute NotifyUintChanged2JS work queue");
569         delete callbackInfo;
570         callbackInfo = nullptr;
571         delete work;
572         work = nullptr;
573     }
574 }
575 
NotifyFloatChanged2JS(float value)576 void NAccessibilityConfigObserver::NotifyFloatChanged2JS(float value)
577 {
578     HILOG_INFO("id = [%{public}d] value = [%{public}f]", static_cast<int32_t>(configId_), value);
579 
580     StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo();
581     if (callbackInfo == nullptr) {
582         HILOG_ERROR("Failed to create callbackInfo.");
583         return;
584     }
585     callbackInfo->floatValue_ = value;
586     callbackInfo->env_ = env_;
587     callbackInfo->ref_ = handlerRef_;
588     uv_work_t *work = new(std::nothrow) uv_work_t;
589     if (!work) {
590         HILOG_ERROR("NotifyFloatChanged2JS Failed to create work.");
591         delete callbackInfo;
592         callbackInfo = nullptr;
593         return;
594     }
595     work->data = static_cast<void*>(callbackInfo);
596     int ret = NotifyFloatChanged(work);
597     if (ret != 0) {
598         HILOG_ERROR("Failed to execute NotifyFloatChanged2JS work queue");
599         delete callbackInfo;
600         callbackInfo = nullptr;
601         delete work;
602         work = nullptr;
603     }
604 }
605 
SubscribeToFramework()606 void NAccessibilityConfigObserverImpl::SubscribeToFramework()
607 {
608     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
609     for (int32_t index = 0; index < static_cast<int32_t>(CONFIG_ID_MAX); index ++) {
610         instance.SubscribeConfigObserver(static_cast<CONFIG_ID>(index), shared_from_this(), false);
611     }
612 }
613 
UnsubscribeFromFramework()614 void NAccessibilityConfigObserverImpl::UnsubscribeFromFramework()
615 {
616     HILOG_INFO("UnsubscribeFromFramework");
617     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
618     for (int32_t index = 0; index < static_cast<int32_t>(CONFIG_ID_MAX); index ++) {
619         instance.UnsubscribeConfigObserver(static_cast<CONFIG_ID>(index), shared_from_this());
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