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_info.h"
17 #include "hilog_wrapper.h"
18 #include "napi_accessibility_utils.h"
19
20 using namespace OHOS;
21 using namespace OHOS::Accessibility;
22
23 napi_value NElementInfo::cons_ = nullptr;
24 napi_ref NElementInfo::consRef_ = nullptr;
25
DefineJSElementInfo(napi_env env)26 void NElementInfo::DefineJSElementInfo(napi_env env)
27 {
28 napi_property_descriptor descForElementInfo[] = {
29 DECLARE_NAPI_FUNCTION("executeAction", NElementInfo::ExecuteAction),
30 DECLARE_NAPI_FUNCTION("getByContent", NElementInfo::GetByContent),
31 DECLARE_NAPI_FUNCTION("get", NElementInfo::GetFocus),
32 DECLARE_NAPI_FUNCTION("next", NElementInfo::GetNext),
33 DECLARE_NAPI_FUNCTION("getChild", NElementInfo::GetChild),
34 DECLARE_NAPI_FUNCTION("getParent", NElementInfo::GetParent),
35 };
36
37 NAPI_CALL_RETURN_VOID(env,
38 napi_define_class(env,
39 "AccessibilityElementInfo",
40 NAPI_AUTO_LENGTH,
41 NElementInfo::JSConstructor,
42 nullptr,
43 sizeof(descForElementInfo) / sizeof(descForElementInfo[0]),
44 descForElementInfo,
45 &NElementInfo::cons_));
46 napi_create_reference(env, NElementInfo::cons_, 1, &NElementInfo::consRef_);
47 }
48
JSConstructor(napi_env env,napi_callback_info info)49 napi_value NElementInfo::JSConstructor(napi_env env, napi_callback_info info)
50 {
51 napi_value jsthis = nullptr;
52 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
53 return jsthis;
54 }
55
ExecuteAction(napi_env env,napi_callback_info info)56 napi_value NElementInfo::ExecuteAction(napi_env env, napi_callback_info info)
57 {
58 HILOG_INFO("start");
59 size_t argc = ARGS_SIZE_THREE;
60 napi_value argv[ARGS_SIZE_THREE] = {0};
61 napi_status status;
62 napi_value thisVar;
63 void* data = nullptr;
64 AccessibilityElementInfo* nodeInfo = nullptr;
65 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
66 std::string action;
67 ParseString(env, action, argv[PARAM0]);
68 HILOG_DEBUG("argc = %{public}d", (int)argc);
69 HILOG_INFO("action = %{public}s", action.c_str());
70 status = napi_unwrap(env, thisVar, (void**)&nodeInfo);
71 if (!nodeInfo) {
72 HILOG_ERROR("nodeInfo is null!!");
73 }
74 NAccessibilityInfoData *callbackInfo = new NAccessibilityInfoData();
75 ConvertActionArgsJSToNAPI(env, argv[argc - 1], callbackInfo->actionArguments_,
76 ConvertStringToAccessibleOperationType(action));
77 callbackInfo->nativeNodeInfo_ = *nodeInfo;
78 callbackInfo->content_ = action;
79 napi_value promise = nullptr;
80
81 // Parse function
82 napi_valuetype valueType = napi_undefined;
83 if (argc >= ARGS_SIZE_TWO) {
84 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valueType));
85 }
86 if (valueType == napi_function) {
87 HILOG_ERROR("ExecuteAction callback mode");
88 napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
89 napi_get_undefined(env, &promise);
90 } else {
91 HILOG_ERROR("ExecuteAction promise mode");
92 napi_create_promise(env, &callbackInfo->deferred_, &promise);
93 }
94 napi_value resource = nullptr;
95 napi_create_string_utf8(env, "ExecuteAction", NAPI_AUTO_LENGTH, &resource);
96
97 napi_create_async_work(
98 env, nullptr, resource,
99 [](napi_env env, void* data) {
100 NAccessibilityInfoData *callbackInfo = (NAccessibilityInfoData*)data;
101 ActionType action = ConvertStringToAccessibleOperationType(callbackInfo->content_);
102 AccessibilityElementInfo nodeInfo = callbackInfo->nativeNodeInfo_;
103 callbackInfo->result_ = nodeInfo.ExecuteAction(action, callbackInfo->actionArguments_);
104 },
105 [](napi_env env, napi_status status, void* data) {
106 HILOG_DEBUG("ExecuteAction execute back");
107 NAccessibilityInfoData* callbackInfo = (NAccessibilityInfoData*)data;
108 napi_value jsReturnValue = 0;
109 napi_value argv[ARGS_SIZE_TWO] = {0};
110 napi_value callback = 0;
111 napi_value undefined = 0;
112 napi_get_undefined(env, &undefined);
113
114 napi_get_boolean(env, callbackInfo->result_, &argv[PARAM1]);
115 HILOG_DEBUG("callbackInfo->result_[%{public}d]", callbackInfo->result_);
116
117 if (callbackInfo->callback_) {
118 // Callback mode
119 argv[PARAM0] = GetErrorValue(env, CODE_SUCCESS);
120 napi_get_reference_value(env, callbackInfo->callback_, &callback);
121 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, argv, &jsReturnValue);
122 napi_delete_reference(env, callbackInfo->callback_);
123 } else {
124 // Promise mode
125 napi_resolve_deferred(env, callbackInfo->deferred_, argv[PARAM1]);
126 }
127
128 napi_delete_async_work(env, callbackInfo->work_);
129 delete callbackInfo;
130 },
131 (void*)callbackInfo,
132 &callbackInfo->work_);
133 napi_queue_async_work(env, callbackInfo->work_);
134
135 return promise;
136 }
137
GetByContent(napi_env env,napi_callback_info info)138 napi_value NElementInfo::GetByContent(napi_env env, napi_callback_info info)
139 {
140 HILOG_INFO("start");
141 size_t argc = ARGS_SIZE_TWO;
142 napi_value argv[ARGS_SIZE_TWO] = {0};
143 napi_status status;
144 napi_value thisVar;
145 void* data = nullptr;
146 AccessibilityElementInfo* nodeInfo = nullptr;
147
148 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
149 std::string content;
150 ParseString(env, content, argv[PARAM0]);
151 HILOG_DEBUG("argc = %{public}d", (int)argc);
152 HILOG_INFO("content[%{public}s]", content.c_str());
153
154 status = napi_unwrap(env, thisVar, (void**)&nodeInfo);
155 if (!nodeInfo) {
156 HILOG_ERROR("nodeInfo is null!!");
157 }
158
159 NAccessibilityInfoData *callbackInfo = new NAccessibilityInfoData();
160 callbackInfo->nativeNodeInfo_ = *nodeInfo;
161 callbackInfo->content_ = content;
162 napi_value promise = nullptr;
163 if (argc > ARGS_SIZE_ONE) {
164 HILOG_DEBUG("callback mode");
165 napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
166 napi_get_undefined(env, &promise);
167 } else {
168 HILOG_DEBUG("promise mode");
169 napi_create_promise(env, &callbackInfo->deferred_, &promise);
170 }
171 napi_value resource = nullptr;
172 napi_create_string_utf8(env, "GetByContent", NAPI_AUTO_LENGTH, &resource);
173
174 napi_create_async_work(
175 env, nullptr, resource,
176 [](napi_env env, void* data) { // execute async to call c++ function
177 NAccessibilityInfoData *callbackInfo = (NAccessibilityInfoData*)data;
178 AccessibilityElementInfo nodeInfo = callbackInfo->nativeNodeInfo_;
179 callbackInfo->ret_ = nodeInfo.GetByContent(callbackInfo->content_, callbackInfo->nodeInfos_);
180 },
181 [](napi_env env, napi_status status, void* data) { // execute the complete function
182 HILOG_DEBUG("execute back");
183 NAccessibilityInfoData* callbackInfo = (NAccessibilityInfoData*)data;
184 napi_value jsReturnValue = 0;
185 napi_value argv[ARGS_SIZE_TWO] = {0};
186 napi_value callback = 0;
187 napi_value undefined = 0;
188 napi_get_undefined(env, &undefined);
189
190 napi_create_array(env, &argv[PARAM1]);
191 napi_get_reference_value(env, NElementInfo::consRef_, &NElementInfo::cons_);
192 ConvertElementInfosToJS(env, argv[PARAM1], callbackInfo->nodeInfos_);
193
194 argv[PARAM0] = GetErrorValue(env, callbackInfo->ret_ ? CODE_SUCCESS : CODE_FAILED);
195 if (callbackInfo->callback_) {
196 HILOG_DEBUG("callback mode");
197 napi_get_reference_value(env, callbackInfo->callback_, &callback);
198 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, argv, &jsReturnValue);
199 napi_delete_reference(env, callbackInfo->callback_);
200 } else {
201 HILOG_DEBUG("Promise mode");
202 if (callbackInfo->ret_) {
203 napi_resolve_deferred(env, callbackInfo->deferred_, argv[PARAM1]);
204 } else {
205 napi_reject_deferred(env, callbackInfo->deferred_, argv[PARAM0]);
206 }
207 }
208
209 napi_delete_async_work(env, callbackInfo->work_);
210 delete callbackInfo;
211 },
212 (void*)callbackInfo,
213 &callbackInfo->work_);
214 napi_queue_async_work(env, callbackInfo->work_);
215
216 return promise;
217 }
218
GetFocus(napi_env env,napi_callback_info info)219 napi_value NElementInfo::GetFocus(napi_env env, napi_callback_info info)
220 {
221 HILOG_INFO("start");
222 size_t argc = ARGS_SIZE_TWO;
223 napi_value argv[ARGS_SIZE_TWO] = {0};
224 napi_status status;
225 napi_value thisVar;
226 void* data = nullptr;
227 AccessibilityElementInfo* nodeInfo = nullptr;
228
229 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
230 std::string focusType;
231 ParseString(env, focusType, argv[PARAM0]);
232 HILOG_DEBUG("argc = %{public}d", (int)argc);
233 HILOG_INFO("focusType[%{public}s]", focusType.c_str());
234
235 status = napi_unwrap(env, thisVar, (void**)&nodeInfo);
236 if (!nodeInfo) {
237 HILOG_ERROR("nodeInfo is null!!");
238 }
239
240 NAccessibilityInfoData *callbackInfo = new NAccessibilityInfoData();
241 callbackInfo->nativeNodeInfo_ = *nodeInfo;
242 callbackInfo->content_ = focusType;
243 napi_value promise = nullptr;
244 if (argc > ARGS_SIZE_ONE) {
245 HILOG_DEBUG("callback mode");
246 napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
247 napi_get_undefined(env, &promise);
248 } else {
249 HILOG_DEBUG("promise mode");
250 napi_create_promise(env, &callbackInfo->deferred_, &promise);
251 }
252 napi_value resource = nullptr;
253 napi_create_string_utf8(env, "GetFocus", NAPI_AUTO_LENGTH, &resource);
254
255 napi_create_async_work(
256 env, nullptr, resource,
257 [](napi_env env, void* data) {
258 NAccessibilityInfoData *callbackInfo = (NAccessibilityInfoData*)data;
259 int focus = 0;
260 if (!std::strcmp(callbackInfo->content_.c_str(), "accessibility")) {
261 focus = FOCUS_TYPE_ACCESSIBILITY;
262 } else if (!std::strcmp(callbackInfo->content_.c_str(), "normal")) {
263 focus = FOCUS_TYPE_INPUT;
264 } else {
265 focus = FOCUS_TYPE_INVALID;
266 }
267 AccessibilityElementInfo nodeInfo = callbackInfo->nativeNodeInfo_;
268 callbackInfo->ret_ = nodeInfo.GetFocus(focus, callbackInfo->nodeInfo_);
269 },
270 [](napi_env env, napi_status status, void* data) {
271 HILOG_DEBUG("execute back");
272 NAccessibilityInfoData* callbackInfo = (NAccessibilityInfoData*)data;
273 napi_value jsReturnValue = 0;
274 napi_value argv[ARGS_SIZE_TWO] = {0};
275 napi_value callback = 0;
276 napi_value undefined = 0;
277 napi_get_undefined(env, &undefined);
278
279 napi_get_reference_value(env, NElementInfo::consRef_, &NElementInfo::cons_);
280 napi_new_instance(env, NElementInfo::cons_, 0, nullptr, &argv[PARAM1]);
281 ConvertElementInfoToJS(env, argv[PARAM1], callbackInfo->nodeInfo_);
282
283 argv[PARAM0] = GetErrorValue(env, callbackInfo->ret_ ? CODE_SUCCESS : CODE_FAILED);
284 if (callbackInfo->callback_) {
285 // Callback mode
286 napi_get_reference_value(env, callbackInfo->callback_, &callback);
287 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, argv, &jsReturnValue);
288 napi_delete_reference(env, callbackInfo->callback_);
289 } else {
290 // Promise mode
291 if (callbackInfo->ret_) {
292 napi_resolve_deferred(env, callbackInfo->deferred_, argv[PARAM1]);
293 } else {
294 napi_reject_deferred(env, callbackInfo->deferred_, argv[PARAM0]);
295 }
296 }
297
298 napi_delete_async_work(env, callbackInfo->work_);
299 delete callbackInfo;
300 },
301 (void*)callbackInfo,
302 &callbackInfo->work_);
303 napi_queue_async_work(env, callbackInfo->work_);
304
305 return promise;
306 }
307
CovertStringToDirection(std::string str)308 static FocusMoveDirection CovertStringToDirection(std::string str)
309 {
310 static const std::map<std::string, FocusMoveDirection> focusMoveDirectionTable = {
311 {"up", FocusMoveDirection::UP},
312 {"down", FocusMoveDirection::DOWN},
313 {"left", FocusMoveDirection::LEFT},
314 {"right", FocusMoveDirection::RIGHT},
315 {"forward", FocusMoveDirection::FORWARD},
316 {"backward", FocusMoveDirection::BACKWARD}
317 };
318
319 if (focusMoveDirectionTable.find(str) == focusMoveDirectionTable.end()) {
320 return FocusMoveDirection::DIRECTION_INVALID;
321 }
322
323 return focusMoveDirectionTable.at(str);
324 }
325
GetNext(napi_env env,napi_callback_info info)326 napi_value NElementInfo::GetNext(napi_env env, napi_callback_info info)
327 {
328 HILOG_INFO("start");
329 size_t argc = ARGS_SIZE_TWO;
330 napi_value argv[ARGS_SIZE_TWO] = {0};
331 napi_status status;
332 napi_value thisVar;
333 void* data = nullptr;
334 AccessibilityElementInfo* nodeInfo = nullptr;
335 bool ret = true;
336
337 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
338 std::string direction;
339 if (!ParseString(env, direction, argv[PARAM0]) || direction == "") {
340 ret = false;
341 }
342 HILOG_DEBUG("argc = %{public}d", (int)argc);
343 HILOG_INFO("direction[%{public}s]", direction.c_str());
344
345 status = napi_unwrap(env, thisVar, (void**)&nodeInfo);
346 if (!nodeInfo) {
347 HILOG_ERROR("nodeInfo is null!!");
348 }
349
350 NAccessibilityInfoData *callbackInfo = new NAccessibilityInfoData();
351 callbackInfo->nativeNodeInfo_ = *nodeInfo;
352 callbackInfo->content_ = direction;
353 callbackInfo->ret_ = ret;
354 napi_value promise = nullptr;
355 if (argc > ARGS_SIZE_ONE) {
356 HILOG_DEBUG("GetNext callback mode");
357 napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
358 napi_get_undefined(env, &promise);
359 } else {
360 HILOG_DEBUG("GetNext promise mode");
361 napi_create_promise(env, &callbackInfo->deferred_, &promise);
362 }
363 napi_value resource = nullptr;
364 napi_create_string_utf8(env, "GetNext", NAPI_AUTO_LENGTH, &resource);
365
366 napi_create_async_work(
367 env, nullptr, resource,
368 [](napi_env env, void* data) { // execute async to call c++ function
369 NAccessibilityInfoData *callbackInfo = (NAccessibilityInfoData*)data;
370 AccessibilityElementInfo nodeInfo = callbackInfo->nativeNodeInfo_;
371 if (callbackInfo->ret_) {
372 callbackInfo->ret_ = nodeInfo.GetNext(CovertStringToDirection(callbackInfo->content_),
373 callbackInfo->nodeInfo_);
374 }
375 },
376 [](napi_env env, napi_status status, void* data) { // execute the complete function
377 HILOG_DEBUG("GetNext execute back");
378 NAccessibilityInfoData* callbackInfo = (NAccessibilityInfoData*)data;
379 napi_value jsReturnValue = 0;
380 napi_value argv[ARGS_SIZE_TWO] = {0};
381 napi_value callback = 0;
382 napi_value undefined = 0;
383 napi_get_undefined(env, &undefined);
384
385 napi_get_reference_value(env, NElementInfo::consRef_, &NElementInfo::cons_);
386 napi_new_instance(env, NElementInfo::cons_, 0, nullptr, &argv[PARAM1]);
387 ConvertElementInfoToJS(env, argv[PARAM1], callbackInfo->nodeInfo_);
388
389 argv[PARAM0] = GetErrorValue(env, callbackInfo->ret_ ? CODE_SUCCESS : CODE_FAILED);
390 if (callbackInfo->callback_) {
391 // Callback mode
392 napi_get_reference_value(env, callbackInfo->callback_, &callback);
393 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, argv, &jsReturnValue);
394 napi_delete_reference(env, callbackInfo->callback_);
395 } else {
396 // Promise mode
397 if (callbackInfo->ret_) {
398 napi_resolve_deferred(env, callbackInfo->deferred_, argv[PARAM1]);
399 } else {
400 napi_reject_deferred(env, callbackInfo->deferred_, argv[PARAM0]);
401 }
402 }
403
404 napi_delete_async_work(env, callbackInfo->work_);
405 delete callbackInfo;
406 },
407 (void*)callbackInfo,
408 &callbackInfo->work_);
409 napi_queue_async_work(env, callbackInfo->work_);
410
411 return promise;
412 }
413
GetChild(napi_env env,napi_callback_info info)414 napi_value NElementInfo::GetChild(napi_env env, napi_callback_info info)
415 {
416 HILOG_INFO("start");
417 size_t argc = ARGS_SIZE_TWO;
418 napi_value argv[ARGS_SIZE_TWO] = {0};
419 napi_status status;
420 napi_value thisVar;
421 void* data = nullptr;
422 AccessibilityElementInfo* nodeInfo = nullptr;
423
424 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
425 HILOG_DEBUG("argc = %{public}d", (int)argc);
426 int childIndex;
427 napi_get_value_int32(env, argv[PARAM0], &childIndex);
428 HILOG_INFO("childIndex[%{public}d]", childIndex);
429
430 status = napi_unwrap(env, thisVar, (void**)&nodeInfo);
431 if (!nodeInfo) {
432 HILOG_ERROR("nodeInfo is null!!");
433 }
434
435 NAccessibilityInfoData *callbackInfo = new NAccessibilityInfoData();
436 callbackInfo->nativeNodeInfo_ = *nodeInfo;
437 callbackInfo->childIndex_ = childIndex;
438 napi_value promise = nullptr;
439 if (argc > ARGS_SIZE_ONE) {
440 HILOG_DEBUG("GetChild callback mode");
441 napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
442 napi_get_undefined(env, &promise);
443 } else {
444 HILOG_DEBUG("GetChild promise mode");
445 napi_create_promise(env, &callbackInfo->deferred_, &promise);
446 }
447 napi_value resource = nullptr;
448 napi_create_string_utf8(env, "GetChild", NAPI_AUTO_LENGTH, &resource);
449
450 napi_create_async_work(
451 env, nullptr, resource,
452 [](napi_env env, void* data) { // execute async to call c++ function
453 NAccessibilityInfoData *callbackInfo = (NAccessibilityInfoData*)data;
454 AccessibilityElementInfo nodeInfo = callbackInfo->nativeNodeInfo_;
455 callbackInfo->ret_ = nodeInfo.GetChild(callbackInfo->childIndex_, callbackInfo->nodeInfo_);
456 },
457 [](napi_env env, napi_status status, void* data) { // execute the complete function
458 HILOG_DEBUG("GetChild execute back");
459 NAccessibilityInfoData* callbackInfo = (NAccessibilityInfoData*)data;
460 napi_value jsReturnValue = 0;
461 napi_value argv[ARGS_SIZE_TWO] = {0};
462 napi_value callback = 0;
463 napi_value undefined = 0;
464 napi_get_undefined(env, &undefined);
465
466 napi_get_reference_value(env, NElementInfo::consRef_, &NElementInfo::cons_);
467 napi_new_instance(env, NElementInfo::cons_, 0, nullptr, &argv[PARAM1]);
468 ConvertElementInfoToJS(env, argv[PARAM1], callbackInfo->nodeInfo_);
469
470 argv[PARAM0] = GetErrorValue(env, callbackInfo->ret_ ? CODE_SUCCESS : CODE_FAILED);
471 if (callbackInfo->callback_) {
472 // Callback mode
473 napi_get_reference_value(env, callbackInfo->callback_, &callback);
474 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, argv, &jsReturnValue);
475 napi_delete_reference(env, callbackInfo->callback_);
476 } else {
477 // Promise mode
478 if (callbackInfo->ret_) {
479 napi_resolve_deferred(env, callbackInfo->deferred_, argv[PARAM1]);
480 } else {
481 napi_reject_deferred(env, callbackInfo->deferred_, argv[PARAM0]);
482 }
483 }
484
485 napi_delete_async_work(env, callbackInfo->work_);
486 delete callbackInfo;
487 },
488 (void*)callbackInfo,
489 &callbackInfo->work_);
490 napi_queue_async_work(env, callbackInfo->work_);
491
492 return promise;
493 }
494
GetParent(napi_env env,napi_callback_info info)495 napi_value NElementInfo::GetParent(napi_env env, napi_callback_info info)
496 {
497 HILOG_INFO("start");
498 size_t argc = ARGS_SIZE_ONE;
499 napi_value argv[ARGS_SIZE_ONE] = {0};
500 napi_status status;
501 napi_value thisVar;
502 void* data = nullptr;
503 AccessibilityElementInfo* nodeInfo = nullptr;
504
505 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
506 HILOG_DEBUG("argc = %{public}d", (int)argc);
507
508 status = napi_unwrap(env, thisVar, (void**)&nodeInfo);
509 if (!nodeInfo) {
510 HILOG_ERROR("nodeInfo is null!!");
511 }
512
513 NAccessibilityInfoData *callbackInfo = new NAccessibilityInfoData();
514 callbackInfo->nativeNodeInfo_ = *nodeInfo;
515
516 napi_value promise = nullptr;
517 if (argc > 0) {
518 HILOG_DEBUG("GetParent callback mode");
519 napi_create_reference(env, argv[PARAM0], 1, &callbackInfo->callback_);
520 napi_get_undefined(env, &promise);
521 } else {
522 HILOG_DEBUG("GetParent promise mode");
523 napi_create_promise(env, &callbackInfo->deferred_, &promise);
524 }
525 napi_value resource = nullptr;
526 napi_create_string_utf8(env, "GetParent", NAPI_AUTO_LENGTH, &resource);
527
528 napi_create_async_work(
529 env, nullptr, resource,
530 [](napi_env env, void* data) { // execute async to call c++ function
531 NAccessibilityInfoData *callbackInfo = (NAccessibilityInfoData*)data;
532 AccessibilityElementInfo nodeInfo = callbackInfo->nativeNodeInfo_;
533 callbackInfo->ret_ = nodeInfo.GetParent(callbackInfo->nodeInfo_);
534 },
535 [](napi_env env, napi_status status, void* data) { // execute the complete function
536 HILOG_DEBUG("GetParent execute back");
537 NAccessibilityInfoData* callbackInfo = (NAccessibilityInfoData*)data;
538 napi_value jsReturnValue = 0;
539 napi_value argv[ARGS_SIZE_TWO] = {0};
540 napi_value callback = 0;
541 napi_value undefined = 0;
542 napi_get_undefined(env, &undefined);
543
544 napi_get_reference_value(env, NElementInfo::consRef_, &NElementInfo::cons_);
545 napi_new_instance(env, NElementInfo::cons_, 0, nullptr, &argv[PARAM1]);
546 ConvertElementInfoToJS(env, argv[PARAM1], callbackInfo->nodeInfo_);
547
548 argv[PARAM0] = GetErrorValue(env, callbackInfo->ret_ ? CODE_SUCCESS : CODE_FAILED);
549 if (callbackInfo->callback_) {
550 // Callback mode
551 napi_get_reference_value(env, callbackInfo->callback_, &callback);
552 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, argv, &jsReturnValue);
553 napi_delete_reference(env, callbackInfo->callback_);
554 } else {
555 // Promise mode
556 if (callbackInfo->ret_) {
557 napi_resolve_deferred(env, callbackInfo->deferred_, argv[PARAM1]);
558 } else {
559 napi_reject_deferred(env, callbackInfo->deferred_, argv[PARAM0]);
560 }
561 }
562
563 napi_delete_async_work(env, callbackInfo->work_);
564 delete callbackInfo;
565 },
566 (void*)callbackInfo,
567 &callbackInfo->work_);
568 napi_queue_async_work(env, callbackInfo->work_);
569
570 return promise;
571 }