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 }