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 StateCallbackInfo *callbackInfo = new(std::nothrow) 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 uv_work_t *work = new(std::nothrow) uv_work_t;
760 if (!work) {
761 HILOG_ERROR("Failed to create work.");
762 delete callbackInfo;
763 callbackInfo = nullptr;
764 return;
765 }
766 work->data = static_cast<void*>(callbackInfo);
767
768 int ret = NotifyJSWork(env, work);
769 if (ret != 0) {
770 HILOG_ERROR("Failed to execute NotifyJS work queue");
771 delete callbackInfo;
772 callbackInfo = nullptr;
773 delete work;
774 work = nullptr;
775 }
776 }
777
NotifyJSWork(napi_env env, uv_work_t *work)778 int StateListener::NotifyJSWork(napi_env env, uv_work_t *work)
779 {
780 uv_loop_s *loop = nullptr;
781 napi_get_uv_event_loop(env, &loop);
782 if (loop == nullptr || work == nullptr) {
783 HILOG_ERROR("loop or work is nullptr.");
784 return RET_ERR_FAILED;
785 }
786 int ret = uv_queue_work_with_qos(
787 loop,
788 work,
789 [](uv_work_t *work) {},
790 [](uv_work_t *work, int status) {
791 StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data);
792 napi_env tmpEnv = callbackInfo->env_;
793 auto closeScope = [tmpEnv](napi_handle_scope scope) {
794 napi_close_handle_scope(tmpEnv, scope);
795 };
796 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
797 OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope);
798 napi_value handler = nullptr;
799 napi_value callResult = nullptr;
800 napi_value jsEvent = nullptr;
801 napi_get_boolean(callbackInfo->env_, callbackInfo->state_, &jsEvent);
802
803 napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler);
804 napi_value undefined = nullptr;
805 napi_get_undefined(callbackInfo->env_, &undefined);
806 napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult);
807 delete callbackInfo;
808 callbackInfo = nullptr;
809 delete work;
810 work = nullptr;
811 },
812 uv_qos_default);
813 return ret;
814 }
815
OnStateChanged(const bool state)816 void StateListener::OnStateChanged(const bool state)
817 {
818 NotifyJS(env_, state, handlerRef_);
819 }
820
DefineJSCaptionsManager(napi_env env)821 void NAccessibilityClient::DefineJSCaptionsManager(napi_env env)
822 {
823 napi_property_descriptor captionsManagerDesc[] = {
824 DECLARE_NAPI_GETTER_SETTER("enabled",
825 NAccessibilityClient::GetCaptionStateEnabled, NAccessibilityClient::SetCaptionStateEnabled),
826 DECLARE_NAPI_GETTER_SETTER("style",
827 NAccessibilityClient::GetCaptionStyle, NAccessibilityClient::SetCaptionStyle),
828 DECLARE_NAPI_FUNCTION("on", NAccessibilityClient::RegisterCaptionStateCallback),
829 DECLARE_NAPI_FUNCTION("off", NAccessibilityClient::DeregisterCaptionStateCallback),
830 };
831
832 napi_value aaCons = nullptr;
833 NAPI_CALL_RETURN_VOID(env,
834 napi_define_class(env,
835 "CaptionsManager",
836 NAPI_AUTO_LENGTH,
837 NAccessibilityClient::AccessibleAbilityConstructor,
838 nullptr,
839 sizeof(captionsManagerDesc) / sizeof(captionsManagerDesc[0]),
840 captionsManagerDesc,
841 &aaCons));
842
843 napi_create_reference(env, aaCons, 1, &NAccessibilityClient::aaConsRef_);
844 }
845
AccessibleAbilityConstructor(napi_env env, napi_callback_info info)846 napi_value NAccessibilityClient::AccessibleAbilityConstructor(napi_env env, napi_callback_info info)
847 {
848 napi_value jsthis = nullptr;
849 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
850 return jsthis;
851 }
852
853
GetCaptionsManager(napi_env env, napi_callback_info info)854 napi_value NAccessibilityClient::GetCaptionsManager(napi_env env, napi_callback_info info)
855 {
856 HILOG_INFO();
857 napi_value result = 0;
858 napi_value aaCons = nullptr;
859 napi_get_reference_value(env, NAccessibilityClient::aaConsRef_, &aaCons);
860 napi_new_instance(env, aaCons, 0, nullptr, &result);
861 return result;
862 }
863
SetCaptionStateEnabled(napi_env env, napi_callback_info info)864 napi_value NAccessibilityClient::SetCaptionStateEnabled(napi_env env, napi_callback_info info)
865 {
866 HILOG_INFO();
867 size_t argc = ARGS_SIZE_ONE;
868 napi_value parameters[ARGS_SIZE_ONE] = {0};
869 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
870 if (argc >= ARGS_SIZE_ONE) {
871 bool captionState = false;
872 OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
873 if (!ParseBool(env, captionState, parameters[PARAM0])) {
874 ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
875 } else {
876 HILOG_INFO("captionState = %{public}s", captionState ? "True" : "False");
877
878 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
879 ret = instance.SetCaptionsState(captionState);
880 }
881 if (ret != OHOS::Accessibility::RET_OK) {
882 napi_value err = CreateBusinessError(env, ret);
883 napi_throw(env, err);
884 }
885 } else {
886 HILOG_ERROR("SetCaptionStateEnabled argc size Error");
887 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
888 napi_throw(env, err);
889 }
890
891 napi_value undefined = nullptr;
892 napi_get_undefined(env, &undefined);
893 return undefined;
894 }
895
GetCaptionStateEnabled(napi_env env, napi_callback_info info)896 napi_value NAccessibilityClient::GetCaptionStateEnabled(napi_env env, napi_callback_info info)
897 {
898 HILOG_INFO();
899 napi_value captionStateEnabled = nullptr;
900
901 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
902 bool captionState = false;
903 instance.GetCaptionsState(captionState);
904 napi_get_boolean(env, captionState, &captionStateEnabled);
905
906 HILOG_INFO("captionState = %{public}s", captionState ? "True" : "False");
907
908 return captionStateEnabled;
909 }
910
SetCaptionStyle(napi_env env, napi_callback_info info)911 napi_value NAccessibilityClient::SetCaptionStyle(napi_env env, napi_callback_info info)
912 {
913 HILOG_INFO();
914 size_t argc = ARGS_SIZE_ONE;
915 napi_value parameters[ARGS_SIZE_ONE] = {0};
916 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
917 if (argc >= ARGS_SIZE_ONE) {
918 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
919 OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
920 if (!ConvertObjToCaptionProperty(env, parameters[PARAM0], &captionProperty)) {
921 ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
922 } else {
923 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
924 ret = instance.SetCaptionsProperty(captionProperty);
925 }
926 if (ret != OHOS::Accessibility::RET_OK) {
927 napi_value err = CreateBusinessError(env, ret);
928 napi_throw(env, err);
929 }
930 } else {
931 HILOG_ERROR("SetCaptionStyle argc size Error");
932 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
933 napi_throw(env, err);
934 }
935
936 napi_value undefined = nullptr;
937 napi_get_undefined(env, &undefined);
938 return undefined;
939 }
940
GetCaptionStyle(napi_env env, napi_callback_info info)941 napi_value NAccessibilityClient::GetCaptionStyle(napi_env env, napi_callback_info info)
942 {
943 HILOG_INFO();
944 napi_value captionStyle = nullptr;
945 napi_get_reference_value(env, NAccessibilityClient::aaStyleConsRef_, &captionStyle);
946
947 return captionStyle;
948 }
949
RegisterCaptionStateCallback(napi_env env, napi_callback_info info)950 napi_value NAccessibilityClient::RegisterCaptionStateCallback(napi_env env, napi_callback_info info)
951 {
952 HILOG_INFO();
953
954 size_t argc = ARGS_SIZE_TWO;
955 napi_value args[ARGS_SIZE_TWO] = {0};
956 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
957 if (status != napi_ok) {
958 HILOG_ERROR("RegisterCaptionStateCallback Failed to get event type");
959 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_FAILED);
960 napi_throw(env, err);
961 return nullptr;
962 }
963
964 OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
965 if (argc < ARGS_SIZE_TWO) {
966 HILOG_ERROR("RegisterCaptionStateCallback argc is invalid: %{public}zu", argc);
967 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
968 }
969
970 OHOS::AccessibilityConfig::CONFIG_ID type = OHOS::AccessibilityConfig::CONFIG_ID_MAX;
971 if (errCode == OHOS::Accessibility::RET_OK) {
972 std::string eventType = "";
973 if (!ParseString(env, eventType, args[PARAM0])) {
974 HILOG_ERROR("eventType type parse failed");
975 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
976 } else {
977 if (std::strcmp(eventType.c_str(), "enableChange") == 0) {
978 type = OHOS::AccessibilityConfig::CONFIG_CAPTION_STATE;
979 } else if (std::strcmp(eventType.c_str(), "styleChange") == 0) {
980 type = OHOS::AccessibilityConfig::CONFIG_CAPTION_STYLE;
981 } else {
982 HILOG_ERROR("SubscribeState eventType[%{public}s] is error", eventType.c_str());
983 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
984 }
985 }
986 }
987
988 if (errCode == OHOS::Accessibility::RET_OK) {
989 napi_valuetype valueType = napi_null;
990 napi_typeof(env, args[PARAM1], &valueType);
991 if (valueType != napi_function) {
992 HILOG_ERROR("RegisterCaptionStateCallback args[PARAM1] format is wrong");
993 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
994 }
995 }
996
997 if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
998 napi_value err = CreateBusinessError(env, errCode);
999 HILOG_ERROR("invalid param");
1000 napi_throw(env, err);
1001 return nullptr;
1002 }
1003
1004 captionListeners_->SubscribeObserver(env, type, args[PARAM1]);
1005
1006 return nullptr;
1007 }
1008
DeregisterCaptionStateCallback(napi_env env, napi_callback_info info)1009 napi_value NAccessibilityClient::DeregisterCaptionStateCallback(napi_env env, napi_callback_info info)
1010 {
1011 HILOG_INFO();
1012 size_t argc = ARGS_SIZE_TWO;
1013 napi_value args[ARGS_SIZE_TWO] = {0};
1014 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1015
1016 OHOS::Accessibility::RetError errCode = OHOS::Accessibility::RET_OK;
1017 if (argc < ARGS_SIZE_TWO - 1) {
1018 HILOG_ERROR("DeregisterCaptionStateCallback argc is invalid: %{public}zu", argc);
1019 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1020 }
1021
1022 OHOS::AccessibilityConfig::CONFIG_ID type = OHOS::AccessibilityConfig::CONFIG_ID_MAX;
1023 if (errCode == OHOS::Accessibility::RET_OK) {
1024 std::string eventType = "";
1025 if (!ParseString(env, eventType, args[PARAM0])) {
1026 HILOG_ERROR("eventType type parse failed");
1027 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1028 } else {
1029 if (std::strcmp(eventType.c_str(), "enableChange") == 0) {
1030 type = OHOS::AccessibilityConfig::CONFIG_CAPTION_STATE;
1031 } else if (std::strcmp(eventType.c_str(), "styleChange") == 0) {
1032 type = OHOS::AccessibilityConfig::CONFIG_CAPTION_STYLE;
1033 } else {
1034 HILOG_ERROR("SubscribeState eventType[%{public}s] is error", eventType.c_str());
1035 errCode = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1036 }
1037 }
1038 }
1039
1040 if (errCode == OHOS::Accessibility::RET_ERR_INVALID_PARAM) {
1041 napi_value err = CreateBusinessError(env, errCode);
1042 HILOG_ERROR("DeregisterCaptionStateCallback invalid param");
1043 napi_throw(env, err);
1044 return nullptr;
1045 }
1046
1047 if (argc >= ARGS_SIZE_TWO && CheckJsFunction(env, args[PARAM1])) {
1048 captionListeners_->UnsubscribeObserver(env, type, args[PARAM1]);
1049 } else {
1050 captionListeners_->UnsubscribeObservers(type);
1051 }
1052
1053 return nullptr;
1054 }
1055
DefineJSCaptionsStyle(napi_env env)1056 void NAccessibilityClient::DefineJSCaptionsStyle(napi_env env)
1057 {
1058 napi_property_descriptor captionsStyleDesc[] = {
1059 DECLARE_NAPI_GETTER_SETTER("fontFamily",
1060 NAccessibilityClient::GetCaptionsFontFamily, NAccessibilityClient::SetCaptionsFontFamily),
1061 DECLARE_NAPI_GETTER_SETTER("fontScale",
1062 NAccessibilityClient::GetCaptionsFontScale, NAccessibilityClient::SetCaptionsFontScale),
1063 DECLARE_NAPI_GETTER_SETTER("fontColor",
1064 NAccessibilityClient::GetCaptionFrontColor, NAccessibilityClient::SetCaptionFrontColor),
1065 DECLARE_NAPI_GETTER_SETTER("fontEdgeType",
1066 NAccessibilityClient::GetCaptionFontEdgeType, NAccessibilityClient::SetCaptionFontEdgeType),
1067 DECLARE_NAPI_GETTER_SETTER("backgroundColor",
1068 NAccessibilityClient::GetCaptionBackgroundColor, NAccessibilityClient::SetCaptionBackgroundColor),
1069 DECLARE_NAPI_GETTER_SETTER("windowColor",
1070 NAccessibilityClient::GetCaptionWindowColor, NAccessibilityClient::SetCaptionWindowColor),
1071 };
1072
1073 napi_value aaStyleCons = nullptr;
1074 napi_value captionStyle = nullptr;
1075
1076 NAPI_CALL_RETURN_VOID(env,
1077 napi_define_class(env,
1078 "CaptionsStyle",
1079 NAPI_AUTO_LENGTH,
1080 NAccessibilityClient::AccessibleAbilityConstructorStyle,
1081 nullptr,
1082 sizeof(captionsStyleDesc) / sizeof(captionsStyleDesc[0]),
1083 captionsStyleDesc,
1084 &aaStyleCons));
1085
1086 napi_new_instance(env, aaStyleCons, 0, nullptr, &captionStyle);
1087 napi_create_reference(env, captionStyle, 1, &NAccessibilityClient::aaStyleConsRef_);
1088 }
1089
AccessibleAbilityConstructorStyle(napi_env env, napi_callback_info info)1090 napi_value NAccessibilityClient::AccessibleAbilityConstructorStyle(napi_env env, napi_callback_info info)
1091 {
1092 HILOG_INFO();
1093 napi_value jsthis = nullptr;
1094 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
1095 return jsthis;
1096 }
1097
GetCaptionsFontFamily(napi_env env, napi_callback_info info)1098 napi_value NAccessibilityClient::GetCaptionsFontFamily(napi_env env, napi_callback_info info)
1099 {
1100 HILOG_INFO();
1101 napi_value returnValue = nullptr;
1102 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1103 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1104 instance.GetCaptionsProperty(captionProperty);
1105 napi_create_string_utf8(env, captionProperty.GetFontFamily().c_str(), NAPI_AUTO_LENGTH, &returnValue);
1106 return returnValue;
1107 }
1108
SetCaptionsFontFamily(napi_env env, napi_callback_info info)1109 napi_value NAccessibilityClient::SetCaptionsFontFamily(napi_env env, napi_callback_info info)
1110 {
1111 HILOG_INFO();
1112 size_t argc = ARGS_SIZE_ONE;
1113 napi_value parameters[ARGS_SIZE_ONE] = {0};
1114 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1115 if (argc >= ARGS_SIZE_ONE) {
1116 // Get input FontFamily
1117 std::string fontFamily = "";
1118 OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1119 if (ParseString(env, fontFamily, parameters[PARAM0]) && fontFamily.length() > 0) {
1120 HILOG_INFO("FontFamily = %{public}s", fontFamily.c_str());
1121 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1122 OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1123 instance.GetCaptionsProperty(captionProperty);
1124 // Change the input info and then set the CaptionProperty
1125 captionProperty.SetFontFamily(std::string(fontFamily));
1126 ret = instance.SetCaptionsProperty(captionProperty);
1127 } else {
1128 ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1129 }
1130 if (ret != OHOS::Accessibility::RET_OK) {
1131 napi_value err = CreateBusinessError(env, ret);
1132 napi_throw(env, err);
1133 }
1134 } else {
1135 HILOG_ERROR("SetCaptionsFontFamily argc size Error");
1136 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1137 napi_throw(env, err);
1138 }
1139 napi_value undefined = nullptr;
1140 napi_get_undefined(env, &undefined);
1141 return undefined;
1142 }
1143
GetCaptionsFontScale(napi_env env, napi_callback_info info)1144 napi_value NAccessibilityClient::GetCaptionsFontScale(napi_env env, napi_callback_info info)
1145 {
1146 HILOG_INFO();
1147 napi_value returnValue = nullptr;
1148 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1149 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1150 instance.GetCaptionsProperty(captionProperty);
1151 napi_create_int32(env, captionProperty.GetFontScale(), &returnValue);
1152 return returnValue;
1153 }
1154
SetCaptionsFontScale(napi_env env, napi_callback_info info)1155 napi_value NAccessibilityClient::SetCaptionsFontScale(napi_env env, napi_callback_info info)
1156 {
1157 HILOG_INFO();
1158 size_t argc = ARGS_SIZE_ONE;
1159 napi_value parameters[ARGS_SIZE_ONE] = {0};
1160 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1161 if (argc >= ARGS_SIZE_ONE) {
1162 // Get input FontScale
1163 int32_t num = 100;
1164 OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1165 if (ParseInt32(env, num, parameters[PARAM0])) {
1166 HILOG_INFO("FontScale = %{public}d", num);
1167 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1168 OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1169 instance.GetCaptionsProperty(captionProperty);
1170 // Change the input info and then set the CaptionProperty
1171 captionProperty.SetFontScale(num);
1172 ret = instance.SetCaptionsProperty(captionProperty);
1173 } else {
1174 ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1175 }
1176 if (ret != OHOS::Accessibility::RET_OK) {
1177 napi_value err = CreateBusinessError(env, ret);
1178 napi_throw(env, err);
1179 }
1180 } else {
1181 HILOG_ERROR("SetCaptionsFontScale argc size Error");
1182 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1183 napi_throw(env, err);
1184 }
1185 napi_value undefined = nullptr;
1186 napi_get_undefined(env, &undefined);
1187 return undefined;
1188 }
1189
GetCaptionFrontColor(napi_env env, napi_callback_info info)1190 napi_value NAccessibilityClient::GetCaptionFrontColor(napi_env env, napi_callback_info info)
1191 {
1192 HILOG_INFO();
1193 napi_value returnValue = nullptr;
1194 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1195 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1196 instance.GetCaptionsProperty(captionProperty);
1197 uint32_t color = captionProperty.GetFontColor();
1198 std::string colorStr = ConvertColorToString(color);
1199 napi_create_string_utf8(env, colorStr.c_str(), NAPI_AUTO_LENGTH, &returnValue);
1200 return returnValue;
1201 }
1202
SetCaptionFrontColor(napi_env env, napi_callback_info info)1203 napi_value NAccessibilityClient::SetCaptionFrontColor(napi_env env, napi_callback_info info)
1204 {
1205 HILOG_INFO();
1206 size_t argc = ARGS_SIZE_ONE;
1207 napi_value parameters[ARGS_SIZE_ONE] = {0};
1208 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1209 if (argc >= ARGS_SIZE_ONE) {
1210 HILOG_DEBUG("SetCaptionFrontColor argc > 1");
1211 uint32_t color = GetColorValue(env, parameters[PARAM0]);
1212 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1213 OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1214 instance.GetCaptionsProperty(captionProperty);
1215 // Change the input info and then set the CaptionProperty
1216 captionProperty.SetFontColor(color);
1217 OHOS::Accessibility::RetError ret = instance.SetCaptionsProperty(captionProperty);
1218 if (ret != OHOS::Accessibility::RET_OK) {
1219 napi_value err = CreateBusinessError(env, ret);
1220 napi_throw(env, err);
1221 }
1222 } else {
1223 HILOG_ERROR("SetCaptionFrontColor argc size Error");
1224 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1225 napi_throw(env, err);
1226 }
1227 napi_value undefined = nullptr;
1228 napi_get_undefined(env, &undefined);
1229 return undefined;
1230 }
1231
GetCaptionFontEdgeType(napi_env env, napi_callback_info info)1232 napi_value NAccessibilityClient::GetCaptionFontEdgeType(napi_env env, napi_callback_info info)
1233 {
1234 HILOG_INFO();
1235 napi_value returnValue = nullptr;
1236 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1237 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1238 instance.GetCaptionsProperty(captionProperty);
1239 napi_create_string_utf8(env, captionProperty.GetFontEdgeType().c_str(), NAPI_AUTO_LENGTH, &returnValue);
1240 return returnValue;
1241 }
1242
SetCaptionFontEdgeType(napi_env env, napi_callback_info info)1243 napi_value NAccessibilityClient::SetCaptionFontEdgeType(napi_env env, napi_callback_info info)
1244 {
1245 HILOG_INFO();
1246 size_t argc = ARGS_SIZE_ONE;
1247 napi_value parameters[ARGS_SIZE_ONE] = {0};
1248
1249 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1250 if (argc >= ARGS_SIZE_ONE) {
1251 // Get input FontEdgeType
1252 std::string fontEdgeType = "";
1253 OHOS::Accessibility::RetError ret = OHOS::Accessibility::RET_OK;
1254 if (ParseString(env, fontEdgeType, parameters[PARAM0]) && fontEdgeType.length() > 0) {
1255 HILOG_INFO("fontEdgeType = %{public}s", fontEdgeType.c_str());
1256 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1257 OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1258 instance.GetCaptionsProperty(captionProperty);
1259 // Change the input info and then set the CaptionProperty
1260 captionProperty.SetFontEdgeType(std::string(fontEdgeType));
1261 ret = instance.SetCaptionsProperty(captionProperty);
1262 } else {
1263 ret = OHOS::Accessibility::RET_ERR_INVALID_PARAM;
1264 }
1265 if (ret != OHOS::Accessibility::RET_OK) {
1266 napi_value err = CreateBusinessError(env, ret);
1267 napi_throw(env, err);
1268 }
1269 } else {
1270 HILOG_ERROR("SetCaptionFontEdgeType argc size Error");
1271 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1272 napi_throw(env, err);
1273 }
1274 napi_value undefined = nullptr;
1275 napi_get_undefined(env, &undefined);
1276 return undefined;
1277 }
1278
GetCaptionBackgroundColor(napi_env env, napi_callback_info info)1279 napi_value NAccessibilityClient::GetCaptionBackgroundColor(napi_env env, napi_callback_info info)
1280 {
1281 HILOG_INFO();
1282 napi_value returnValue = nullptr;
1283 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1284 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1285 instance.GetCaptionsProperty(captionProperty);
1286 uint32_t color = captionProperty.GetBackgroundColor();
1287 std::string colorStr = ConvertColorToString(color);
1288 napi_create_string_utf8(env, colorStr.c_str(), NAPI_AUTO_LENGTH, &returnValue);
1289 return returnValue;
1290 }
1291
SetCaptionBackgroundColor(napi_env env, napi_callback_info info)1292 napi_value NAccessibilityClient::SetCaptionBackgroundColor(napi_env env, napi_callback_info info)
1293 {
1294 HILOG_INFO();
1295 size_t argc = ARGS_SIZE_ONE;
1296 napi_value parameters[ARGS_SIZE_ONE] = {0};
1297 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1298 if (argc >= ARGS_SIZE_ONE) {
1299 HILOG_DEBUG("SetCaptionBackgroundColor argc > 1");
1300 uint32_t color = GetColorValue(env, parameters[PARAM0]);
1301 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1302 OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1303 instance.GetCaptionsProperty(captionProperty);
1304 // Change the input info and then set the CaptionProperty
1305 captionProperty.SetBackgroundColor(color);
1306 OHOS::Accessibility::RetError ret = instance.SetCaptionsProperty(captionProperty);
1307 if (ret != OHOS::Accessibility::RET_OK) {
1308 napi_value err = CreateBusinessError(env, ret);
1309 napi_throw(env, err);
1310 }
1311 } else {
1312 HILOG_ERROR("SetCaptionBackgroundColor argc size Error");
1313 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1314 napi_throw(env, err);
1315 }
1316 napi_value undefined = nullptr;
1317 napi_get_undefined(env, &undefined);
1318 return undefined;
1319 }
1320
GetCaptionWindowColor(napi_env env, napi_callback_info info)1321 napi_value NAccessibilityClient::GetCaptionWindowColor(napi_env env, napi_callback_info info)
1322 {
1323 HILOG_INFO();
1324 napi_value returnValue = nullptr;
1325 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1326 OHOS::AccessibilityConfig::CaptionProperty captionProperty = {};
1327 instance.GetCaptionsProperty(captionProperty);
1328 uint32_t color = captionProperty.GetWindowColor();
1329 std::string colorStr = ConvertColorToString(color);
1330 napi_create_string_utf8(env, colorStr.c_str(), NAPI_AUTO_LENGTH, &returnValue);
1331 return returnValue;
1332 }
1333
SetCaptionWindowColor(napi_env env, napi_callback_info info)1334 napi_value NAccessibilityClient::SetCaptionWindowColor(napi_env env, napi_callback_info info)
1335 {
1336 HILOG_INFO();
1337 size_t argc = ARGS_SIZE_ONE;
1338 napi_value parameters[ARGS_SIZE_ONE] = {0};
1339 napi_get_cb_info(env, info, &argc, parameters, nullptr, nullptr);
1340 if (argc >= ARGS_SIZE_ONE) {
1341 HILOG_DEBUG("SetCaptionWindowColor argc > 1");
1342 uint32_t color = GetColorValue(env, parameters[PARAM0]);
1343 auto &instance = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
1344 OHOS::AccessibilityConfig::CaptionProperty captionProperty {};
1345 instance.GetCaptionsProperty(captionProperty);
1346 // Change the input info and then set the CaptionProperty
1347 captionProperty.SetWindowColor(color);
1348 OHOS::Accessibility::RetError ret = instance.SetCaptionsProperty(captionProperty);
1349 if (ret != OHOS::Accessibility::RET_OK) {
1350 napi_value err = CreateBusinessError(env, ret);
1351 napi_throw(env, err);
1352 }
1353 } else {
1354 HILOG_ERROR("SetCaptionWindowColor argc size Error");
1355 napi_value err = CreateBusinessError(env, OHOS::Accessibility::RET_ERR_INVALID_PARAM);
1356 napi_throw(env, err);
1357 }
1358 napi_value undefined = nullptr;
1359 napi_get_undefined(env, &undefined);
1360 return undefined;
1361 }
1362
SubscribeToFramework()1363 void StateListenerImpl::SubscribeToFramework()
1364 {
1365 auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
1366 if (asaClient) {
1367 asaClient->SubscribeStateObserver(shared_from_this(), type_);
1368 }
1369 }
1370
UnsubscribeFromFramework()1371 void StateListenerImpl::UnsubscribeFromFramework()
1372 {
1373 HILOG_INFO("UnsubscribeFromFramework");
1374 auto asaClient = AccessibilitySystemAbilityClient::GetInstance();
1375 if (asaClient) {
1376 asaClient->UnsubscribeStateObserver(shared_from_this(), type_);
1377 }
1378 }
1379
OnStateChanged(const bool state)1380 void StateListenerImpl::OnStateChanged(const bool state)
1381 {
1382 HILOG_INFO();
1383 std::lock_guard<ffrt::mutex> lock(mutex_);
1384 for (auto &observer : observers_) {
1385 observer->OnStateChanged(state);
1386 }
1387 }
1388
SubscribeObserver(napi_env env, napi_value observer)1389 void StateListenerImpl::SubscribeObserver(napi_env env, napi_value observer)
1390 {
1391 HILOG_INFO();
1392 std::lock_guard<ffrt::mutex> lock(mutex_);
1393 for (auto iter = observers_.begin(); iter != observers_.end();) {
1394 if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) {
1395 HILOG_DEBUG("SubscribeObserver Observer exist");
1396 return;
1397 } else {
1398 iter++;
1399 }
1400 }
1401
1402 napi_ref ref;
1403 napi_create_reference(env, observer, 1, &ref);
1404 std::shared_ptr<StateListener> stateListener = std::make_shared<StateListener>(env, ref);
1405
1406 observers_.emplace_back(stateListener);
1407 HILOG_INFO("observer size%{public}zu", observers_.size());
1408 }
1409
UnsubscribeObserver(napi_env env, napi_value observer)1410 void StateListenerImpl::UnsubscribeObserver(napi_env env, napi_value observer)
1411 {
1412 HILOG_INFO();
1413 std::lock_guard<ffrt::mutex> lock(mutex_);
1414 for (auto iter = observers_.begin(); iter != observers_.end();) {
1415 if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) {
1416 observers_.erase(iter);
1417 return;
1418 } else {
1419 iter++;
1420 }
1421 }
1422 }
1423
UnsubscribeObservers()1424 void StateListenerImpl::UnsubscribeObservers()
1425 {
1426 HILOG_INFO();
1427 std::lock_guard<ffrt::mutex> lock(mutex_);
1428 observers_.clear();
1429 }