• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_accessibility_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 }