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