• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 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_system_ability_client.h"
17 
18 #include <uv.h>
19 #include "accessibility_state_event.h"
20 #include "hilog_wrapper.h"
21 #include "accessibility_utils.h"
22 #include "api_reporter_helper.h"
23 
24 using namespace OHOS;
25 using namespace OHOS::Accessibility;
26 using namespace OHOS::AccessibilityNapi;
27 
28 namespace OHOS {
29 namespace Accessibility {
TmpOpenScope(napi_env env)30 napi_handle_scope TmpOpenScope(napi_env env)
31 {
32     napi_handle_scope scope = nullptr;
33     NAPI_CALL(env, napi_open_handle_scope(env, &scope));
34     return scope;
35 }
36 } // namespace Accessibility
37 } // namespace OHOS
38 
39 std::shared_ptr<StateListenerImpl> NAccessibilityClient::accessibilityStateListeners_ =
40     std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED);
41 std::shared_ptr<StateListenerImpl> NAccessibilityClient::touchGuideStateListeners_ =
42     std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED);
43 std::shared_ptr<StateListenerImpl> NAccessibilityClient::screenReaderStateListeners_ =
44     std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED);
45 std::shared_ptr<StateListenerImpl> NAccessibilityClient::touchModeListeners_ =
46     std::make_shared<StateListenerImpl>(AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED);
47 std::shared_ptr<NAccessibilityConfigObserverImpl> NAccessibilityClient::captionListeners_ =
48     std::make_shared<NAccessibilityConfigObserverImpl>();
49 constexpr int32_t REPORTER_THRESHOLD_VALUE = 3000;
50 
51 napi_ref NAccessibilityClient::aaConsRef_;
52 napi_ref NAccessibilityClient::aaStyleConsRef_;
53 
54 #define ACCESSIBILITY_NAPI_ASSERT(env, cond, errCode) \
55 do { \
56     if (!(cond)) { \
57         napi_value err = CreateBusinessError(env, errCode); \
58         napi_throw(env, err); \
59         napi_value res = nullptr; \
60         napi_get_undefined(env, &res); \
61         return res; \
62     } \
63 } while (0)
64 
IsScreenReaderOpenSync(napi_env env,napi_callback_info info)65 napi_value NAccessibilityClient::IsScreenReaderOpenSync(napi_env env, napi_callback_info info)
66 {
67     HILOG_INFO();
68     size_t argc = ARGS_SIZE_ONE;
69     napi_value argv = nullptr;
70     bool status = false;
71     do {
72         napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
73         if (argc != ARGS_SIZE_ZERO) {
74             break;
75         }
76         auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
77         if (asaClient == nullptr) {
78             break;
79         }
80         asaClient->IsScreenReaderEnabled(status);
81     } while (0);
82     napi_value result = nullptr;
83     napi_get_boolean(env, status, &result);
84     return result;
85 }
86 
IsOpenAccessibilitySync(napi_env env,napi_callback_info info)87 napi_value NAccessibilityClient::IsOpenAccessibilitySync(napi_env env, napi_callback_info info)
88 {
89 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
90     ApiReportHelper reporter("NAccessibilityClient.IsOpenAccessibilitySync");
91 #endif // ACCESSIBILITY_EMULATOR_DEFINED
92     HILOG_INFO();
93     size_t argc = ARGS_SIZE_ONE;
94     napi_value argv = nullptr;
95     bool status = false;
96     do {
97         napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
98         if (argc != ARGS_SIZE_ZERO) {
99             break;
100         }
101         auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
102         if (asaClient == nullptr) {
103             break;
104         }
105         asaClient->IsEnabled(status);
106     } while (0);
107     napi_value result = nullptr;
108     napi_get_boolean(env, status, &result);
109     return result;
110 }
111 
IsOpenAccessibility(napi_env env,napi_callback_info info)112 napi_value NAccessibilityClient::IsOpenAccessibility(napi_env env, napi_callback_info info)
113 {
114 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
115     ApiReportHelper reporter("NAccessibilityClient.IsOpenAccessibility");
116 #endif // ACCESSIBILITY_EMULATOR_DEFINED
117     HILOG_INFO();
118     size_t argc = ARGS_SIZE_ONE;
119     napi_value argv = nullptr;
120     NAccessibilitySystemAbilityClient* callbackInfo = new(std::nothrow) NAccessibilitySystemAbilityClient();
121     if (callbackInfo == nullptr) {
122         HILOG_ERROR("Failed to create callbackInfo.");
123         return nullptr;
124     }
125     napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
126 
127     napi_value promise = nullptr;
128     if (argc > 0 && CheckJsFunction(env, argv)) {
129         HILOG_DEBUG("IsOpenAccessibility callback mode");
130         napi_create_reference(env, argv, 1, &callbackInfo->callback_);
131         napi_get_undefined(env, &promise);
132     } else {
133         HILOG_DEBUG("IsOpenAccessibility promise mode");
134         napi_create_promise(env, &callbackInfo->deferred_, &promise);
135     }
136     napi_value resource = nullptr;
137     napi_create_string_utf8(env, "IsOpenAccessibility", NAPI_AUTO_LENGTH, &resource);
138 
139     auto ret = napi_create_async_work(env, nullptr, resource,
140         // Execute async to call c++ function
141         [](napi_env env, void* data) {
142             NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
143             auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
144             if (asaClient) {
145                 callbackInfo->ret_ = asaClient->IsEnabled(callbackInfo->enabled_);
146                 HILOG_INFO("IsOpenAccessibility Executing enabled[%{public}d]", callbackInfo->enabled_);
147             }
148         },
149         // Execute the complete function
150         [](napi_env env, napi_status status, void* data) {
151             Completefunction(env, "IsOpenAccessibility", data);
152         },
153         reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
154     if (ret != napi_ok) {
155         delete callbackInfo;
156         callbackInfo = nullptr;
157         HILOG_ERROR("failed to create async work.");
158         return nullptr;
159     }
160     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
161     return promise;
162 }
163 
IsOpenTouchExplorationSync(napi_env env,napi_callback_info info)164 napi_value NAccessibilityClient::IsOpenTouchExplorationSync(napi_env env, napi_callback_info info)
165 {
166 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
167     ApiReportHelper reporter("NAccessibilityClient.IsOpenTouchExplorationSync");
168 #endif // ACCESSIBILITY_EMULATOR_DEFINED
169     HILOG_INFO();
170     size_t argc = ARGS_SIZE_ONE;
171     napi_value argv = nullptr;
172     bool status = false;
173     do {
174         napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
175         if (argc != ARGS_SIZE_ZERO) {
176             break;
177         }
178         auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
179         if (asaClient == nullptr) {
180             break;
181         }
182         asaClient->IsTouchExplorationEnabled(status);
183     } while (0);
184     napi_value result = nullptr;
185     napi_get_boolean(env, status, &result);
186     return result;
187 }
188 
IsOpenTouchExploration(napi_env env,napi_callback_info info)189 napi_value NAccessibilityClient::IsOpenTouchExploration(napi_env env, napi_callback_info info)
190 {
191 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
192     ApiReportHelper reporter("NAccessibilityClient.IsOpenTouchExploration");
193 #endif // ACCESSIBILITY_EMULATOR_DEFINED
194     HILOG_INFO();
195     NAccessibilitySystemAbilityClient* callbackInfo = new(std::nothrow) NAccessibilitySystemAbilityClient();
196     if (callbackInfo == nullptr) {
197         HILOG_ERROR("Failed to create callbackInfo.");
198         return nullptr;
199     }
200     size_t argc = ARGS_SIZE_ONE;
201     napi_value argv = nullptr;
202     napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
203 
204     napi_value promise = nullptr;
205     if (argc > 0 && CheckJsFunction(env, argv)) {
206         HILOG_DEBUG("IsOpenTouchExploration callback mode");
207         napi_create_reference(env, argv, 1, &callbackInfo->callback_);
208         napi_get_undefined(env, &promise);
209     } else {
210         HILOG_DEBUG("IsOpenTouchExploration promise mode");
211         napi_create_promise(env, &callbackInfo->deferred_, &promise);
212     }
213     napi_value resource = nullptr;
214     napi_create_string_utf8(env, "IsOpenTouchExploration", NAPI_AUTO_LENGTH, &resource);
215 
216     auto ret = napi_create_async_work(env, nullptr, resource,
217         // Execute async to call c++ function
218         [](napi_env env, void* data) {
219             NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
220             auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
221             if (asaClient) {
222                 callbackInfo->ret_ = asaClient->IsTouchExplorationEnabled(callbackInfo->touchEnabled_);
223                 HILOG_INFO("IsOpenTouchExploration Executing touchEnabled[%{public}d]", callbackInfo->touchEnabled_);
224             }
225         },
226         // Execute the complete function
227         [](napi_env env, napi_status status, void* data) {
228             Completefunction(env, "IsOpenTouchExploration", data);
229         },
230         reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
231     if (ret != napi_ok) {
232         delete callbackInfo;
233         callbackInfo = nullptr;
234         HILOG_ERROR("failed to create async work.");
235         return nullptr;
236     }
237     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
238     return promise;
239 }
240 
GetTouchModeSync(napi_env env,napi_callback_info info)241 napi_value NAccessibilityClient::GetTouchModeSync(napi_env env, napi_callback_info info)
242 {
243     HILOG_INFO();
244     size_t argc = ARGS_SIZE_ONE;
245     napi_value argv = nullptr;
246     napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
247     ACCESSIBILITY_NAPI_ASSERT(env, argc == ARGS_SIZE_ZERO, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
248 
249     auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
250     ACCESSIBILITY_NAPI_ASSERT(env, asaClient != nullptr, OHOS::Accessibility::RET_ERR_NULLPTR);
251     std::string touchMode = "";
252     napi_value touchModeValue = nullptr;
253     asaClient->GetTouchMode(touchMode);
254     ACCESSIBILITY_NAPI_ASSERT(env, !touchMode.empty(), OHOS::Accessibility::RET_ERR_FAILED);
255     napi_create_string_utf8(env, touchMode.c_str(), NAPI_AUTO_LENGTH, &touchModeValue);
256     return touchModeValue;
257 }
258 
Completefunction(napi_env env,std::string type,void * data)259 void NAccessibilityClient::Completefunction(napi_env env, std::string type, void* data)
260 {
261     NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
262     napi_value result[ARGS_SIZE_TWO] = {0};
263     napi_value callback = 0;
264     napi_value undefined = 0;
265     napi_get_undefined(env, &undefined);
266 
267     if (type == "IsOpenAccessibility") {
268         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, callbackInfo->enabled_, &result[PARAM1]));
269         HILOG_INFO("IsOpenAccessibility completed enabled[%{public}d]", callbackInfo->enabled_);
270     } else if (type == "IsOpenTouchExploration") {
271         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, callbackInfo->touchEnabled_, &result[PARAM1]));
272         HILOG_INFO("IsOpenTouchExploration completed touchEnabled_[%{public}d]", callbackInfo->touchEnabled_);
273     } else {
274         napi_delete_async_work(env, callbackInfo->work_);
275         delete callbackInfo;
276         callbackInfo = nullptr;
277         return;
278     }
279     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
280     if (callbackInfo->callback_) {
281         napi_get_reference_value(env, callbackInfo->callback_, &callback);
282         napi_value returnVal = nullptr;
283         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
284         napi_delete_reference(env, callbackInfo->callback_);
285     } else {
286         if (callbackInfo->ret_ == OHOS::Accessibility::RET_OK) {
287             HILOG_DEBUG("Completefunction callbackInfo->ret_ is RET_OK");
288             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
289         } else {
290             HILOG_DEBUG("Completefunction callbackInfo->ret_ is not RET_OK");
291             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
292         }
293     }
294     napi_delete_async_work(env, callbackInfo->work_);
295     delete callbackInfo;
296     callbackInfo = nullptr;
297 }
298 
GetAbilityListExecute(napi_env env,void * data)299 void NAccessibilityClient::GetAbilityListExecute(napi_env env, void* data)
300 {
301     NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
302     auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
303     if (asaClient) {
304         callbackInfo->ret_ = asaClient->GetAbilityList(callbackInfo->abilityTypes_,
305             callbackInfo->stateTypes_, callbackInfo->abilityList_);
306     }
307 }
308 
GetAbilityListComplete(napi_env env,napi_status status,void * data)309 void NAccessibilityClient::GetAbilityListComplete(napi_env env, napi_status status, void* data)
310 {
311     NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
312     napi_value result[ARGS_SIZE_TWO] = {0};
313     napi_value callback = 0;
314     napi_value undefined = 0;
315     napi_get_undefined(env, &undefined);
316     napi_create_array(env, &result[PARAM1]);
317     ConvertAccessibleAbilityInfosToJS(env, result[PARAM1], callbackInfo->abilityList_);
318     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
319     if (callbackInfo->callback_) {
320         napi_get_reference_value(env, callbackInfo->callback_, &callback);
321         napi_value returnVal = nullptr;
322         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
323         napi_delete_reference(env, callbackInfo->callback_);
324     } else {
325         if (callbackInfo->ret_ == OHOS::Accessibility::RET_OK) {
326             HILOG_DEBUG("GetAbilityListComplete callbackInfo->ret_ is RET_OK");
327             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
328         } else {
329             HILOG_DEBUG("GetAbilityListComplete callbackInfo->ret_ is not RET_OK");
330             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
331         }
332     }
333     napi_delete_async_work(env, callbackInfo->work_);
334     delete callbackInfo;
335     callbackInfo = nullptr;
336 }
337 
GetAbilityList(napi_env env,napi_callback_info info)338 napi_value NAccessibilityClient::GetAbilityList(napi_env env, napi_callback_info info)
339 {
340 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
341     ApiReportHelper reporter("NAccessibilityClient.GetAbilityList");
342 #endif // ACCESSIBILITY_EMULATOR_DEFINED
343     NAccessibilitySystemAbilityClient* callbackInfo = new(std::nothrow) NAccessibilitySystemAbilityClient();
344     if (callbackInfo == nullptr) {
345         HILOG_ERROR("Failed to create callbackInfo.");
346         return nullptr;
347     }
348 
349     size_t argc = 3;
350     napi_value parameters[3] = {0};
351     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
352 
353     std::string abilityTypes = GetStringFromNAPI(env, parameters[0]);
354     std::string stateTypes = GetStringFromNAPI(env, parameters[1]);
355     HILOG_INFO("abilityTypes[%{public}s] stateTypes[%{public}s]", abilityTypes.c_str(), stateTypes.c_str());
356 
357     callbackInfo->abilityTypes_ = ConvertStringToAccessibilityAbilityTypes(abilityTypes);
358     callbackInfo->stateTypes_ = ConvertStringToAbilityStateType(stateTypes);
359 
360     napi_value promise = nullptr;
361 
362     if (argc > ARGS_SIZE_TWO && CheckJsFunction(env, parameters[ARGS_SIZE_TWO])) {
363         napi_create_reference(env, parameters[ARGS_SIZE_TWO], 1, &callbackInfo->callback_);
364         napi_get_undefined(env, &promise);
365     } else {
366         napi_create_promise(env, &callbackInfo->deferred_, &promise);
367     }
368     napi_value resource = nullptr;
369     napi_create_string_utf8(env, "GetAbilityList", NAPI_AUTO_LENGTH, &resource);
370 
371     auto ret = napi_create_async_work(env, nullptr, resource,
372         // Execute async to call c++ function
373         NAccessibilityClient::GetAbilityListExecute,
374         // Execute the complete function
375         NAccessibilityClient::GetAbilityListComplete,
376         reinterpret_cast<void*>(callbackInfo),
377         &callbackInfo->work_);
378     if (ret != napi_ok) {
379         delete callbackInfo;
380         callbackInfo = nullptr;
381         HILOG_ERROR("failed to create async work.");
382         return nullptr;
383     }
384     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
385     return promise;
386 }
387 
GetAccessibilityExtensionList(napi_env env,napi_callback_info info)388 napi_value NAccessibilityClient::GetAccessibilityExtensionList(napi_env env, napi_callback_info info)
389 {
390 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
391     ApiReportHelper reporter("NAccessibilityClient.GetAccessibilityExtensionList");
392 #endif // ACCESSIBILITY_EMULATOR_DEFINED
393     NAccessibilitySystemAbilityClient* callbackInfo = new(std::nothrow) NAccessibilitySystemAbilityClient();
394     if (callbackInfo == nullptr) {
395         HILOG_ERROR("Failed to create callbackInfo.");
396         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
397         napi_throw(env, err);
398         return nullptr;
399     }
400 
401     size_t argc = ARGS_SIZE_THREE;
402     napi_value parameters[ARGS_SIZE_THREE] = {0};
403     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
404 
405     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
406     do {
407         if (argc < ARGS_SIZE_THREE - 1) {
408             HILOG_ERROR("argc is invalid: %{public}zu", argc);
409             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
410             break;
411         }
412 
413         // parse ability type
414         std::string abilityTypes = "";
415         std::string stateTypes = "";
416         if (!ParseString(env, abilityTypes, parameters[PARAM0]) ||
417             !ParseString(env, stateTypes, parameters[PARAM1])) {
418             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
419             break;
420         }
421 
422         HILOG_INFO("abilityTypes = %{private}s", abilityTypes.c_str());
423         if (CheckAbilityType(abilityTypes)) {
424             callbackInfo->abilityTypes_ = ConvertStringToAccessibilityAbilityTypes(abilityTypes);
425         } else {
426             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
427             break;
428         }
429         // parse ability state
430         HILOG_INFO("stateTypes = %{private}s", stateTypes.c_str());
431         if (CheckStateType(stateTypes)) {
432             callbackInfo->stateTypes_ = ConvertStringToAbilityStateType(stateTypes);
433         } else {
434             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
435         }
436     } while (0);
437 
438     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
439         delete callbackInfo;
440         callbackInfo = nullptr;
441         napi_value err = CreateBusinessError(env, errCode);
442         HILOG_ERROR("invalid param");
443         napi_throw(env, err);
444         return nullptr;
445     }
446 
447     return GetAccessibilityExtensionListAsync(env, argc, parameters, callbackInfo);
448 }
449 
GetAccessibilityExtensionListAsync(napi_env env,size_t argc,napi_value * parameters,NAccessibilitySystemAbilityClient * callbackInfo)450 napi_value NAccessibilityClient::GetAccessibilityExtensionListAsync(
451     napi_env env, size_t argc, napi_value* parameters, NAccessibilitySystemAbilityClient* callbackInfo)
452 {
453     napi_value promise = nullptr;
454     if (argc > ARGS_SIZE_THREE - 1 && CheckJsFunction(env, parameters[PARAM2])) {
455         napi_create_reference(env, parameters[PARAM2], 1, &callbackInfo->callback_);
456         napi_get_undefined(env, &promise);
457     } else {
458         napi_create_promise(env, &callbackInfo->deferred_, &promise);
459     }
460     napi_value resource = nullptr;
461     napi_create_string_utf8(env, "GetAccessibilityExtensionList", NAPI_AUTO_LENGTH, &resource);
462 
463     auto ret = napi_create_async_work(env, nullptr, resource,
464         // Execute async to call c++ function
465         NAccessibilityClient::GetAbilityListExecute,
466         // Execute the complete function
467         NAccessibilityClient::GetAbilityListComplete,
468         reinterpret_cast<void*>(callbackInfo),
469         &callbackInfo->work_);
470     if (ret != napi_ok) {
471         delete callbackInfo;
472         callbackInfo = nullptr;
473         HILOG_ERROR("failed to create async work.");
474         return nullptr;
475     }
476     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
477     return promise;
478 }
479 
GetAccessibilityExtensionListSync(napi_env env,napi_callback_info info)480 napi_value NAccessibilityClient::GetAccessibilityExtensionListSync(napi_env env, napi_callback_info info)
481 {
482 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
483     ApiReportHelper reporter("NAccessibilityClient.GetAccessibilityExtensionListSync");
484 #endif // ACCESSIBILITY_EMULATOR_DEFINED
485     size_t argc = ARGS_SIZE_THREE;
486     napi_value parameters[ARGS_SIZE_THREE] = {0};
487     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
488 
489     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
490     OHOS::Accessibility::AbilityStateType stateTypes = OHOS::Accessibility::ABILITY_STATE_INVALID;
491     uint32_t abilityTypes = 0;
492 
493     do {
494         if (argc < ARGS_SIZE_THREE - 1) {
495             HILOG_ERROR("argc is invalid: %{public}zu", argc);
496             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
497             break;
498         }
499 
500         // parse ability type
501         std::string abilityTypeStr = "";
502         std::string stateTypeStr = "";
503         if (!ParseString(env, abilityTypeStr, parameters[PARAM0]) ||
504             !ParseString(env, stateTypeStr, parameters[PARAM1])) {
505             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
506             break;
507         }
508 
509         HILOG_DEBUG("abilityTypeStr = %{private}s", abilityTypeStr.c_str());
510         if (CheckAbilityType(abilityTypeStr)) {
511             abilityTypes = ConvertStringToAccessibilityAbilityTypes(abilityTypeStr);
512         } else {
513             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
514             break;
515         }
516 
517         // parse ability state
518         HILOG_DEBUG("stateTypeStr = %{private}s", stateTypeStr.c_str());
519         if (CheckStateType(stateTypeStr)) {
520             stateTypes = ConvertStringToAbilityStateType(stateTypeStr);
521         } else {
522             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
523         }
524     } while (0);
525 
526     std::vector<OHOS::Accessibility::AccessibilityAbilityInfo> abilityList {};
527     if (errCode == OHOS::Accessibility::RET_OK) {
528         auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
529         if (asaClient) {
530             errCode = asaClient->GetAbilityList(abilityTypes, stateTypes, abilityList);
531         }
532     }
533 
534     napi_value resultAbilityList = nullptr;
535     napi_create_array(env, &resultAbilityList);
536     ConvertAccessibleAbilityInfosToJS(env, resultAbilityList, abilityList);
537     return resultAbilityList;
538 }
539 
CheckAbilityType(const std::string & abilityType)540 bool NAccessibilityClient::CheckAbilityType(const std::string& abilityType)
541 {
542     if (std::strcmp(abilityType.c_str(), "audible") == 0 ||
543         std::strcmp(abilityType.c_str(), "generic") == 0 ||
544         std::strcmp(abilityType.c_str(), "haptic") == 0 ||
545         std::strcmp(abilityType.c_str(), "spoken") == 0 ||
546         std::strcmp(abilityType.c_str(), "visual") == 0 ||
547         std::strcmp(abilityType.c_str(), "all") == 0) {
548         return true;
549     } else {
550         return false;
551     }
552 }
553 
CheckStateType(const std::string & stateType)554 bool NAccessibilityClient::CheckStateType(const std::string& stateType)
555 {
556     if (std::strcmp(stateType.c_str(), "enable") == 0 ||
557         std::strcmp(stateType.c_str(), "disable") == 0 ||
558         std::strcmp(stateType.c_str(), "install") == 0) {
559         return true;
560     } else {
561         return false;
562     }
563 }
564 
SendEventExecute(napi_env env,void * data)565 void NAccessibilityClient::SendEventExecute(napi_env env, void* data)
566 {
567     NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
568     auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
569     if (callbackInfo->result_ && asaClient) {
570         callbackInfo->ret_ = asaClient->SendEvent(callbackInfo->eventInfo_);
571     }
572     HILOG_INFO("SendEvent result[%{public}d]", callbackInfo->ret_);
573 }
574 
SendEventComplete(napi_env env,napi_status status,void * data)575 void NAccessibilityClient::SendEventComplete(napi_env env, napi_status status, void* data)
576 {
577     NAccessibilitySystemAbilityClient* callbackInfo = static_cast<NAccessibilitySystemAbilityClient*>(data);
578     napi_value result[ARGS_SIZE_TWO] = {0};
579     napi_value callback = 0;
580     napi_value undefined = 0;
581     napi_value ret = 0;
582     napi_get_undefined(env, &undefined);
583     napi_get_undefined(env, &ret);
584     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
585     result[PARAM1] = ret;
586     if (callbackInfo->callback_) {
587         napi_get_reference_value(env, callbackInfo->callback_, &callback);
588         napi_value returnVal = nullptr;
589         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
590         napi_delete_reference(env, callbackInfo->callback_);
591     } else {
592         if (callbackInfo->ret_ == OHOS::Accessibility::RET_OK) {
593             HILOG_DEBUG("SendEventComplete callbackInfo->ret_ is RET_OK");
594             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
595         } else {
596             HILOG_DEBUG("SendEventComplete callbackInfo->ret_ is not RET_OK");
597             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
598         }
599     }
600     napi_delete_async_work(env, callbackInfo->work_);
601     delete callbackInfo;
602     callbackInfo = nullptr;
603 }
604 
SendEvent(napi_env env,napi_callback_info info)605 napi_value NAccessibilityClient::SendEvent(napi_env env, napi_callback_info info)
606 {
607 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
608     ApiReportHelper reporter("NAccessibilityClient.SendEvent", REPORTER_THRESHOLD_VALUE);
609 #endif // ACCESSIBILITY_EMULATOR_DEFINED
610     HILOG_INFO();
611     NAccessibilitySystemAbilityClient* callbackInfo = new(std::nothrow) NAccessibilitySystemAbilityClient();
612     if (callbackInfo == nullptr) {
613         HILOG_ERROR("Failed to create callbackInfo.");
614         return nullptr;
615     }
616 
617     size_t argc = ARGS_SIZE_TWO;
618     napi_value parameters[ARGS_SIZE_TWO] = {0};
619     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
620     callbackInfo->result_ = ConvertEventInfoJSToNAPI(env, parameters[0], callbackInfo->eventInfo_);
621 
622     napi_value promise = nullptr;
623 
624     if (argc > ARGS_SIZE_ONE && CheckJsFunction(env, parameters[1])) {
625         HILOG_DEBUG("SendEvent callback mode");
626         napi_create_reference(env, parameters[1], 1, &callbackInfo->callback_);
627     } else {
628         HILOG_DEBUG("SendEvent promise mode");
629         napi_create_promise(env, &callbackInfo->deferred_, &promise);
630     }
631     napi_value resource = nullptr;
632     napi_create_string_utf8(env, "SendEvent", NAPI_AUTO_LENGTH, &resource);
633 
634     auto ret = napi_create_async_work(env, nullptr, resource,
635         NAccessibilityClient::SendEventExecute,
636         NAccessibilityClient::SendEventComplete,
637         reinterpret_cast<void*>(callbackInfo),
638         &callbackInfo->work_);
639     if (ret != napi_ok) {
640         delete callbackInfo;
641         callbackInfo = nullptr;
642         HILOG_ERROR("failed to create async work.");
643         return nullptr;
644     }
645     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
646 
647     return promise;
648 }
649 
SendAccessibilityEvent(napi_env env,napi_callback_info info)650 napi_value NAccessibilityClient::SendAccessibilityEvent(napi_env env, napi_callback_info info)
651 {
652 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
653     ApiReportHelper reporter("NAccessibilityClient.SendAccessibilityEvent", REPORTER_THRESHOLD_VALUE);
654 #endif // ACCESSIBILITY_EMULATOR_DEFINED
655     HILOG_INFO();
656     NAccessibilitySystemAbilityClient* callbackInfo = new(std::nothrow) NAccessibilitySystemAbilityClient();
657     if (callbackInfo == nullptr) {
658         HILOG_ERROR("Failed to create callbackInfo.");
659         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_NULLPTR);
660         napi_throw(env, err);
661         return nullptr;
662     }
663 
664     size_t argc = ARGS_SIZE_TWO;
665     napi_value parameters[ARGS_SIZE_TWO] = {0};
666     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
667 
668     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
669     if (argc < ARGS_SIZE_TWO - 1) {
670         HILOG_ERROR("argc is invalid: %{public}zu", argc);
671         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
672     }
673 
674     if (errCode == OHOS::Accessibility::RET_OK) {
675         callbackInfo->result_ = ConvertEventInfoJSToNAPI(env, parameters[0], callbackInfo->eventInfo_);
676         if (!callbackInfo->result_) {
677             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
678         }
679     }
680 
681     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
682         delete callbackInfo;
683         callbackInfo = nullptr;
684         napi_value err = CreateBusinessError(env, errCode);
685         HILOG_ERROR("SendAccessibilityEvent invalid param");
686         napi_throw(env, err);
687         return nullptr;
688     }
689 
690     napi_value promise = nullptr;
691     if (argc > ARGS_SIZE_TWO - 1 && CheckJsFunction(env, parameters[PARAM1])) {
692         napi_create_reference(env, parameters[PARAM1], 1, &callbackInfo->callback_);
693         napi_get_undefined(env, &promise);
694     } else {
695         HILOG_DEBUG("SendEvent promise mode");
696         napi_create_promise(env, &callbackInfo->deferred_, &promise);
697     }
698     napi_value resource = nullptr;
699     napi_create_string_utf8(env, "SendAccessibilityEvent", NAPI_AUTO_LENGTH, &resource);
700 
701     napi_create_async_work(env, nullptr, resource,
702         NAccessibilityClient::SendEventExecute,
703         NAccessibilityClient::SendEventComplete,
704         reinterpret_cast<void*>(callbackInfo),
705         &callbackInfo->work_);
706     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
707 
708     return promise;
709 }
710 
SubscribeState(napi_env env,napi_callback_info info)711 napi_value NAccessibilityClient::SubscribeState(napi_env env, napi_callback_info info)
712 {
713     HILOG_INFO();
714 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
715     ApiReportHelper reporter("NAccessibilityClient.SubscribeState");
716 #endif // ACCESSIBILITY_EMULATOR_DEFINED
717     size_t argc = ARGS_SIZE_TWO;
718     napi_value args[ARGS_SIZE_TWO] = {0};
719     napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
720     if (status != napi_ok) {
721         HILOG_ERROR("SubscribeState Failed to get event type");
722         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
723         napi_throw(env, err);
724         return nullptr;
725     }
726 
727     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
728     if (argc < ARGS_SIZE_TWO) {
729         HILOG_ERROR("SubscribeState argc is invalid: %{public}zu", argc);
730         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
731     }
732     uint32_t type = AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED;
733     GetAccessibilityStateEventType(env, args, errCode, type);
734     if (errCode == OHOS::Accessibility::RET_OK) {
735         napi_valuetype valueType = napi_null;
736         napi_typeof(env, args[PARAM1], &valueType);
737         if (valueType != napi_function) {
738             HILOG_ERROR("args[PARAM1] format is wrong");
739             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
740         }
741     }
742 
743     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
744         napi_value err = CreateBusinessError(env, errCode);
745         HILOG_ERROR("SubscribeState invalid param");
746         napi_throw(env, err);
747         return nullptr;
748     }
749 
750     switch (type) {
751         case AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED:
752 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
753             reporter.setApiName("NAccessibilityClient.SubscribeState.accessibilityStateChange");
754 #endif // ACCESSIBILITY_EMULATOR_DEFINED
755             accessibilityStateListeners_->SubscribeObserver(env, args[PARAM1]);
756             break;
757         case AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED:
758 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
759             reporter.setApiName("NAccessibilityClient.SubscribeState.touchGuideStateChange");
760 #endif // ACCESSIBILITY_EMULATOR_DEFINED
761             touchGuideStateListeners_->SubscribeObserver(env, args[PARAM1]);
762             break;
763         case AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED:
764 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
765             reporter.setApiName("NAccessibilityClient.SubscribeState.screenReaderStateChange");
766 #endif // ACCESSIBILITY_EMULATOR_DEFINED
767             screenReaderStateListeners_->SubscribeObserver(env, args[PARAM1]);
768             break;
769         case AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED:
770 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
771             reporter.setApiName("NAccessibilityClient.SubscribeState.touchModeChange");
772 #endif // ACCESSIBILITY_EMULATOR_DEFINED
773             touchModeListeners_->SubscribeObserver(env, args[PARAM1]);
774             touchGuideStateListeners_->SubscribeObserver(env, args[PARAM1], false);
775             break;
776         default:
777             break;
778     }
779     return nullptr;
780 }
781 
GetAccessibilityStateEventType(napi_env env,napi_value * args,OHOS::Accessibility::RetError & errCode,uint32_t & type)782 void NAccessibilityClient::GetAccessibilityStateEventType(
783     napi_env env, napi_value* args, OHOS::Accessibility::RetError& errCode, uint32_t& type)
784 {
785     if (errCode == OHOS::Accessibility::RET_OK) {
786         std::string eventType = "";
787         if (!ParseString(env, eventType, args[PARAM0])) {
788             HILOG_ERROR("eventType type parse failed");
789             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
790         } else {
791             if (std::strcmp(eventType.c_str(), "accessibilityStateChange") == 0) {
792                 type = AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED;
793             } else if (std::strcmp(eventType.c_str(), "touchGuideStateChange") == 0) {
794                 type = AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED;
795             } else if (std::strcmp(eventType.c_str(), "screenReaderStateChange") == 0) {
796                 type = AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED;
797             } else if (std::strcmp(eventType.c_str(), "touchModeChange") == 0) {
798                 type = AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED;
799             } else {
800                 HILOG_ERROR("SubscribeState eventType[%{public}s] is error", eventType.c_str());
801                 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
802             }
803         }
804     }
805 }
806 
UnsubscribeState(napi_env env,napi_callback_info info)807 napi_value NAccessibilityClient::UnsubscribeState(napi_env env, napi_callback_info info)
808 {
809     HILOG_INFO();
810 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
811     ApiReportHelper reporter("NAccessibilityClient.UnsubscribeState");
812 #endif // ACCESSIBILITY_EMULATOR_DEFINED
813     size_t argc = ARGS_SIZE_TWO;
814     napi_value args[ARGS_SIZE_TWO] = {0};
815     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
816 
817     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
818     if (argc < ARGS_SIZE_TWO - 1) {
819         HILOG_ERROR("UnsubscribeState argc is invalid: %{public}zu", argc);
820         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
821     }
822 
823     uint32_t type = AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED;
824     GetAccessibilityStateEventType(env, args, errCode, type);
825 
826     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
827         napi_value err = CreateBusinessError(env, errCode);
828         HILOG_ERROR("invalid param");
829         napi_throw(env, err);
830         return nullptr;
831     }
832     switch (type) {
833         case AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED:
834 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
835             reporter.setApiName("NAccessibilityClient.UnsubscribeState.accessibilityStateChange");
836 #endif // ACCESSIBILITY_EMULATOR_DEFINED
837             if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, args[PARAM1])) {
838                 accessibilityStateListeners_->UnsubscribeObserver(env, args[PARAM1]);
839             } else {
840                 accessibilityStateListeners_->UnsubscribeObservers();
841             }
842             break;
843         case AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED:
844 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
845             reporter.setApiName("NAccessibilityClient.UnsubscribeState.touchGuideStateChange");
846 #endif // ACCESSIBILITY_EMULATOR_DEFINED
847             if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, args[PARAM1])) {
848                 touchGuideStateListeners_->UnsubscribeObserver(env, args[PARAM1]);
849             } else {
850                 touchGuideStateListeners_->UnsubscribeObservers();
851             }
852             break;
853         case AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED:
854 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
855             reporter.setApiName("NAccessibilityClient.UnsubscribeState.screenReaderStateChange");
856 #endif // ACCESSIBILITY_EMULATOR_DEFINED
857             if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, args[PARAM1])) {
858                 screenReaderStateListeners_->UnsubscribeObserver(env, args[PARAM1]);
859             } else {
860                 screenReaderStateListeners_->UnsubscribeObservers();
861             }
862             break;
863         case AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED:
864 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
865             reporter.setApiName("NAccessibilityClient.UnsubscribeState.touchModeChange");
866 #endif // ACCESSIBILITY_EMULATOR_DEFINED
867             if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, args[PARAM1])) {
868                 touchModeListeners_->UnsubscribeObserver(env, args[PARAM1]);
869                 touchGuideStateListeners_->UnsubscribeObserver(env, args[PARAM1]);
870             } else {
871                 touchModeListeners_->UnsubscribeObservers();
872                 touchGuideStateListeners_->UnsubscribeObservers();
873             }
874             break;
875         default:
876             break;
877     }
878 
879     return nullptr;
880 }
881 
NotifyJS(napi_env env,bool state,napi_ref handlerRef)882 void StateListener::NotifyJS(napi_env env, bool state, napi_ref handlerRef)
883 {
884     HILOG_INFO("state = [%{public}s]", state ? "true" : "false");
885 
886     std::shared_ptr<StateCallbackInfo> callbackInfo = std::make_shared<StateCallbackInfo>();
887     if (callbackInfo == nullptr) {
888         HILOG_ERROR("Failed to create callbackInfo");
889         return;
890     }
891     callbackInfo->state_ = state;
892     callbackInfo->env_ = env;
893     callbackInfo->ref_ = handlerRef;
894     auto task = [callbackInfo]() {
895         if (callbackInfo == nullptr) {
896             return;
897         }
898 
899         napi_env tmpEnv = callbackInfo->env_;
900         auto closeScope = [tmpEnv](napi_handle_scope scope) {
901             napi_close_handle_scope(tmpEnv, scope);
902         };
903         std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(
904             OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
905         napi_value handler = nullptr;
906         napi_value callResult = nullptr;
907         napi_value jsEvent = nullptr;
908         napi_get_boolean(callbackInfo->env_, callbackInfo->state_, &jsEvent);
909         napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
910         napi_value undefined = nullptr;
911         napi_get_undefined(callbackInfo->env_, &undefined);
912         napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
913     };
914     if (napi_send_event(env, task, napi_eprio_high) != napi_status::napi_ok) {
915         HILOG_ERROR("failed to send event");
916     }
917 }
918 
NotifyJS(napi_env env,std::string mode,napi_ref handlerRef)919 void StateListener::NotifyJS(napi_env env, std::string mode, napi_ref handlerRef)
920 {
921     HILOG_INFO("mode = [%{public}s]", mode.c_str());
922 
923     std::shared_ptr<StateCallbackInfo> callbackInfo = std::make_shared<StateCallbackInfo>();
924     if (callbackInfo == nullptr) {
925         HILOG_ERROR("Failed to create callbackInfo");
926         return;
927     }
928     callbackInfo->stringValue_ = mode;
929     callbackInfo->env_ = env;
930     callbackInfo->ref_ = handlerRef;
931     auto task = [callbackInfo]() {
932         if (callbackInfo == nullptr) {
933             return;
934         }
935 
936         napi_env tmpEnv = callbackInfo->env_;
937         auto closeScope = [tmpEnv](napi_handle_scope scope) {
938             napi_close_handle_scope(tmpEnv, scope);
939         };
940         std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(
941             OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
942         napi_value handler = nullptr;
943         napi_value callResult = nullptr;
944         napi_value jsEvent = nullptr;
945         napi_create_string_utf8(callbackInfo->env_, callbackInfo->stringValue_.c_str(), NAPI_AUTO_LENGTH, &jsEvent);
946         napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
947         napi_value undefined = nullptr;
948         napi_get_undefined(callbackInfo->env_, &undefined);
949         napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
950     };
951     if (napi_send_event(env, task, napi_eprio_high) != napi_status::napi_ok) {
952         HILOG_ERROR("failed to send event");
953     }
954 }
955 
OnStateChanged(const bool state)956 void StateListener::OnStateChanged(const bool state)
957 {
958     NotifyJS(env_, state, handlerRef_);
959 }
960 
OnStateChanged(const std::string mode)961 void StateListener::OnStateChanged(const std::string mode)
962 {
963     NotifyJS(env_, mode, handlerRef_);
964 }
965 
DefineJSCaptionsManager(napi_env env)966 void NAccessibilityClient::DefineJSCaptionsManager(napi_env env)
967 {
968     napi_property_descriptor captionsManagerDesc[] = {
969         DECLARE_NAPI_GETTER_SETTER("enabled",
970             NAccessibilityClient::GetCaptionStateEnabled, NAccessibilityClient::SetCaptionStateEnabled),
971         DECLARE_NAPI_GETTER_SETTER("style",
972             NAccessibilityClient::GetCaptionStyle, NAccessibilityClient::SetCaptionStyle),
973         DECLARE_NAPI_FUNCTION("on", NAccessibilityClient::RegisterCaptionStateCallback),
974         DECLARE_NAPI_FUNCTION("off", NAccessibilityClient::DeregisterCaptionStateCallback),
975     };
976 
977     napi_value aaCons = nullptr;
978     NAPI_CALL_RETURN_VOID(env,
979         napi_define_class(env,
980             "CaptionsManager",
981             NAPI_AUTO_LENGTH,
982             NAccessibilityClient::AccessibleAbilityConstructor,
983             nullptr,
984             sizeof(captionsManagerDesc) / sizeof(captionsManagerDesc[0]),
985             captionsManagerDesc,
986             &aaCons));
987 
988     napi_create_reference(env, aaCons, 1, &NAccessibilityClient::aaConsRef_);
989 }
990 
AccessibleAbilityConstructor(napi_env env,napi_callback_info info)991 napi_value NAccessibilityClient::AccessibleAbilityConstructor(napi_env env, napi_callback_info info)
992 {
993     napi_value jsthis = nullptr;
994     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
995     return jsthis;
996 }
997 
998 
GetCaptionsManager(napi_env env,napi_callback_info info)999 napi_value NAccessibilityClient::GetCaptionsManager(napi_env env, napi_callback_info info)
1000 {
1001     HILOG_INFO();
1002 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1003     ApiReportHelper reporter("NAccessibilityClient.GetCaptionsManager");
1004 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1005     napi_value result = 0;
1006     napi_value aaCons = nullptr;
1007     napi_get_reference_value(env, NAccessibilityClient::aaConsRef_, &aaCons);
1008     napi_new_instance(env, aaCons, 0, nullptr, &result);
1009     return result;
1010 }
1011 
SetCaptionStateEnabled(napi_env env,napi_callback_info info)1012 napi_value NAccessibilityClient::SetCaptionStateEnabled(napi_env env, napi_callback_info info)
1013 {
1014     HILOG_INFO();
1015     size_t argc = ARGS_SIZE_ONE;
1016     napi_value parameters[ARGS_SIZE_ONE] = {0};
1017     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1018     if (argc >= ARGS_SIZE_ONE) {
1019         bool captionState = false;
1020         OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1021         if (!ParseBool(env, captionState, parameters[PARAM0])) {
1022             ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1023         } else {
1024             HILOG_INFO("captionState = %{public}s", captionState ? "True" : "False");
1025 
1026             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1027             ret = instance.SetCaptionsState(captionState);
1028         }
1029         if (ret != OHOS::Accessibility::RET_OK) {
1030             napi_value err = CreateBusinessError(env, ret);
1031             napi_throw(env, err);
1032         }
1033     } else {
1034         HILOG_ERROR("SetCaptionStateEnabled argc size Error");
1035         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1036         napi_throw(env, err);
1037     }
1038 
1039     napi_value undefined = nullptr;
1040     napi_get_undefined(env, &undefined);
1041     return undefined;
1042 }
1043 
GetCaptionStateEnabled(napi_env env,napi_callback_info info)1044 napi_value NAccessibilityClient::GetCaptionStateEnabled(napi_env env, napi_callback_info info)
1045 {
1046     HILOG_INFO();
1047     napi_value captionStateEnabled = nullptr;
1048 
1049     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1050     bool captionState = false;
1051     instance.GetCaptionsState(captionState);
1052     napi_get_boolean(env, captionState, &captionStateEnabled);
1053 
1054     HILOG_INFO("captionState = %{public}s", captionState ? "True" : "False");
1055 
1056     return captionStateEnabled;
1057 }
1058 
SetCaptionStyle(napi_env env,napi_callback_info info)1059 napi_value NAccessibilityClient::SetCaptionStyle(napi_env env, napi_callback_info info)
1060 {
1061     HILOG_INFO();
1062     size_t argc = ARGS_SIZE_ONE;
1063     napi_value parameters[ARGS_SIZE_ONE] = {0};
1064     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1065     if (argc >= ARGS_SIZE_ONE) {
1066         OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1067         OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1068         if (!ConvertObjToCaptionProperty(env, parameters[PARAM0], &captionProperty)) {
1069             ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1070         } else {
1071             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1072             ret = instance.SetCaptionsProperty(captionProperty);
1073         }
1074         if (ret != OHOS::Accessibility::RET_OK) {
1075             napi_value err = CreateBusinessError(env, ret);
1076             napi_throw(env, err);
1077         }
1078     } else {
1079         HILOG_ERROR("SetCaptionStyle argc size Error");
1080         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1081         napi_throw(env, err);
1082     }
1083 
1084     napi_value undefined = nullptr;
1085     napi_get_undefined(env, &undefined);
1086     return undefined;
1087 }
1088 
GetCaptionStyle(napi_env env,napi_callback_info info)1089 napi_value NAccessibilityClient::GetCaptionStyle(napi_env env, napi_callback_info info)
1090 {
1091     HILOG_INFO();
1092     napi_value captionStyle = nullptr;
1093     napi_get_reference_value(env, NAccessibilityClient::aaStyleConsRef_, &captionStyle);
1094 
1095     return captionStyle;
1096 }
1097 
RegisterCaptionStateCallback(napi_env env,napi_callback_info info)1098 napi_value NAccessibilityClient::RegisterCaptionStateCallback(napi_env env, napi_callback_info info)
1099 {
1100     HILOG_INFO();
1101 
1102     size_t argc = ARGS_SIZE_TWO;
1103     napi_value args[ARGS_SIZE_TWO] = {0};
1104     napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1105     if (status != napi_ok) {
1106         HILOG_ERROR("RegisterCaptionStateCallback Failed to get event type");
1107         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
1108         napi_throw(env, err);
1109         return nullptr;
1110     }
1111 
1112     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
1113     if (argc < ARGS_SIZE_TWO) {
1114         HILOG_ERROR("RegisterCaptionStateCallback argc is invalid: %{public}zu", argc);
1115         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1116     }
1117 
1118     OHOS::AccessibilityConfig::CONFIG_ID type = OHOS::AccessibilityConfig::CONFIG_ID_MAX;
1119     if (errCode == OHOS::Accessibility::RET_OK) {
1120         std::string eventType = "";
1121         if (!ParseString(env, eventType, args[PARAM0])) {
1122             HILOG_ERROR("eventType type parse failed");
1123             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1124         } else {
1125             if (std::strcmp(eventType.c_str(), "enableChange") == 0) {
1126                 type = OHOS::AccessibilityConfig::CONFIG_CAPTION_STATE;
1127             } else if (std::strcmp(eventType.c_str(), "styleChange") == 0) {
1128                 type =  OHOS::AccessibilityConfig::CONFIG_CAPTION_STYLE;
1129             } else {
1130                 HILOG_ERROR("SubscribeState eventType[%{public}s] is error", eventType.c_str());
1131                 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1132             }
1133         }
1134     }
1135 
1136     if (errCode == OHOS::Accessibility::RET_OK) {
1137         napi_valuetype valueType = napi_null;
1138         napi_typeof(env, args[PARAM1], &valueType);
1139         if (valueType != napi_function) {
1140             HILOG_ERROR("RegisterCaptionStateCallback args[PARAM1] format is wrong");
1141             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1142         }
1143     }
1144 
1145     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
1146         napi_value err = CreateBusinessError(env, errCode);
1147         HILOG_ERROR("invalid param");
1148         napi_throw(env, err);
1149         return nullptr;
1150     }
1151 
1152     captionListeners_->SubscribeObserver(env, type, args[PARAM1]);
1153 
1154     return nullptr;
1155 }
1156 
DeregisterCaptionStateCallback(napi_env env,napi_callback_info info)1157 napi_value NAccessibilityClient::DeregisterCaptionStateCallback(napi_env env, napi_callback_info info)
1158 {
1159     HILOG_INFO();
1160     size_t argc = ARGS_SIZE_TWO;
1161     napi_value args[ARGS_SIZE_TWO] = {0};
1162     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1163 
1164     OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
1165     if (argc < ARGS_SIZE_TWO - 1) {
1166         HILOG_ERROR("DeregisterCaptionStateCallback argc is invalid: %{public}zu", argc);
1167         errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1168     }
1169 
1170     OHOS::AccessibilityConfig::CONFIG_ID type = OHOS::AccessibilityConfig::CONFIG_ID_MAX;
1171     if (errCode == OHOS::Accessibility::RET_OK) {
1172         std::string eventType = "";
1173         if (!ParseString(env, eventType, args[PARAM0])) {
1174             HILOG_ERROR("eventType type parse failed");
1175             errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1176         } else {
1177             if (std::strcmp(eventType.c_str(), "enableChange") == 0) {
1178                 type = OHOS::AccessibilityConfig::CONFIG_CAPTION_STATE;
1179             } else if (std::strcmp(eventType.c_str(), "styleChange") == 0) {
1180                 type =  OHOS::AccessibilityConfig::CONFIG_CAPTION_STYLE;
1181             } else {
1182                 HILOG_ERROR("SubscribeState eventType[%{public}s] is error", eventType.c_str());
1183                 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1184             }
1185         }
1186     }
1187 
1188     if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
1189         napi_value err = CreateBusinessError(env, errCode);
1190         HILOG_ERROR("DeregisterCaptionStateCallback invalid param");
1191         napi_throw(env, err);
1192         return nullptr;
1193     }
1194 
1195     if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, args[PARAM1])) {
1196         captionListeners_->UnsubscribeObserver(env, type, args[PARAM1]);
1197     } else {
1198         captionListeners_->UnsubscribeObservers(type);
1199     }
1200 
1201     return nullptr;
1202 }
1203 
DefineJSCaptionsStyle(napi_env env)1204 void NAccessibilityClient::DefineJSCaptionsStyle(napi_env env)
1205 {
1206     napi_property_descriptor captionsStyleDesc[] = {
1207         DECLARE_NAPI_GETTER_SETTER("fontFamily",
1208             NAccessibilityClient::GetCaptionsFontFamily, NAccessibilityClient::SetCaptionsFontFamily),
1209         DECLARE_NAPI_GETTER_SETTER("fontScale",
1210             NAccessibilityClient::GetCaptionsFontScale, NAccessibilityClient::SetCaptionsFontScale),
1211         DECLARE_NAPI_GETTER_SETTER("fontColor",
1212             NAccessibilityClient::GetCaptionFrontColor, NAccessibilityClient::SetCaptionFrontColor),
1213         DECLARE_NAPI_GETTER_SETTER("fontEdgeType",
1214             NAccessibilityClient::GetCaptionFontEdgeType, NAccessibilityClient::SetCaptionFontEdgeType),
1215         DECLARE_NAPI_GETTER_SETTER("backgroundColor",
1216             NAccessibilityClient::GetCaptionBackgroundColor, NAccessibilityClient::SetCaptionBackgroundColor),
1217         DECLARE_NAPI_GETTER_SETTER("windowColor",
1218             NAccessibilityClient::GetCaptionWindowColor, NAccessibilityClient::SetCaptionWindowColor),
1219     };
1220 
1221     napi_value aaStyleCons = nullptr;
1222     napi_value captionStyle = nullptr;
1223 
1224     NAPI_CALL_RETURN_VOID(env,
1225         napi_define_class(env,
1226             "CaptionsStyle",
1227             NAPI_AUTO_LENGTH,
1228             NAccessibilityClient::AccessibleAbilityConstructorStyle,
1229             nullptr,
1230             sizeof(captionsStyleDesc) / sizeof(captionsStyleDesc[0]),
1231             captionsStyleDesc,
1232             &aaStyleCons));
1233 
1234     napi_new_instance(env, aaStyleCons, 0, nullptr, &captionStyle);
1235     napi_create_reference(env, captionStyle, 1, &NAccessibilityClient::aaStyleConsRef_);
1236 }
1237 
AccessibleAbilityConstructorStyle(napi_env env,napi_callback_info info)1238 napi_value NAccessibilityClient::AccessibleAbilityConstructorStyle(napi_env env, napi_callback_info info)
1239 {
1240     HILOG_INFO();
1241     napi_value jsthis = nullptr;
1242     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
1243     return jsthis;
1244 }
1245 
GetCaptionsFontFamily(napi_env env,napi_callback_info info)1246 napi_value NAccessibilityClient::GetCaptionsFontFamily(napi_env env, napi_callback_info info)
1247 {
1248     HILOG_INFO();
1249     napi_value returnValue = nullptr;
1250     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1251     OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1252     instance.GetCaptionsProperty(captionProperty);
1253     napi_create_string_utf8(env, captionProperty.GetFontFamily().c_str(), NAPI_AUTO_LENGTH, &returnValue);
1254     return returnValue;
1255 }
1256 
SetCaptionsFontFamily(napi_env env,napi_callback_info info)1257 napi_value NAccessibilityClient::SetCaptionsFontFamily(napi_env env, napi_callback_info info)
1258 {
1259     HILOG_INFO();
1260     size_t argc = ARGS_SIZE_ONE;
1261     napi_value parameters[ARGS_SIZE_ONE] = {0};
1262     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1263     if (argc >= ARGS_SIZE_ONE) {
1264         // Get input FontFamily
1265         std::string fontFamily = "";
1266         OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1267         if (ParseString(env, fontFamily, parameters[PARAM0]) && fontFamily.length() > 0) {
1268             HILOG_INFO("FontFamily = %{public}s", fontFamily.c_str());
1269             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1270             OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1271             instance.GetCaptionsProperty(captionProperty);
1272             // Change the input info and then set the CaptionProperty
1273             captionProperty.SetFontFamily(std::string(fontFamily));
1274             ret = instance.SetCaptionsProperty(captionProperty);
1275         } else {
1276             ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1277         }
1278         if (ret != OHOS::Accessibility::RET_OK) {
1279             napi_value err = CreateBusinessError(env, ret);
1280             napi_throw(env, err);
1281         }
1282     } else {
1283         HILOG_ERROR("SetCaptionsFontFamily argc size Error");
1284         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1285         napi_throw(env, err);
1286     }
1287     napi_value undefined = nullptr;
1288     napi_get_undefined(env, &undefined);
1289     return undefined;
1290 }
1291 
GetCaptionsFontScale(napi_env env,napi_callback_info info)1292 napi_value NAccessibilityClient::GetCaptionsFontScale(napi_env env, napi_callback_info info)
1293 {
1294     HILOG_INFO();
1295     napi_value returnValue = nullptr;
1296     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1297     OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1298     instance.GetCaptionsProperty(captionProperty);
1299     napi_create_int32(env, captionProperty.GetFontScale(), &returnValue);
1300     return returnValue;
1301 }
1302 
SetCaptionsFontScale(napi_env env,napi_callback_info info)1303 napi_value NAccessibilityClient::SetCaptionsFontScale(napi_env env, napi_callback_info info)
1304 {
1305     HILOG_INFO();
1306     size_t argc = ARGS_SIZE_ONE;
1307     napi_value parameters[ARGS_SIZE_ONE] = {0};
1308     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1309     if (argc >= ARGS_SIZE_ONE) {
1310         // Get input FontScale
1311         int32_t num = 100;
1312         OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1313         if (ParseInt32(env, num, parameters[PARAM0])) {
1314             HILOG_INFO("FontScale = %{public}d", num);
1315             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1316             OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1317             instance.GetCaptionsProperty(captionProperty);
1318             // Change the input info and then set the CaptionProperty
1319             captionProperty.SetFontScale(num);
1320             ret = instance.SetCaptionsProperty(captionProperty);
1321         } else {
1322             ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1323         }
1324         if (ret != OHOS::Accessibility::RET_OK) {
1325             napi_value err = CreateBusinessError(env, ret);
1326             napi_throw(env, err);
1327         }
1328     } else {
1329         HILOG_ERROR("SetCaptionsFontScale argc size Error");
1330         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1331         napi_throw(env, err);
1332     }
1333     napi_value undefined = nullptr;
1334     napi_get_undefined(env, &undefined);
1335     return undefined;
1336 }
1337 
GetCaptionFrontColor(napi_env env,napi_callback_info info)1338 napi_value NAccessibilityClient::GetCaptionFrontColor(napi_env env, napi_callback_info info)
1339 {
1340     HILOG_INFO();
1341     napi_value returnValue = nullptr;
1342     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1343     OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1344     instance.GetCaptionsProperty(captionProperty);
1345     uint32_t color = captionProperty.GetFontColor();
1346     std::string colorStr = ConvertColorToString(color);
1347     napi_create_string_utf8(env, colorStr.c_str(), NAPI_AUTO_LENGTH, &returnValue);
1348     return returnValue;
1349 }
1350 
SetCaptionFrontColor(napi_env env,napi_callback_info info)1351 napi_value NAccessibilityClient::SetCaptionFrontColor(napi_env env, napi_callback_info info)
1352 {
1353     HILOG_INFO();
1354     size_t argc = ARGS_SIZE_ONE;
1355     napi_value parameters[ARGS_SIZE_ONE] = {0};
1356     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1357     if (argc >= ARGS_SIZE_ONE) {
1358         HILOG_DEBUG("SetCaptionFrontColor argc > 1");
1359         uint32_t color = GetColorValue(env, parameters[PARAM0]);
1360         auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1361         OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1362         instance.GetCaptionsProperty(captionProperty);
1363         // Change the input info and then set the CaptionProperty
1364         captionProperty.SetFontColor(color);
1365         OHOS::Accessibility::RetError ret = instance.SetCaptionsProperty(captionProperty);
1366         if (ret != OHOS::Accessibility::RET_OK) {
1367             napi_value err = CreateBusinessError(env, ret);
1368             napi_throw(env, err);
1369         }
1370     } else {
1371         HILOG_ERROR("SetCaptionFrontColor argc size Error");
1372         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1373         napi_throw(env, err);
1374     }
1375     napi_value undefined = nullptr;
1376     napi_get_undefined(env, &undefined);
1377     return undefined;
1378 }
1379 
GetCaptionFontEdgeType(napi_env env,napi_callback_info info)1380 napi_value NAccessibilityClient::GetCaptionFontEdgeType(napi_env env, napi_callback_info info)
1381 {
1382     HILOG_INFO();
1383     napi_value returnValue = nullptr;
1384     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1385     OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1386     instance.GetCaptionsProperty(captionProperty);
1387     napi_create_string_utf8(env, captionProperty.GetFontEdgeType().c_str(), NAPI_AUTO_LENGTH, &returnValue);
1388     return returnValue;
1389 }
1390 
SetCaptionFontEdgeType(napi_env env,napi_callback_info info)1391 napi_value NAccessibilityClient::SetCaptionFontEdgeType(napi_env env, napi_callback_info info)
1392 {
1393     HILOG_INFO();
1394     size_t argc = ARGS_SIZE_ONE;
1395     napi_value parameters[ARGS_SIZE_ONE] = {0};
1396 
1397     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1398     if (argc >= ARGS_SIZE_ONE) {
1399         // Get input FontEdgeType
1400         std::string fontEdgeType = "";
1401         OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1402         if (ParseString(env, fontEdgeType, parameters[PARAM0]) && fontEdgeType.length() > 0) {
1403             HILOG_INFO("fontEdgeType = %{public}s", fontEdgeType.c_str());
1404             auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1405             OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1406             instance.GetCaptionsProperty(captionProperty);
1407             // Change the input info and then set the CaptionProperty
1408             captionProperty.SetFontEdgeType(std::string(fontEdgeType));
1409             ret = instance.SetCaptionsProperty(captionProperty);
1410         } else {
1411             ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1412         }
1413         if (ret != OHOS::Accessibility::RET_OK) {
1414             napi_value err = CreateBusinessError(env, ret);
1415             napi_throw(env, err);
1416         }
1417     } else {
1418         HILOG_ERROR("SetCaptionFontEdgeType argc size Error");
1419         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1420         napi_throw(env, err);
1421     }
1422     napi_value undefined = nullptr;
1423     napi_get_undefined(env, &undefined);
1424     return undefined;
1425 }
1426 
GetCaptionBackgroundColor(napi_env env,napi_callback_info info)1427 napi_value NAccessibilityClient::GetCaptionBackgroundColor(napi_env env, napi_callback_info info)
1428 {
1429     HILOG_INFO();
1430     napi_value returnValue = nullptr;
1431     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1432     OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1433     instance.GetCaptionsProperty(captionProperty);
1434     uint32_t color = captionProperty.GetBackgroundColor();
1435     std::string colorStr = ConvertColorToString(color);
1436     napi_create_string_utf8(env, colorStr.c_str(), NAPI_AUTO_LENGTH, &returnValue);
1437     return returnValue;
1438 }
1439 
SetCaptionBackgroundColor(napi_env env,napi_callback_info info)1440 napi_value NAccessibilityClient::SetCaptionBackgroundColor(napi_env env, napi_callback_info info)
1441 {
1442     HILOG_INFO();
1443     size_t argc = ARGS_SIZE_ONE;
1444     napi_value parameters[ARGS_SIZE_ONE] = {0};
1445     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1446     if (argc >= ARGS_SIZE_ONE) {
1447         HILOG_DEBUG("SetCaptionBackgroundColor argc > 1");
1448         uint32_t color = GetColorValue(env, parameters[PARAM0]);
1449         auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1450         OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1451         instance.GetCaptionsProperty(captionProperty);
1452         // Change the input info and then set the CaptionProperty
1453         captionProperty.SetBackgroundColor(color);
1454         OHOS::Accessibility::RetError ret = instance.SetCaptionsProperty(captionProperty);
1455         if (ret != OHOS::Accessibility::RET_OK) {
1456             napi_value err = CreateBusinessError(env, ret);
1457             napi_throw(env, err);
1458         }
1459     } else {
1460         HILOG_ERROR("SetCaptionBackgroundColor argc size Error");
1461         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1462         napi_throw(env, err);
1463     }
1464     napi_value undefined = nullptr;
1465     napi_get_undefined(env, &undefined);
1466     return undefined;
1467 }
1468 
GetCaptionWindowColor(napi_env env,napi_callback_info info)1469 napi_value NAccessibilityClient::GetCaptionWindowColor(napi_env env, napi_callback_info info)
1470 {
1471     HILOG_INFO();
1472     napi_value returnValue = nullptr;
1473     auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1474     OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1475     instance.GetCaptionsProperty(captionProperty);
1476     uint32_t color = captionProperty.GetWindowColor();
1477     std::string colorStr = ConvertColorToString(color);
1478     napi_create_string_utf8(env, colorStr.c_str(), NAPI_AUTO_LENGTH, &returnValue);
1479     return returnValue;
1480 }
1481 
SetCaptionWindowColor(napi_env env,napi_callback_info info)1482 napi_value NAccessibilityClient::SetCaptionWindowColor(napi_env env, napi_callback_info info)
1483 {
1484     HILOG_INFO();
1485     size_t argc = ARGS_SIZE_ONE;
1486     napi_value parameters[ARGS_SIZE_ONE] = {0};
1487     napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1488     if (argc >= ARGS_SIZE_ONE) {
1489         HILOG_DEBUG("SetCaptionWindowColor argc > 1");
1490         uint32_t color = GetColorValue(env, parameters[PARAM0]);
1491         auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1492         OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1493         instance.GetCaptionsProperty(captionProperty);
1494         // Change the input info and then set the CaptionProperty
1495         captionProperty.SetWindowColor(color);
1496         OHOS::Accessibility::RetError ret = instance.SetCaptionsProperty(captionProperty);
1497         if (ret != OHOS::Accessibility::RET_OK) {
1498             napi_value err = CreateBusinessError(env, ret);
1499             napi_throw(env, err);
1500         }
1501     } else {
1502         HILOG_ERROR("SetCaptionWindowColor argc size Error");
1503         napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1504         napi_throw(env, err);
1505     }
1506     napi_value undefined = nullptr;
1507     napi_get_undefined(env, &undefined);
1508     return undefined;
1509 }
1510 
SubscribeToFramework()1511 void StateListenerImpl::SubscribeToFramework()
1512 {
1513     auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
1514     if (asaClient) {
1515         asaClient->SubscribeStateObserver(shared_from_this(), type_);
1516     }
1517 }
1518 
UnsubscribeFromFramework()1519 void StateListenerImpl::UnsubscribeFromFramework()
1520 {
1521     HILOG_INFO("UnsubscribeFromFramework");
1522     auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
1523     if (asaClient) {
1524         asaClient->UnsubscribeStateObserver(shared_from_this(), type_);
1525     }
1526 }
1527 
OnStateChanged(const bool state)1528 void StateListenerImpl::OnStateChanged(const bool state)
1529 {
1530     HILOG_INFO();
1531     std::lock_guard<ffrt::mutex> lock(mutex_);
1532     std::string touchMode = "";
1533     if (type_ == AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED) {
1534         for (auto &observer : observers_) {
1535             touchMode = state ? "singleTouchMode" : "doubleTouchMode";
1536             observer->OnStateChanged(touchMode);
1537         }
1538         return;
1539     }
1540 
1541     for (auto &observer : observers_) {
1542         if (observer->isBoolObserver_) {
1543             observer->OnStateChanged(state);
1544         } else if (!state) {
1545             // notify the touch mode change
1546             touchMode = "none";
1547             observer->OnStateChanged(touchMode);
1548         }
1549     }
1550 }
1551 
DeleteObserverReference(napi_env env,std::shared_ptr<StateListener> observer)1552 void StateListenerImpl::DeleteObserverReference(napi_env env, std::shared_ptr<StateListener> observer)
1553 {
1554     if (observer == nullptr) {
1555         return;
1556     }
1557     std::shared_ptr<AccessibilityCallbackInfo> callbackInfo =
1558         std::make_shared<AccessibilityCallbackInfo>();
1559     if (callbackInfo == nullptr) {
1560         HILOG_ERROR("failed to create callbackInfo");
1561         return;
1562     }
1563     callbackInfo->env_ = observer->env_;
1564     callbackInfo->ref_ = observer->handlerRef_;
1565     auto task = [callbackInfo]() {
1566         if (callbackInfo == nullptr) {
1567             return;
1568         }
1569         napi_env tmpEnv = callbackInfo->env_;
1570         auto closeScope = [tmpEnv](napi_handle_scope scope) {
1571             napi_close_handle_scope(tmpEnv, scope);
1572         };
1573         std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(
1574             OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
1575         napi_delete_reference(tmpEnv, callbackInfo->ref_);
1576     };
1577     if (napi_send_event(env, task, napi_eprio_high) != napi_status::napi_ok) {
1578         HILOG_ERROR("failed to send event");
1579     }
1580 }
1581 
SubscribeObserver(napi_env env,napi_value observer,bool isBoolObserver)1582 void StateListenerImpl::SubscribeObserver(napi_env env, napi_value observer, bool isBoolObserver)
1583 {
1584     HILOG_INFO();
1585     std::lock_guard<ffrt::mutex> lock(mutex_);
1586     for (auto iter = observers_.begin(); iter != observers_.end();) {
1587         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) {
1588             HILOG_DEBUG("SubscribeObserver Observer exist");
1589             return;
1590         } else {
1591             iter++;
1592         }
1593     }
1594 
1595     napi_ref ref;
1596     napi_create_reference(env, observer, 1, &ref);
1597     std::shared_ptr<StateListener> stateListener = std::make_shared<StateListener>(env, ref, isBoolObserver);
1598 
1599     observers_.emplace_back(stateListener);
1600     HILOG_INFO("observer size%{public}zu", observers_.size());
1601 }
1602 
UnsubscribeObserver(napi_env env,napi_value observer)1603 void StateListenerImpl::UnsubscribeObserver(napi_env env, napi_value observer)
1604 {
1605     HILOG_INFO();
1606     std::lock_guard<ffrt::mutex> lock(mutex_);
1607     for (auto iter = observers_.begin(); iter != observers_.end();) {
1608         if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) {
1609             DeleteObserverReference(env, *iter);
1610             observers_.erase(iter);
1611             return;
1612         } else {
1613             iter++;
1614         }
1615     }
1616 }
1617 
UnsubscribeObservers()1618 void StateListenerImpl::UnsubscribeObservers()
1619 {
1620     HILOG_INFO();
1621     std::lock_guard<ffrt::mutex> lock(mutex_);
1622     for (auto iter = observers_.begin(); iter != observers_.end();) {
1623         DeleteObserverReference((*iter)->env_, *iter);
1624         observers_.erase(iter);
1625     }
1626     observers_.clear();
1627 }