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