• 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_element.h"
17 #include <algorithm>
18 #include <map>
19 #include <vector>
20 #include "accessible_ability_client.h"
21 #include "hilog_wrapper.h"
22 #include "accessibility_utils.h"
23 
24 using namespace OHOS;
25 using namespace OHOS::Accessibility;
26 using namespace OHOS::AccessibilityNapi;
27 namespace {
28     const std::vector<std::string> ELEMENT_INFO_ATTRIBUTE_NAMES = {"componentId", "inspectorKey",
29         "bundleName", "componentType", "inputType", "text", "hintText", "description", "triggerAction",
30         "textMoveUnit", "contents", "lastContent", "itemCount", "currentIndex", "startIndex", "endIndex",
31         "resourceName", "textLengthLimit", "rect", "checkable", "checked", "focusable", "isVisible",
32         "selected", "clickable", "longClickable", "isEnable", "isPassword", "scrollable",
33         "editable", "pluralLineSupported", "parent", "children", "isFocused", "accessibilityFocused",
34         "error", "isHint", "pageId", "valueMax", "valueMin", "valueNow", "windowId"};
35     const std::vector<std::string> WINDOW_INFO_ATTRIBUTE_NAMES = {"isActive", "screenRect", "layer", "type",
36         "rootElement", "isFocused", "windowId"};
37 
38     using AttributeNamesFunc = void (*)(NAccessibilityElementData *callbackInfo, napi_value &value);
39     std::map<std::string, AttributeNamesFunc> elementInfoCompleteMap = {
40         {"componentId", &NAccessibilityElement::GetElementInfoComponentId},
41         {"inspectorKey", &NAccessibilityElement::GetElementInfoInspectorKey},
42         {"bundleName", &NAccessibilityElement::GetElementInfoBundleName},
43         {"componentType", &NAccessibilityElement::GetElementInfoComponentType},
44         {"inputType", &NAccessibilityElement::GetElementInfoInputType},
45         {"text", &NAccessibilityElement::GetElementInfoText},
46         {"hintText", &NAccessibilityElement::GetElementInfoHintText},
47         {"description", &NAccessibilityElement::GetElementInfoDescription},
48         {"resourceName", &NAccessibilityElement::GetElementInfoResourceName},
49         {"textLengthLimit", &NAccessibilityElement::GetElementInfoTextLengthLimit},
50         {"rect", &NAccessibilityElement::GetElementInfoRect},
51         {"checkable", &NAccessibilityElement::GetElementInfoCheckable},
52         {"checked", &NAccessibilityElement::GetElementInfoChecked},
53         {"focusable", &NAccessibilityElement::GetElementInfoFocusable},
54         {"isVisible", &NAccessibilityElement::GetElementInfoIsVisible},
55         {"selected", &NAccessibilityElement::GetElementInfoSelected},
56         {"clickable", &NAccessibilityElement::GetElementInfoClickable},
57         {"longClickable", &NAccessibilityElement::GetElementInfoLongClickable},
58         {"isEnable", &NAccessibilityElement::GetElementInfoIsEnable},
59         {"isPassword", &NAccessibilityElement::GetElementInfoIsPassword},
60         {"scrollable", &NAccessibilityElement::GetElementInfoScrollable},
61         {"editable", &NAccessibilityElement::GetElementInfoEditable},
62         {"pluralLineSupported", &NAccessibilityElement::GetElementInfoPluralLineSupported},
63         {"itemCount", &NAccessibilityElement::GetElementInfoItemCount},
64         {"currentIndex", &NAccessibilityElement::GetElementInfoCurrentIndex},
65         {"startIndex", &NAccessibilityElement::GetElementInfoStartIndex},
66         {"endIndex", &NAccessibilityElement::GetElementInfoEndIndex},
67         {"textMoveUnit", &NAccessibilityElement::GetElementInfoTextMoveUnit},
68         {"parent", &NAccessibilityElement::GetElementInfoParent},
69         {"children", &NAccessibilityElement::GetElementInfoChildren},
70         {"triggerAction", &NAccessibilityElement::GetElementInfoTriggerAction},
71         {"contents", &NAccessibilityElement::GetElementInfoContents},
72         {"lastContent", &NAccessibilityElement::GetElementInfoLastContent},
73         {"isFocused", &NAccessibilityElement::GetElementInfoIsFocused},
74         {"accessibilityFocused", &NAccessibilityElement::GetElementInfoAccessibilityFocused},
75         {"error", &NAccessibilityElement::GetElementInfoError},
76         {"isHint", &NAccessibilityElement::GetElementInfoIsHint},
77         {"pageId", &NAccessibilityElement::GetElementInfoPageId},
78         {"valueMax", &NAccessibilityElement::GetElementInfoValueMax},
79         {"valueMin", &NAccessibilityElement::GetElementInfoValueMin},
80         {"valueNow", &NAccessibilityElement::GetElementInfoValueNow},
81         {"windowId", &NAccessibilityElement::GetElementInfoWindowId},
82     };
83     std::map<std::string, AttributeNamesFunc> windowInfoCompleteMap = {
84         {"isActive", &NAccessibilityElement::GetWindowInfoIsActive},
85         {"screenRect", &NAccessibilityElement::GetWindowInfoScreenRect},
86         {"layer", &NAccessibilityElement::GetWindowInfoLayer},
87         {"type", &NAccessibilityElement::GetWindowInfoType},
88         {"rootElement", &NAccessibilityElement::GetWindowInfoRootElement},
89         {"isFocused", &NAccessibilityElement::GetWindowInfoIsFocused},
90         {"windowId", &NAccessibilityElement::GetWindowInfoWindowId},
91     };
92 } // namespace
93 
94 thread_local napi_ref NAccessibilityElement::consRef_ = nullptr;
95 
DefineJSAccessibilityElement(napi_env env)96 void NAccessibilityElement::DefineJSAccessibilityElement(napi_env env)
97 {
98     napi_property_descriptor descForAccessibilityElement[] = {
99         DECLARE_NAPI_FUNCTION("attributeNames", NAccessibilityElement::AttributeNames),
100         DECLARE_NAPI_FUNCTION("attributeValue", NAccessibilityElement::AttributeValue),
101         DECLARE_NAPI_FUNCTION("actionNames", NAccessibilityElement::ActionNames),
102         DECLARE_NAPI_FUNCTION("performAction", NAccessibilityElement::PerformAction),
103         DECLARE_NAPI_FUNCTION("findElement", NAccessibilityElement::FindElement),
104     };
105 
106     napi_value constructor = nullptr;
107 
108     NAPI_CALL_RETURN_VOID(env,
109         napi_define_class(env,
110             "AccessibilityElement",
111             NAPI_AUTO_LENGTH,
112             NAccessibilityElement::JSConstructor,
113             nullptr,
114             sizeof(descForAccessibilityElement) / sizeof(descForAccessibilityElement[0]),
115             descForAccessibilityElement,
116             &constructor));
117     napi_create_reference(env, constructor, 1, &NAccessibilityElement::consRef_);
118 }
119 
JSConstructor(napi_env env,napi_callback_info info)120 napi_value NAccessibilityElement::JSConstructor(napi_env env, napi_callback_info info)
121 {
122     napi_value jsthis = nullptr;
123     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
124     return jsthis;
125 }
126 
ConvertElementInfoToJS(napi_env env,napi_value result,const AccessibilityElementInfo & elementInfo)127 void NAccessibilityElement::ConvertElementInfoToJS(napi_env env, napi_value result,
128     const AccessibilityElementInfo& elementInfo)
129 {
130     // Bind js object to a Native object
131     std::shared_ptr<AccessibilityElementInfo> elementInformation =
132         std::make_shared<AccessibilityElementInfo>(elementInfo);
133     AccessibilityElement* pAccessibilityElement = new(std::nothrow) AccessibilityElement(elementInformation);
134     if (!pAccessibilityElement) {
135         HILOG_ERROR("Failed to create elementInformation.");
136         return;
137     }
138     napi_status sts = napi_wrap(
139         env,
140         result,
141         pAccessibilityElement,
142         [](napi_env env, void* data, void* hint) {
143             AccessibilityElement* info = static_cast<AccessibilityElement*>(data);
144             delete info;
145             info = nullptr;
146         },
147         nullptr,
148         nullptr);
149     HILOG_DEBUG("napi_wrap status: %{public}d", (int)sts);
150 }
151 
ConvertElementInfosToJS(napi_env env,napi_value result,const std::vector<OHOS::Accessibility::AccessibilityElementInfo> & elementInfos)152 void NAccessibilityElement::ConvertElementInfosToJS(
153     napi_env env, napi_value result, const std::vector<OHOS::Accessibility::AccessibilityElementInfo>& elementInfos)
154 {
155     HILOG_DEBUG("elementInfo size(%{public}zu)", elementInfos.size());
156 
157     napi_value constructor = nullptr;
158     napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
159 
160     size_t index = 0;
161     for (auto& elementInfo : elementInfos) {
162         napi_value obj = nullptr;
163         napi_status status = napi_new_instance(env, constructor, 0, nullptr, &obj);
164         HILOG_INFO("status is %{public}d", status);
165         ConvertElementInfoToJS(env, obj, elementInfo);
166         napi_set_element(env, result, index, obj);
167         index++;
168     }
169 }
170 
AttributeNames(napi_env env,napi_callback_info info)171 napi_value NAccessibilityElement::AttributeNames(napi_env env, napi_callback_info info)
172 {
173     HILOG_INFO();
174     size_t argc = ARGS_SIZE_ONE;
175     napi_value argv = nullptr;
176     napi_value thisVar = nullptr;
177     void* data = nullptr;
178     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data));
179     HILOG_DEBUG("argc = %{public}d", (int)argc);
180 
181     NAccessibilityElementData *callbackInfo = new(std::nothrow) NAccessibilityElementData();
182     if (!callbackInfo) {
183         HILOG_ERROR("Failed to create callbackInfo.");
184         return nullptr;
185     }
186     callbackInfo->env_ = env;
187 
188     napi_value promise = nullptr;
189     if (argc > ARGS_SIZE_ONE - 1) {
190         napi_valuetype valueType = napi_null;
191         napi_typeof(env, argv, &valueType);
192         if (valueType == napi_function) {
193             napi_create_reference(env, argv, 1, &callbackInfo->callback_);
194             napi_get_undefined(env, &promise);
195         } else {
196             napi_create_promise(env, &callbackInfo->deferred_, &promise);
197         }
198     } else {
199         napi_create_promise(env, &callbackInfo->deferred_, &promise);
200     }
201 
202     AccessibilityElement* accessibilityElement = nullptr;
203     napi_status status = napi_unwrap(env, thisVar, (void**)&accessibilityElement);
204     if (!accessibilityElement || status != napi_ok) {
205         HILOG_ERROR("accessibilityElement is null or status[%{public}d] is wrong", status);
206         return ErrorOperation(callbackInfo);
207     }
208     callbackInfo->accessibilityElement_ = *accessibilityElement;
209 
210     napi_value resource = nullptr;
211     napi_create_string_utf8(env, "AttributeNames", NAPI_AUTO_LENGTH, &resource);
212     napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {},
213         // Execute the complete function
214         AttributeNamesComplete,
215         reinterpret_cast<void*>(callbackInfo),
216         &callbackInfo->work_);
217     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
218     return promise;
219 }
220 
AttributeNamesComplete(napi_env env,napi_status status,void * data)221 void NAccessibilityElement::AttributeNamesComplete(napi_env env, napi_status status, void* data)
222 {
223     HILOG_INFO("AttributeNameComplete execute back");
224     NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
225     napi_value result[ARGS_SIZE_TWO] = {0};
226     napi_value callback = 0;
227     napi_value undefined = 0;
228     napi_get_undefined(env, &undefined);
229     if (!callbackInfo) {
230         HILOG_ERROR("callbackInfo is nullptr");
231         return;
232     }
233 
234     napi_create_array(env, &result[1]);
235     if (callbackInfo->accessibilityElement_.isElementInfo_) {
236         HILOG_DEBUG("covert element info to js");
237         ConvertStringVecToJS(env, result[1], ELEMENT_INFO_ATTRIBUTE_NAMES);
238     } else {
239         HILOG_DEBUG("covert window info to js");
240         ConvertStringVecToJS(env, result[1], WINDOW_INFO_ATTRIBUTE_NAMES);
241     }
242 
243     if (callbackInfo->callback_) {
244         // Callback mode
245         result[PARAM0] = CreateBusinessError(env, OHOS::Accessibility::RetError::RET_OK);
246         napi_get_reference_value(env, callbackInfo->callback_, &callback);
247         napi_value returnVal;
248         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
249         napi_delete_reference(env, callbackInfo->callback_);
250     } else {
251         // Promise mode
252         napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
253     }
254     napi_delete_async_work(env, callbackInfo->work_);
255     delete callbackInfo;
256     callbackInfo = nullptr;
257 }
258 
AttributeValue(napi_env env,napi_callback_info info)259 napi_value NAccessibilityElement::AttributeValue(napi_env env, napi_callback_info info)
260 {
261     size_t argc = ARGS_SIZE_TWO;
262     napi_value argv[ARGS_SIZE_TWO] = {0};
263     napi_value thisVar = nullptr;
264     void* data = nullptr;
265     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
266     if (status != napi_ok) {
267         HILOG_ERROR("Failed to get cb info");
268         napi_value err = CreateBusinessError(env, RetError::RET_ERR_FAILED);
269         napi_throw(env, err);
270         return nullptr;
271     }
272     HILOG_DEBUG("argc = %{public}d", (int)argc);
273 
274     // Unwrap AccessibilityElement
275     AccessibilityElement* accessibilityElement = nullptr;
276     status = napi_unwrap(env, thisVar, (void**)&accessibilityElement);
277     if (!accessibilityElement || status != napi_ok) {
278         HILOG_ERROR("accessibilityElement is null or status[%{public}d] is wrong", status);
279         napi_value err = CreateBusinessError(env, RetError::RET_ERR_NULLPTR);
280         napi_throw(env, err);
281         return nullptr;
282     }
283 
284     NAccessibilityElementData *callbackInfo = new(std::nothrow) NAccessibilityElementData();
285     if (!callbackInfo) {
286         HILOG_ERROR("Failed to create callbackInfo.");
287         napi_value err = CreateBusinessError(env, RetError::RET_ERR_NULLPTR);
288         napi_throw(env, err);
289         return nullptr;
290     }
291     callbackInfo->env_ = env;
292     callbackInfo->accessibilityElement_ = *accessibilityElement;
293 
294     NAccessibilityErrorCode errCode = GetAttribute(env, argc, argv, callbackInfo);
295     if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
296         delete callbackInfo;
297         callbackInfo = nullptr;
298         delete accessibilityElement;
299         accessibilityElement = nullptr;
300         napi_value err = CreateBusinessError(env, RetError::RET_ERR_INVALID_PARAM);
301         HILOG_ERROR("invalid param");
302         napi_throw(env, err);
303         return nullptr;
304     }
305 
306     return AttributeValueAsync(env, argc, argv, callbackInfo);
307 }
308 
GetAttribute(napi_env env,size_t argc,napi_value * argv,NAccessibilityElementData * callbackInfo)309 NAccessibilityErrorCode NAccessibilityElement::GetAttribute(
310     napi_env env, size_t argc, napi_value* argv, NAccessibilityElementData* callbackInfo)
311 {
312     NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
313     if (argc < ARGS_SIZE_TWO - 1) {
314         HILOG_ERROR("argc is invalid: %{public}zu", argc);
315         errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
316     }
317 
318     if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
319         // Parse attribute name
320         std::string attribute = "";
321         if (ParseString(env, attribute, argv[PARAM0])) {
322             HILOG_INFO("attribute = %{public}s", attribute.c_str());
323             callbackInfo->attribute_ = attribute;
324         } else {
325             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
326         }
327     }
328     return errCode;
329 }
330 
AttributeValueAsync(napi_env env,size_t argc,napi_value * argv,NAccessibilityElementData * callbackInfo)331 napi_value NAccessibilityElement::AttributeValueAsync(
332     napi_env env, size_t argc, napi_value* argv, NAccessibilityElementData* callbackInfo)
333 {
334     napi_value promise = nullptr;
335     if (argc > ARGS_SIZE_TWO - 1) {
336         napi_valuetype valueType = napi_null;
337         napi_typeof(env, argv[PARAM1], &valueType);
338         if (valueType == napi_function) {
339             napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
340             napi_get_undefined(env, &promise);
341         } else {
342             napi_create_promise(env, &callbackInfo->deferred_, &promise);
343         }
344     } else {
345         napi_create_promise(env, &callbackInfo->deferred_, &promise);
346     }
347 
348     napi_value resource = nullptr;
349     napi_create_string_utf8(env, "AttributeValue", NAPI_AUTO_LENGTH, &resource);
350     napi_create_async_work(env, nullptr, resource, NAccessibilityElement::AttributeValueExecute,
351         NAccessibilityElement::AttributeValueComplete, reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
352     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
353     return promise;
354 }
355 
AttributeValueExecute(napi_env env,void * data)356 void NAccessibilityElement::AttributeValueExecute(napi_env env, void* data)
357 {
358     NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
359     if (!callbackInfo) {
360         HILOG_ERROR("callbackInfo is nullptr");
361         return;
362     }
363 
364     if (callbackInfo->attribute_ == "parent") {
365         if (callbackInfo->accessibilityElement_.elementInfo_) {
366             callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->GetParentElementInfo(
367                 *callbackInfo->accessibilityElement_.elementInfo_, callbackInfo->nodeInfo_);
368         } else {
369             HILOG_ERROR("elementInfo is nullptr");
370         }
371     } else if (callbackInfo->attribute_ == "children") {
372         if (callbackInfo->accessibilityElement_.elementInfo_) {
373             callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->GetChildren(
374                 *callbackInfo->accessibilityElement_.elementInfo_, callbackInfo->nodeInfos_);
375         } else {
376             HILOG_ERROR("elementInfo is nullptr");
377         }
378     } else if (callbackInfo->attribute_ == "rootElement") {
379         if (callbackInfo->accessibilityElement_.windowInfo_) {
380             callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->GetRootByWindow(
381                 *callbackInfo->accessibilityElement_.windowInfo_, callbackInfo->nodeInfo_);
382         } else {
383             HILOG_ERROR("windowInfo is nullptr");
384         }
385     } else {
386         callbackInfo->ret_ = RET_OK;
387     }
388     HILOG_INFO("attribute[%{public}s], result[%{public}d]", callbackInfo->attribute_.c_str(), callbackInfo->ret_);
389 }
390 
AttributeValueComplete(napi_env env,napi_status status,void * data)391 void NAccessibilityElement::AttributeValueComplete(napi_env env, napi_status status, void* data)
392 {
393     NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
394     if (!callbackInfo) {
395         HILOG_ERROR("callbackInfo is nullptr");
396         return;
397     }
398     napi_value result[ARGS_SIZE_TWO] = {0};
399 
400     if (callbackInfo->accessibilityElement_.isElementInfo_) {
401         HILOG_DEBUG("It is element info");
402         auto elementIter = elementInfoCompleteMap.find(callbackInfo->attribute_);
403         if (elementIter == elementInfoCompleteMap.end()) {
404             HILOG_ERROR("There is no the attribute[%{public}s] in element info", callbackInfo->attribute_.c_str());
405             napi_get_undefined(callbackInfo->env_, &result[PARAM1]);
406             callbackInfo->ret_ = RET_ERR_PROPERTY_NOT_EXIST;
407         } else {
408             (*elementIter->second)(callbackInfo, result[PARAM1]);
409         }
410     } else {
411         HILOG_DEBUG("It is window info");
412         auto windowIter = windowInfoCompleteMap.find(callbackInfo->attribute_);
413         if (windowIter == windowInfoCompleteMap.end()) {
414             HILOG_ERROR("There is no the attribute[%{public}s]", callbackInfo->attribute_.c_str());
415             napi_get_undefined(callbackInfo->env_, &result[PARAM1]);
416             callbackInfo->ret_ = RET_ERR_PROPERTY_NOT_EXIST;
417         } else {
418             (*windowIter->second)(callbackInfo, result[PARAM1]);
419         }
420     }
421 
422     HILOG_DEBUG("result is %{public}d", callbackInfo->ret_);
423     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
424     if (callbackInfo->callback_) {
425         napi_value callback;
426         napi_value returnVal;
427         napi_value undefined;
428         napi_get_reference_value(env, callbackInfo->callback_, &callback);
429         napi_get_undefined(env, &undefined);
430         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
431         napi_delete_reference(env, callbackInfo->callback_);
432     } else {
433         if (callbackInfo->ret_ == RET_OK) {
434             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
435         } else {
436             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
437         }
438     }
439     napi_delete_async_work(env, callbackInfo->work_);
440     delete callbackInfo;
441     callbackInfo = nullptr;
442 }
443 
CheckElementInfoParameter(NAccessibilityElementData * callbackInfo,napi_value & value)444 bool NAccessibilityElement::CheckElementInfoParameter(NAccessibilityElementData *callbackInfo, napi_value &value)
445 {
446     if (!callbackInfo) {
447         HILOG_ERROR("callbackInfo is nullptr");
448         return false;
449     }
450     if (!callbackInfo->accessibilityElement_.elementInfo_) {
451         HILOG_ERROR("element info is nullptr");
452         napi_get_undefined(callbackInfo->env_, &value);
453         callbackInfo->ret_ = RET_ERR_FAILED;
454         return false;
455     }
456     return true;
457 }
458 
GetElementInfoComponentId(NAccessibilityElementData * callbackInfo,napi_value & value)459 void NAccessibilityElement::GetElementInfoComponentId(NAccessibilityElementData *callbackInfo, napi_value &value)
460 {
461     if (!CheckElementInfoParameter(callbackInfo, value)) {
462         return;
463     }
464     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
465         callbackInfo->accessibilityElement_.elementInfo_->GetAccessibilityId(), &value));
466 }
467 
GetElementInfoPageId(NAccessibilityElementData * callbackInfo,napi_value & value)468 void NAccessibilityElement::GetElementInfoPageId(NAccessibilityElementData *callbackInfo, napi_value &value)
469 {
470     if (!CheckElementInfoParameter(callbackInfo, value)) {
471         return;
472     }
473     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
474         callbackInfo->accessibilityElement_.elementInfo_->GetPageId(), &value));
475 }
476 
GetElementInfoInspectorKey(NAccessibilityElementData * callbackInfo,napi_value & value)477 void NAccessibilityElement::GetElementInfoInspectorKey(NAccessibilityElementData *callbackInfo, napi_value &value)
478 {
479     if (!CheckElementInfoParameter(callbackInfo, value)) {
480         return;
481     }
482     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
483         callbackInfo->accessibilityElement_.elementInfo_->GetInspectorKey().c_str(), NAPI_AUTO_LENGTH, &value));
484 }
485 
GetElementInfoBundleName(NAccessibilityElementData * callbackInfo,napi_value & value)486 void NAccessibilityElement::GetElementInfoBundleName(NAccessibilityElementData *callbackInfo, napi_value &value)
487 {
488     if (!CheckElementInfoParameter(callbackInfo, value)) {
489         return;
490     }
491     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
492         callbackInfo->accessibilityElement_.elementInfo_->GetBundleName().c_str(), NAPI_AUTO_LENGTH, &value));
493 }
494 
GetElementInfoComponentType(NAccessibilityElementData * callbackInfo,napi_value & value)495 void NAccessibilityElement::GetElementInfoComponentType(NAccessibilityElementData *callbackInfo, napi_value &value)
496 {
497     if (!CheckElementInfoParameter(callbackInfo, value)) {
498         return;
499     }
500     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
501         callbackInfo->accessibilityElement_.elementInfo_->GetComponentType().c_str(), NAPI_AUTO_LENGTH, &value));
502 }
503 
GetElementInfoInputType(NAccessibilityElementData * callbackInfo,napi_value & value)504 void NAccessibilityElement::GetElementInfoInputType(NAccessibilityElementData *callbackInfo, napi_value &value)
505 {
506     if (!CheckElementInfoParameter(callbackInfo, value)) {
507         return;
508     }
509     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
510         callbackInfo->accessibilityElement_.elementInfo_->GetInputType(), &value));
511 }
512 
GetElementInfoText(NAccessibilityElementData * callbackInfo,napi_value & value)513 void NAccessibilityElement::GetElementInfoText(NAccessibilityElementData *callbackInfo, napi_value &value)
514 {
515     if (!CheckElementInfoParameter(callbackInfo, value)) {
516         return;
517     }
518     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
519         callbackInfo->accessibilityElement_.elementInfo_->GetContent().c_str(), NAPI_AUTO_LENGTH, &value));
520 }
521 
GetElementInfoHintText(NAccessibilityElementData * callbackInfo,napi_value & value)522 void NAccessibilityElement::GetElementInfoHintText(NAccessibilityElementData *callbackInfo, napi_value &value)
523 {
524     if (!CheckElementInfoParameter(callbackInfo, value)) {
525         return;
526     }
527     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
528         callbackInfo->accessibilityElement_.elementInfo_->GetHint().c_str(), NAPI_AUTO_LENGTH, &value));
529 }
530 
GetElementInfoDescription(NAccessibilityElementData * callbackInfo,napi_value & value)531 void NAccessibilityElement::GetElementInfoDescription(NAccessibilityElementData *callbackInfo, napi_value &value)
532 {
533     if (!CheckElementInfoParameter(callbackInfo, value)) {
534         return;
535     }
536     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
537         callbackInfo->accessibilityElement_.elementInfo_->GetDescriptionInfo().c_str(), NAPI_AUTO_LENGTH, &value));
538 }
539 
GetElementInfoResourceName(NAccessibilityElementData * callbackInfo,napi_value & value)540 void NAccessibilityElement::GetElementInfoResourceName(NAccessibilityElementData *callbackInfo, napi_value &value)
541 {
542     if (!CheckElementInfoParameter(callbackInfo, value)) {
543         return;
544     }
545     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
546         callbackInfo->accessibilityElement_.elementInfo_->GetComponentResourceId().c_str(), NAPI_AUTO_LENGTH, &value));
547 }
548 
GetElementInfoTextLengthLimit(NAccessibilityElementData * callbackInfo,napi_value & value)549 void NAccessibilityElement::GetElementInfoTextLengthLimit(NAccessibilityElementData *callbackInfo, napi_value &value)
550 {
551     if (!CheckElementInfoParameter(callbackInfo, value)) {
552         return;
553     }
554     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
555         callbackInfo->accessibilityElement_.elementInfo_->GetTextLengthLimit(), &value));
556 }
557 
GetElementInfoRect(NAccessibilityElementData * callbackInfo,napi_value & value)558 void NAccessibilityElement::GetElementInfoRect(NAccessibilityElementData *callbackInfo, napi_value &value)
559 {
560     if (!CheckElementInfoParameter(callbackInfo, value)) {
561         return;
562     }
563     OHOS::Accessibility::Rect screenRect = callbackInfo->accessibilityElement_.elementInfo_->GetRectInScreen();
564     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_object(callbackInfo->env_, &value));
565     ConvertRectToJS(callbackInfo->env_, value, screenRect);
566 }
567 
GetElementInfoCheckable(NAccessibilityElementData * callbackInfo,napi_value & value)568 void NAccessibilityElement::GetElementInfoCheckable(NAccessibilityElementData *callbackInfo, napi_value &value)
569 {
570     if (!CheckElementInfoParameter(callbackInfo, value)) {
571         return;
572     }
573     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
574         callbackInfo->accessibilityElement_.elementInfo_->IsCheckable(), &value));
575 }
576 
GetElementInfoChecked(NAccessibilityElementData * callbackInfo,napi_value & value)577 void NAccessibilityElement::GetElementInfoChecked(NAccessibilityElementData *callbackInfo, napi_value &value)
578 {
579     if (!CheckElementInfoParameter(callbackInfo, value)) {
580         return;
581     }
582     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
583         callbackInfo->accessibilityElement_.elementInfo_->IsChecked(), &value));
584 }
585 
GetElementInfoFocusable(NAccessibilityElementData * callbackInfo,napi_value & value)586 void NAccessibilityElement::GetElementInfoFocusable(NAccessibilityElementData *callbackInfo, napi_value &value)
587 {
588     if (!CheckElementInfoParameter(callbackInfo, value)) {
589         return;
590     }
591     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
592         callbackInfo->accessibilityElement_.elementInfo_->IsFocusable(), &value));
593 }
594 
GetElementInfoIsVisible(NAccessibilityElementData * callbackInfo,napi_value & value)595 void NAccessibilityElement::GetElementInfoIsVisible(NAccessibilityElementData *callbackInfo, napi_value &value)
596 {
597     if (!CheckElementInfoParameter(callbackInfo, value)) {
598         return;
599     }
600     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
601         callbackInfo->accessibilityElement_.elementInfo_->IsVisible(), &value));
602 }
603 
GetElementInfoAccessibilityFocused(NAccessibilityElementData * callbackInfo,napi_value & value)604 void NAccessibilityElement::GetElementInfoAccessibilityFocused(
605     NAccessibilityElementData *callbackInfo, napi_value &value)
606 {
607     if (!CheckElementInfoParameter(callbackInfo, value)) {
608         return;
609     }
610     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
611         callbackInfo->accessibilityElement_.elementInfo_->HasAccessibilityFocus(), &value));
612 }
613 
GetElementInfoSelected(NAccessibilityElementData * callbackInfo,napi_value & value)614 void NAccessibilityElement::GetElementInfoSelected(NAccessibilityElementData *callbackInfo, napi_value &value)
615 {
616     if (!CheckElementInfoParameter(callbackInfo, value)) {
617         return;
618     }
619     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
620         callbackInfo->accessibilityElement_.elementInfo_->IsSelected(), &value));
621 }
622 
GetElementInfoClickable(NAccessibilityElementData * callbackInfo,napi_value & value)623 void NAccessibilityElement::GetElementInfoClickable(NAccessibilityElementData *callbackInfo, napi_value &value)
624 {
625     if (!CheckElementInfoParameter(callbackInfo, value)) {
626         return;
627     }
628     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
629         callbackInfo->accessibilityElement_.elementInfo_->IsClickable(), &value));
630 }
631 
GetElementInfoLongClickable(NAccessibilityElementData * callbackInfo,napi_value & value)632 void NAccessibilityElement::GetElementInfoLongClickable(NAccessibilityElementData *callbackInfo, napi_value &value)
633 {
634     if (!CheckElementInfoParameter(callbackInfo, value)) {
635         return;
636     }
637     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
638         callbackInfo->accessibilityElement_.elementInfo_->IsLongClickable(), &value));
639 }
640 
GetElementInfoIsEnable(NAccessibilityElementData * callbackInfo,napi_value & value)641 void NAccessibilityElement::GetElementInfoIsEnable(NAccessibilityElementData *callbackInfo, napi_value &value)
642 {
643     if (!CheckElementInfoParameter(callbackInfo, value)) {
644         return;
645     }
646     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
647         callbackInfo->accessibilityElement_.elementInfo_->IsEnabled(), &value));
648 }
649 
GetElementInfoIsPassword(NAccessibilityElementData * callbackInfo,napi_value & value)650 void NAccessibilityElement::GetElementInfoIsPassword(NAccessibilityElementData *callbackInfo, napi_value &value)
651 {
652     if (!CheckElementInfoParameter(callbackInfo, value)) {
653         return;
654     }
655     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
656         callbackInfo->accessibilityElement_.elementInfo_->IsPassword(), &value));
657 }
658 
GetElementInfoScrollable(NAccessibilityElementData * callbackInfo,napi_value & value)659 void NAccessibilityElement::GetElementInfoScrollable(NAccessibilityElementData *callbackInfo, napi_value &value)
660 {
661     if (!CheckElementInfoParameter(callbackInfo, value)) {
662         return;
663     }
664     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
665         callbackInfo->accessibilityElement_.elementInfo_->IsScrollable(), &value));
666 }
667 
GetElementInfoEditable(NAccessibilityElementData * callbackInfo,napi_value & value)668 void NAccessibilityElement::GetElementInfoEditable(NAccessibilityElementData *callbackInfo, napi_value &value)
669 {
670     if (!CheckElementInfoParameter(callbackInfo, value)) {
671         return;
672     }
673     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
674         callbackInfo->accessibilityElement_.elementInfo_->IsEditable(), &value));
675 }
676 
GetElementInfoPluralLineSupported(NAccessibilityElementData * callbackInfo,napi_value & value)677 void NAccessibilityElement::GetElementInfoPluralLineSupported(
678     NAccessibilityElementData *callbackInfo, napi_value &value)
679 {
680     if (!CheckElementInfoParameter(callbackInfo, value)) {
681         return;
682     }
683     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
684         callbackInfo->accessibilityElement_.elementInfo_->IsPluraLineSupported(), &value));
685 }
686 
GetElementInfoIsHint(NAccessibilityElementData * callbackInfo,napi_value & value)687 void NAccessibilityElement::GetElementInfoIsHint(NAccessibilityElementData *callbackInfo, napi_value &value)
688 {
689     if (!CheckElementInfoParameter(callbackInfo, value)) {
690         return;
691     }
692     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
693         callbackInfo->accessibilityElement_.elementInfo_->IsGivingHint(), &value));
694 }
695 
GetElementInfoItemCount(NAccessibilityElementData * callbackInfo,napi_value & value)696 void NAccessibilityElement::GetElementInfoItemCount(NAccessibilityElementData *callbackInfo, napi_value &value)
697 {
698     if (!CheckElementInfoParameter(callbackInfo, value)) {
699         return;
700     }
701     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
702         callbackInfo->accessibilityElement_.elementInfo_->GetItemCounts(), &value));
703 }
704 
GetElementInfoCurrentIndex(NAccessibilityElementData * callbackInfo,napi_value & value)705 void NAccessibilityElement::GetElementInfoCurrentIndex(NAccessibilityElementData *callbackInfo, napi_value &value)
706 {
707     if (!CheckElementInfoParameter(callbackInfo, value)) {
708         return;
709     }
710     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
711         callbackInfo->accessibilityElement_.elementInfo_->GetCurrentIndex(), &value));
712 }
713 
GetElementInfoStartIndex(NAccessibilityElementData * callbackInfo,napi_value & value)714 void NAccessibilityElement::GetElementInfoStartIndex(NAccessibilityElementData *callbackInfo, napi_value &value)
715 {
716     if (!CheckElementInfoParameter(callbackInfo, value)) {
717         return;
718     }
719     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
720         callbackInfo->accessibilityElement_.elementInfo_->GetBeginIndex(), &value));
721 }
722 
GetElementInfoEndIndex(NAccessibilityElementData * callbackInfo,napi_value & value)723 void NAccessibilityElement::GetElementInfoEndIndex(NAccessibilityElementData *callbackInfo, napi_value &value)
724 {
725     if (!CheckElementInfoParameter(callbackInfo, value)) {
726         return;
727     }
728     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
729         callbackInfo->accessibilityElement_.elementInfo_->GetEndIndex(), &value));
730 }
731 
GetElementInfoValueMax(NAccessibilityElementData * callbackInfo,napi_value & value)732 void NAccessibilityElement::GetElementInfoValueMax(NAccessibilityElementData *callbackInfo, napi_value &value)
733 {
734     if (!CheckElementInfoParameter(callbackInfo, value)) {
735         return;
736     }
737     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
738         callbackInfo->accessibilityElement_.elementInfo_->GetRange().GetMax(), &value));
739 }
740 
GetElementInfoValueMin(NAccessibilityElementData * callbackInfo,napi_value & value)741 void NAccessibilityElement::GetElementInfoValueMin(NAccessibilityElementData *callbackInfo, napi_value &value)
742 {
743     if (!CheckElementInfoParameter(callbackInfo, value)) {
744         return;
745     }
746     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
747         callbackInfo->accessibilityElement_.elementInfo_->GetRange().GetMin(), &value));
748 }
749 
GetElementInfoValueNow(NAccessibilityElementData * callbackInfo,napi_value & value)750 void NAccessibilityElement::GetElementInfoValueNow(NAccessibilityElementData *callbackInfo, napi_value &value)
751 {
752     if (!CheckElementInfoParameter(callbackInfo, value)) {
753         return;
754     }
755     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
756         callbackInfo->accessibilityElement_.elementInfo_->GetRange().GetCurrent(), &value));
757 }
758 
GetElementInfoError(NAccessibilityElementData * callbackInfo,napi_value & value)759 void NAccessibilityElement::GetElementInfoError(NAccessibilityElementData *callbackInfo, napi_value &value)
760 {
761     if (!CheckElementInfoParameter(callbackInfo, value)) {
762         return;
763     }
764     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
765         callbackInfo->accessibilityElement_.elementInfo_->GetError().c_str(), NAPI_AUTO_LENGTH, &value));
766 }
767 
GetElementInfoTextMoveUnit(NAccessibilityElementData * callbackInfo,napi_value & value)768 void NAccessibilityElement::GetElementInfoTextMoveUnit(NAccessibilityElementData *callbackInfo, napi_value &value)
769 {
770     if (!CheckElementInfoParameter(callbackInfo, value)) {
771         return;
772     }
773     std::string textMoveUnit = ConvertTextMoveUnitToString(
774         callbackInfo->accessibilityElement_.elementInfo_->GetTextMovementStep());
775     HILOG_DEBUG("ConvertTextMoveUnitToString: [%{public}s]", textMoveUnit.c_str());
776     if (textMoveUnit == "") {
777         callbackInfo->ret_ = RET_ERR_FAILED;
778         napi_get_undefined(callbackInfo->env_, &value);
779     } else {
780         callbackInfo->ret_ = RET_OK;
781         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
782             textMoveUnit.c_str(), NAPI_AUTO_LENGTH, &value));
783     }
784 }
785 
GetElementInfoParent(NAccessibilityElementData * callbackInfo,napi_value & value)786 void NAccessibilityElement::GetElementInfoParent(NAccessibilityElementData *callbackInfo, napi_value &value)
787 {
788     if (!CheckElementInfoParameter(callbackInfo, value)) {
789         return;
790     }
791     if (callbackInfo->ret_ == RET_OK) {
792         napi_value constructor = nullptr;
793         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_reference_value(callbackInfo->env_,
794             NAccessibilityElement::consRef_, &constructor));
795         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_new_instance(callbackInfo->env_,
796             constructor, 0, nullptr, &value));
797         ConvertElementInfoToJS(callbackInfo->env_, value, callbackInfo->nodeInfo_);
798     } else {
799         HILOG_ERROR("GetElementInfoParent failed!");
800         napi_get_undefined(callbackInfo->env_, &value);
801     }
802 }
803 
GetElementInfoChildren(NAccessibilityElementData * callbackInfo,napi_value & value)804 void NAccessibilityElement::GetElementInfoChildren(NAccessibilityElementData *callbackInfo, napi_value &value)
805 {
806     if (!CheckElementInfoParameter(callbackInfo, value)) {
807         return;
808     }
809     if (callbackInfo->ret_ == RET_OK) {
810         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_array(callbackInfo->env_, &value));
811         ConvertElementInfosToJS(callbackInfo->env_, value, callbackInfo->nodeInfos_);
812     } else {
813         HILOG_ERROR("GetElementInfoChildren failed!");
814         napi_get_undefined(callbackInfo->env_, &value);
815     }
816 }
817 
GetElementInfoTriggerAction(NAccessibilityElementData * callbackInfo,napi_value & value)818 void NAccessibilityElement::GetElementInfoTriggerAction(NAccessibilityElementData *callbackInfo, napi_value &value)
819 {
820     if (!CheckElementInfoParameter(callbackInfo, value)) {
821         return;
822     }
823     std::string triggerAction = ConvertOperationTypeToString(
824         callbackInfo->accessibilityElement_.elementInfo_->GetTriggerAction());
825     HILOG_DEBUG("GetElementInfoTriggerAction: [%{public}s]", triggerAction.c_str());
826     if (triggerAction == "") {
827         callbackInfo->ret_ = RET_ERR_FAILED;
828         napi_get_undefined(callbackInfo->env_, &value);
829     } else {
830         callbackInfo->ret_ = RET_OK;
831         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
832             triggerAction.c_str(), NAPI_AUTO_LENGTH, &value));
833     }
834 }
835 
GetElementInfoContents(NAccessibilityElementData * callbackInfo,napi_value & value)836 void NAccessibilityElement::GetElementInfoContents(NAccessibilityElementData *callbackInfo, napi_value &value)
837 {
838     if (!CheckElementInfoParameter(callbackInfo, value)) {
839         return;
840     }
841     std::vector<std::string> contents {};
842     callbackInfo->accessibilityElement_.elementInfo_->GetContentList(contents);
843     HILOG_DEBUG("contents size: [%{public}zu]", contents.size());
844 
845     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_array(callbackInfo->env_, &value));
846     size_t index = 0;
847     for (auto& content : contents) {
848         napi_value nContent = nullptr;
849         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
850             content.c_str(), NAPI_AUTO_LENGTH, &nContent));
851         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_set_element(callbackInfo->env_, value, index, nContent));
852         index++;
853     }
854 }
855 
GetElementInfoLastContent(NAccessibilityElementData * callbackInfo,napi_value & value)856 void NAccessibilityElement::GetElementInfoLastContent(NAccessibilityElementData *callbackInfo, napi_value &value)
857 {
858     if (!CheckElementInfoParameter(callbackInfo, value)) {
859         return;
860     }
861     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
862         callbackInfo->accessibilityElement_.elementInfo_->GetLatestContent().c_str(), NAPI_AUTO_LENGTH, &value));
863 }
864 
GetElementInfoWindowId(NAccessibilityElementData * callbackInfo,napi_value & value)865 void NAccessibilityElement::GetElementInfoWindowId(NAccessibilityElementData *callbackInfo, napi_value &value)
866 {
867     if (!CheckElementInfoParameter(callbackInfo, value)) {
868         return;
869     }
870     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
871         callbackInfo->accessibilityElement_.elementInfo_->GetWindowId(), &value));
872 }
873 
GetElementInfoIsFocused(NAccessibilityElementData * callbackInfo,napi_value & value)874 void NAccessibilityElement::GetElementInfoIsFocused(NAccessibilityElementData *callbackInfo, napi_value &value)
875 {
876     if (!CheckElementInfoParameter(callbackInfo, value)) {
877         return;
878     }
879     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
880         callbackInfo->accessibilityElement_.elementInfo_->IsFocused(), &value));
881 }
882 
CheckWindowInfoParameter(NAccessibilityElementData * callbackInfo,napi_value & value)883 bool NAccessibilityElement::CheckWindowInfoParameter(NAccessibilityElementData *callbackInfo, napi_value &value)
884 {
885     if (!callbackInfo) {
886         HILOG_ERROR("callbackInfo is nullptr");
887         return false;
888     }
889     if (!callbackInfo->accessibilityElement_.windowInfo_) {
890         HILOG_ERROR("window info is nullptr");
891         napi_get_undefined(callbackInfo->env_, &value);
892         callbackInfo->ret_ = RET_ERR_FAILED;
893         return false;
894     }
895     return true;
896 }
897 
GetWindowInfoIsActive(NAccessibilityElementData * callbackInfo,napi_value & value)898 void NAccessibilityElement::GetWindowInfoIsActive(NAccessibilityElementData *callbackInfo, napi_value &value)
899 {
900     if (!CheckWindowInfoParameter(callbackInfo, value)) {
901         return;
902     }
903     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
904         callbackInfo->accessibilityElement_.windowInfo_->IsActive(), &value));
905 }
906 
GetWindowInfoScreenRect(NAccessibilityElementData * callbackInfo,napi_value & value)907 void NAccessibilityElement::GetWindowInfoScreenRect(NAccessibilityElementData *callbackInfo, napi_value &value)
908 {
909     if (!CheckWindowInfoParameter(callbackInfo, value)) {
910         return;
911     }
912     OHOS::Accessibility::Rect screenRect = callbackInfo->accessibilityElement_.windowInfo_->GetRectInScreen();
913     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_object(callbackInfo->env_, &value));
914     ConvertRectToJS(callbackInfo->env_, value, screenRect);
915 }
916 
GetWindowInfoLayer(NAccessibilityElementData * callbackInfo,napi_value & value)917 void NAccessibilityElement::GetWindowInfoLayer(NAccessibilityElementData *callbackInfo, napi_value &value)
918 {
919     if (!CheckWindowInfoParameter(callbackInfo, value)) {
920         return;
921     }
922     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
923         callbackInfo->accessibilityElement_.windowInfo_->GetWindowLayer(), &value));
924 }
925 
GetWindowInfoType(NAccessibilityElementData * callbackInfo,napi_value & value)926 void NAccessibilityElement::GetWindowInfoType(NAccessibilityElementData *callbackInfo, napi_value &value)
927 {
928     if (!CheckWindowInfoParameter(callbackInfo, value)) {
929         return;
930     }
931     std::string accessibilityWindowType = ConvertWindowTypeToString(
932         callbackInfo->accessibilityElement_.windowInfo_->GetAccessibilityWindowType());
933     HILOG_DEBUG("GetWindowInfoType: [%{public}s]", accessibilityWindowType.c_str());
934     if (accessibilityWindowType == "") {
935         callbackInfo->ret_ = RET_ERR_FAILED;
936         napi_get_undefined(callbackInfo->env_, &value);
937     } else {
938         callbackInfo->ret_ = RET_OK;
939         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_string_utf8(callbackInfo->env_,
940             accessibilityWindowType.c_str(), NAPI_AUTO_LENGTH, &value));
941     }
942 }
943 
GetWindowInfoRootElement(NAccessibilityElementData * callbackInfo,napi_value & value)944 void NAccessibilityElement::GetWindowInfoRootElement(NAccessibilityElementData *callbackInfo, napi_value &value)
945 {
946     if (!CheckWindowInfoParameter(callbackInfo, value)) {
947         return;
948     }
949     if (callbackInfo->ret_ == RET_OK) {
950         napi_value constructor = nullptr;
951         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_reference_value(callbackInfo->env_,
952             NAccessibilityElement::consRef_, &constructor));
953         NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_new_instance(callbackInfo->env_,
954             constructor, 0, nullptr, &value));
955         ConvertElementInfoToJS(callbackInfo->env_, value, callbackInfo->nodeInfo_);
956     } else {
957         HILOG_ERROR("GetWindowInfoRootElement failed!");
958         napi_get_undefined(callbackInfo->env_, &value);
959     }
960 }
961 
GetWindowInfoIsFocused(NAccessibilityElementData * callbackInfo,napi_value & value)962 void NAccessibilityElement::GetWindowInfoIsFocused(NAccessibilityElementData *callbackInfo, napi_value &value)
963 {
964     if (!CheckWindowInfoParameter(callbackInfo, value)) {
965         return;
966     }
967     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_get_boolean(callbackInfo->env_,
968         callbackInfo->accessibilityElement_.windowInfo_->IsFocused(), &value));
969 }
970 
GetWindowInfoWindowId(NAccessibilityElementData * callbackInfo,napi_value & value)971 void NAccessibilityElement::GetWindowInfoWindowId(NAccessibilityElementData *callbackInfo, napi_value &value)
972 {
973     if (!CheckWindowInfoParameter(callbackInfo, value)) {
974         return;
975     }
976     NAPI_CALL_RETURN_VOID(callbackInfo->env_, napi_create_int32(callbackInfo->env_,
977         callbackInfo->accessibilityElement_.windowInfo_->GetWindowId(), &value));
978 }
979 
ActionNames(napi_env env,napi_callback_info info)980 napi_value NAccessibilityElement::ActionNames(napi_env env, napi_callback_info info)
981 {
982     HILOG_INFO();
983     size_t argc = ARGS_SIZE_ONE;
984     napi_value argv = nullptr;
985     napi_value thisVar = nullptr;
986     void* data = nullptr;
987     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data));
988     HILOG_DEBUG("argc = %{public}zu", argc);
989 
990     NAccessibilityElementData *callbackInfo = new(std::nothrow) NAccessibilityElementData();
991     if (!callbackInfo) {
992         HILOG_ERROR("Failed to create callbackInfo.");
993         return nullptr;
994     }
995     callbackInfo->env_ = env;
996 
997     napi_value promise = nullptr;
998     if (argc > ARGS_SIZE_ONE - 1) {
999         napi_valuetype valueType = napi_null;
1000         napi_typeof(env, argv, &valueType);
1001         if (valueType == napi_function) {
1002             napi_create_reference(env, argv, 1, &callbackInfo->callback_);
1003             napi_get_undefined(env, &promise);
1004         } else {
1005             napi_create_promise(env, &callbackInfo->deferred_, &promise);
1006         }
1007     } else {
1008         napi_create_promise(env, &callbackInfo->deferred_, &promise);
1009     }
1010 
1011     AccessibilityElement* accessibilityElement = nullptr;
1012     napi_status status = napi_unwrap(env, thisVar, (void**)&accessibilityElement);
1013     if (!accessibilityElement || status != napi_ok) {
1014         HILOG_ERROR("accessibilityElement is null or status[%{public}d] is wrong", status);
1015         return ErrorOperation(callbackInfo);
1016     }
1017     callbackInfo->accessibilityElement_ = *accessibilityElement;
1018     if (!callbackInfo->accessibilityElement_.isElementInfo_) {
1019         HILOG_ERROR("it is not element info");
1020         return ErrorOperation(callbackInfo);
1021     }
1022 
1023     napi_value resource = nullptr;
1024     napi_create_string_utf8(env, "ActionNames", NAPI_AUTO_LENGTH, &resource);
1025 
1026     napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {},
1027         // Execute the complete function
1028         ActionNamesComplete,
1029         reinterpret_cast<void*>(callbackInfo),
1030         &callbackInfo->work_);
1031     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
1032     return promise;
1033 }
1034 
ActionNamesComplete(napi_env env,napi_status status,void * data)1035 void NAccessibilityElement::ActionNamesComplete(napi_env env, napi_status status, void* data)
1036 {
1037     HILOG_DEBUG("ActionNamesComplete execute back");
1038     NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
1039     napi_value result[ARGS_SIZE_TWO] = {0};
1040     napi_value callback = 0;
1041     napi_value undefined = 0;
1042     napi_get_undefined(env, &undefined);
1043     if (!callbackInfo) {
1044         HILOG_ERROR("callbackInfo is nullptr");
1045         return;
1046     }
1047 
1048     if (callbackInfo->accessibilityElement_.elementInfo_) {
1049         std::vector<std::string> actionNames {};
1050         std::vector<AccessibleAction> operations =
1051             callbackInfo->accessibilityElement_.elementInfo_->GetActionList();
1052         HILOG_DEBUG("action list size is %{public}zu", operations.size());
1053         actionNames.resize(operations.size());
1054         std::transform(operations.begin(), operations.end(), actionNames.begin(),
1055             [](const AccessibleAction operation) {
1056                 return ConvertOperationTypeToString(operation.GetActionType());
1057             });
1058         napi_create_array(env, &result[PARAM1]);
1059         ConvertStringVecToJS(env, result[PARAM1], actionNames);
1060         callbackInfo->ret_ = RET_OK;
1061     } else {
1062         HILOG_ERROR("no elementInfo_");
1063         callbackInfo->ret_ = RET_ERR_FAILED;
1064         napi_get_undefined(env, &result[PARAM1]);
1065     }
1066 
1067     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
1068     if (callbackInfo->callback_) {
1069         // Callback mode
1070         napi_get_reference_value(env, callbackInfo->callback_, &callback);
1071         napi_value returnVal;
1072         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
1073         napi_delete_reference(env, callbackInfo->callback_);
1074     } else {
1075         // Promise mode
1076         if (callbackInfo->accessibilityElement_.elementInfo_) {
1077             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
1078         } else {
1079             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
1080         }
1081     }
1082     napi_delete_async_work(env, callbackInfo->work_);
1083     delete callbackInfo;
1084     callbackInfo = nullptr;
1085 }
1086 
PerformAction(napi_env env,napi_callback_info info)1087 napi_value NAccessibilityElement::PerformAction(napi_env env, napi_callback_info info)
1088 {
1089     size_t argc = ARGS_SIZE_THREE;
1090     napi_value argv[ARGS_SIZE_THREE] = {0};
1091     napi_value thisVar;
1092     void* data = nullptr;
1093     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1094     if (status != napi_ok) {
1095         HILOG_ERROR("Failed to get cb info");
1096         napi_value err = CreateBusinessError(env, RetError::RET_ERR_FAILED);
1097         napi_throw(env, err);
1098         return nullptr;
1099     }
1100     HILOG_DEBUG("argc = %{public}zu", argc);
1101 
1102     AccessibilityElement* accessibilityElement = UnrapAccessibilityElement(env, thisVar);
1103     if (!accessibilityElement) {
1104         return nullptr;
1105     }
1106     std::string actionName;
1107     NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
1108     if (argc < ARGS_SIZE_ONE || !ParseString(env, actionName, argv[PARAM0])) {
1109         HILOG_ERROR("argc is invalid: %{public}zu", argc);
1110         errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
1111         delete accessibilityElement;
1112         accessibilityElement = nullptr;
1113         napi_value err = CreateBusinessError(env, RetError::RET_ERR_INVALID_PARAM);
1114         HILOG_ERROR("invalid param");
1115         napi_throw(env, err);
1116         return nullptr;
1117     }
1118     return PerformActionAsync(env, argc, argv, actionName, accessibilityElement);
1119 }
1120 
UnrapAccessibilityElement(napi_env env,napi_value thisVar)1121 AccessibilityElement* NAccessibilityElement::UnrapAccessibilityElement(napi_env env, napi_value thisVar)
1122 {
1123     AccessibilityElement* accessibilityElement = nullptr;
1124     napi_status status = napi_unwrap(env, thisVar, (void**)&accessibilityElement);
1125     if (!accessibilityElement || status != napi_ok) {
1126         HILOG_ERROR("accessibilityElement is null or status[%{public}d] is wrong", status);
1127         napi_value err = CreateBusinessError(env, RetError::RET_ERR_NULLPTR);
1128         napi_throw(env, err);
1129         return nullptr;
1130     }
1131     if (!(accessibilityElement->isElementInfo_ && accessibilityElement->elementInfo_)) {
1132         HILOG_ERROR("accessibilityElement is wrong. isElementInfo_[%{public}d]", accessibilityElement->isElementInfo_);
1133         napi_value err = CreateBusinessError(env, RetError::RET_ERR_FAILED);
1134         napi_throw(env, err);
1135         return nullptr;
1136     }
1137     return accessibilityElement;
1138 }
1139 
PerformActionAsync(napi_env env,size_t argc,napi_value * argv,std::string actionName,AccessibilityElement * accessibilityElement)1140 napi_value NAccessibilityElement::PerformActionAsync(napi_env env, size_t argc, napi_value* argv,
1141     std::string actionName, AccessibilityElement* accessibilityElement)
1142 {
1143     NAccessibilityElementData *callbackInfo = new(std::nothrow) NAccessibilityElementData();
1144     if (!callbackInfo) {
1145         HILOG_ERROR("Failed to create callbackInfo.");
1146         napi_value err = CreateBusinessError(env, RetError::RET_ERR_NULLPTR);
1147         napi_throw(env, err);
1148         return nullptr;
1149     }
1150     callbackInfo->env_ = env;
1151     callbackInfo->accessibilityElement_ = *accessibilityElement;
1152 
1153     return PerformActionConstructPromise(env, argc, argv, callbackInfo, actionName);
1154 }
1155 
PerformActionConstructPromise(napi_env env,size_t argc,napi_value * argv,NAccessibilityElementData * callbackInfo,std::string actionName)1156 napi_value NAccessibilityElement::PerformActionConstructPromise(napi_env env, size_t argc, napi_value* argv,
1157     NAccessibilityElementData* callbackInfo, std::string actionName)
1158 {
1159     napi_value promise = nullptr;
1160     std::map<std::string, std::string> actionArguments {};
1161     if (argc >= ARGS_SIZE_THREE) {
1162         napi_valuetype secondParamType = napi_null;
1163         napi_typeof(env, argv[PARAM1], &secondParamType);
1164         napi_valuetype thirdParamType = napi_null;
1165         napi_typeof(env, argv[PARAM2], &thirdParamType);
1166         if (thirdParamType == napi_function) {
1167             if (secondParamType == napi_object) {
1168                 ConvertActionArgsJSToNAPI(env, argv[PARAM1], actionArguments,
1169                     ConvertStringToAccessibleOperationType(actionName));
1170             }
1171             napi_create_reference(env, argv[PARAM2], 1, &callbackInfo->callback_);
1172             napi_get_undefined(env, &promise);
1173         } else if (secondParamType == napi_function) {
1174             napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
1175             napi_get_undefined(env, &promise);
1176         } else {
1177             HILOG_INFO("argc is three, use promise");
1178             napi_create_promise(env, &callbackInfo->deferred_, &promise);
1179         }
1180     } else if (argc == ARGS_SIZE_TWO) {
1181         napi_valuetype valueType = napi_null;
1182         napi_typeof(env, argv[PARAM1], &valueType);
1183         if (valueType == napi_function) {
1184             napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
1185             napi_get_undefined(env, &promise);
1186         } else {
1187             if (valueType == napi_object) {
1188                 ConvertActionArgsJSToNAPI(env, argv[PARAM1], actionArguments,
1189                     ConvertStringToAccessibleOperationType(actionName));
1190             }
1191             HILOG_INFO("argc is two, use promise");
1192             napi_create_promise(env, &callbackInfo->deferred_, &promise);
1193         }
1194     } else {
1195         HILOG_INFO("argc is others, use promise");
1196         napi_create_promise(env, &callbackInfo->deferred_, &promise);
1197     }
1198 
1199     callbackInfo->actionName_ = actionName;
1200     callbackInfo->actionArguments_ = actionArguments;
1201     napi_value resource = nullptr;
1202     napi_create_string_utf8(env, "PerformAction", NAPI_AUTO_LENGTH, &resource);
1203     napi_create_async_work(env, nullptr, resource, PerformActionExecute, PerformActionComplete,
1204         reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
1205     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
1206     return promise;
1207 }
1208 
PerformActionExecute(napi_env env,void * data)1209 void NAccessibilityElement::PerformActionExecute(napi_env env, void* data)
1210 {
1211     HILOG_DEBUG("PerformActionExecute");
1212     NAccessibilityElementData *callbackInfo = static_cast<NAccessibilityElementData*>(data);
1213     if (!callbackInfo) {
1214         HILOG_ERROR("callbackInfo is nullptr");
1215         return;
1216     }
1217 
1218     ActionType action = ConvertStringToAccessibleOperationType(callbackInfo->actionName_);
1219     if (action == ActionType::ACCESSIBILITY_ACTION_INVALID) {
1220         HILOG_ERROR("The action is not supported");
1221         callbackInfo->ret_ = OHOS::Accessibility::RetError::RET_ERR_ACTION_NOT_SUPPORT;
1222         return;
1223     }
1224     callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->ExecuteAction(
1225         *callbackInfo->accessibilityElement_.elementInfo_, action, callbackInfo->actionArguments_);
1226     HILOG_DEBUG("callbackInfo->ret_[%{public}d]", callbackInfo->ret_);
1227 }
1228 
PerformActionComplete(napi_env env,napi_status status,void * data)1229 void NAccessibilityElement::PerformActionComplete(napi_env env, napi_status status, void* data)
1230 {
1231     HILOG_DEBUG("PerformActionComplete execute back");
1232     NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
1233     if (!callbackInfo) {
1234         HILOG_ERROR("callbackInfo is nullptr");
1235         return;
1236     }
1237     napi_value result[ARGS_SIZE_TWO] = {0};
1238     napi_value callback = 0;
1239     napi_value undefined = 0;
1240     napi_get_undefined(env, &undefined);
1241     napi_get_undefined(env, &result[PARAM1]);
1242     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
1243     if (callbackInfo->callback_) {
1244         // Callback mode
1245         napi_get_reference_value(env, callbackInfo->callback_, &callback);
1246         napi_value returnVal;
1247         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
1248         napi_delete_reference(env, callbackInfo->callback_);
1249     } else {
1250         // Promise mode
1251         if (callbackInfo->ret_ == RET_OK) {
1252             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
1253         } else {
1254             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
1255         }
1256     }
1257 
1258     napi_delete_async_work(env, callbackInfo->work_);
1259     delete callbackInfo;
1260     callbackInfo = nullptr;
1261 }
1262 
FindElement(napi_env env,napi_callback_info info)1263 napi_value NAccessibilityElement::FindElement(napi_env env, napi_callback_info info)
1264 {
1265     size_t argc = ARGS_SIZE_THREE;
1266     napi_value argv[ARGS_SIZE_THREE] = {0};
1267     napi_value thisVar;
1268     void* data = nullptr;
1269     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1270     if (status != napi_ok) {
1271         HILOG_ERROR("Failed to get cb info");
1272         napi_value err = CreateBusinessError(env, RetError::RET_ERR_FAILED);
1273         napi_throw(env, err);
1274         return nullptr;
1275     }
1276     HILOG_DEBUG("argc = %{public}d", (int)argc);
1277 
1278     // Unwrap AccessibilityElement
1279     AccessibilityElement* accessibilityElement = nullptr;
1280     status = napi_unwrap(env, thisVar, (void**)&accessibilityElement);
1281     if (!accessibilityElement || status != napi_ok) {
1282         HILOG_ERROR("accessibilityElement is null or status[%{public}d] is wrong", status);
1283         napi_value err = CreateBusinessError(env, RetError::RET_ERR_NULLPTR);
1284         napi_throw(env, err);
1285         return nullptr;
1286     }
1287     if (!accessibilityElement->isElementInfo_) {
1288         HILOG_ERROR("Type of AccessibilityElement is not right");
1289         napi_value err = CreateBusinessError(env, RetError::RET_ERR_FAILED);
1290         napi_throw(env, err);
1291         return nullptr;
1292     }
1293 
1294     NAccessibilityElementData *callbackInfo = new(std::nothrow) NAccessibilityElementData();
1295     if (!callbackInfo) {
1296         HILOG_ERROR("Failed to create callbackInfo.");
1297         napi_value err = CreateBusinessError(env, RetError::RET_ERR_NULLPTR);
1298         napi_throw(env, err);
1299         return nullptr;
1300     }
1301     callbackInfo->env_ = env;
1302     FindElementConstructCallbackInfo(env, argc, argv, callbackInfo, accessibilityElement);
1303     if (!callbackInfo) {
1304         return nullptr;
1305     }
1306     return FindElementAsync(env, argc, argv, callbackInfo, accessibilityElement);
1307 }
1308 
FindElementAsync(napi_env env,size_t argc,napi_value * argv,NAccessibilityElementData * callbackInfo,AccessibilityElement * accessibilityElement)1309 napi_value NAccessibilityElement::FindElementAsync(napi_env env, size_t argc, napi_value* argv,
1310     NAccessibilityElementData* callbackInfo, AccessibilityElement* accessibilityElement)
1311 {
1312     napi_value promise = nullptr;
1313     if (argc > ARGS_SIZE_THREE - 1) {
1314         napi_valuetype valueType = napi_null;
1315         napi_typeof(env, argv[PARAM2], &valueType);
1316         if (valueType == napi_function) {
1317             napi_create_reference(env, argv[PARAM2], 1, &callbackInfo->callback_);
1318             napi_get_undefined(env, &promise);
1319         } else {
1320             napi_create_promise(env, &callbackInfo->deferred_, &promise);
1321         }
1322     } else {
1323         napi_create_promise(env, &callbackInfo->deferred_, &promise);
1324     }
1325 
1326     callbackInfo->accessibilityElement_ = *accessibilityElement;
1327 
1328     napi_value resource = nullptr;
1329     napi_create_string_utf8(callbackInfo->env_, "FindElement", NAPI_AUTO_LENGTH, &resource);
1330     napi_create_async_work(callbackInfo->env_, nullptr, resource, FindElementExecute,
1331         FindElementComplete, reinterpret_cast<void*>(callbackInfo), &callbackInfo->work_);
1332     napi_queue_async_work_with_qos(callbackInfo->env_, callbackInfo->work_, napi_qos_user_initiated);
1333     return promise;
1334 }
1335 
FindElementConstructCallbackInfo(napi_env env,size_t argc,napi_value * argv,NAccessibilityElementData * callbackInfo,AccessibilityElement * accessibilityElement)1336 void NAccessibilityElement::FindElementConstructCallbackInfo(napi_env env, size_t argc, napi_value* argv,
1337     NAccessibilityElementData* callbackInfo, AccessibilityElement* accessibilityElement)
1338 {
1339     NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
1340     if (argc < ARGS_SIZE_THREE - 1) {
1341         HILOG_ERROR("argc is invalid: %{public}zu", argc);
1342         errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
1343     }
1344 
1345     if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
1346         // Parse conditionType name
1347         std::string conditionType = "";
1348         if (ParseString(env, conditionType, argv[PARAM0])) {
1349             HILOG_INFO("conditionType = %{public}s", conditionType.c_str());
1350             if (std::strcmp(conditionType.c_str(), "content") != 0 &&
1351                 std::strcmp(conditionType.c_str(), "focusType") != 0 &&
1352                 std::strcmp(conditionType.c_str(), "focusDirection") != 0) {
1353                 HILOG_ERROR("argv[PARAM0] is wrong[%{public}s", conditionType.c_str());
1354                 errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
1355             } else {
1356                 callbackInfo->conditionId_ = ConvertStringToCondition(conditionType);
1357             }
1358         } else {
1359             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
1360         }
1361 
1362         // Parse queryData name
1363         std::string queryData = "";
1364         if (ParseString(env, queryData, argv[PARAM1])) {
1365             HILOG_INFO("queryData = %{public}s", queryData.c_str());
1366             callbackInfo->condition_ = queryData;
1367         } else {
1368             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
1369         }
1370     }
1371 
1372     if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
1373         delete callbackInfo;
1374         callbackInfo = nullptr;
1375         delete accessibilityElement;
1376         accessibilityElement = nullptr;
1377         napi_value err = CreateBusinessError(env, RetError::RET_ERR_INVALID_PARAM);
1378         HILOG_ERROR("invalid param");
1379         napi_throw(env, err);
1380     }
1381 }
1382 
FindElementExecute(napi_env env,void * data)1383 void NAccessibilityElement::FindElementExecute(napi_env env, void* data)
1384 {
1385     NAccessibilityElementData *callbackInfo = static_cast<NAccessibilityElementData*>(data);
1386     if (!callbackInfo) {
1387         HILOG_ERROR("callbackInfo is nullptr");
1388         return;
1389     }
1390 
1391     switch (callbackInfo->conditionId_) {
1392         case FindElementCondition::FIND_ELEMENT_CONDITION_INVALID:
1393             HILOG_ERROR("condition id is invalid");
1394             callbackInfo->ret_ = RET_ERR_INVALID_PARAM;
1395             return;
1396         case FindElementCondition::FIND_ELEMENT_CONDITION_CONTENT:
1397             callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->GetByContent(
1398                 *(callbackInfo->accessibilityElement_.elementInfo_), callbackInfo->condition_,
1399                 callbackInfo->nodeInfos_);
1400             break;
1401         case FindElementCondition::FIND_ELEMENT_CONDITION_FOCUS_TYPE:
1402             {
1403                 int32_t focusType = ConvertStringToFocusType(callbackInfo->condition_);
1404                 HILOG_INFO("focusType is %{public}d", focusType);
1405                 callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->GetFocusByElementInfo(
1406                     *(callbackInfo->accessibilityElement_.elementInfo_),
1407                     focusType, callbackInfo->nodeInfo_);
1408             }
1409             break;
1410         case FindElementCondition::FIND_ELEMENT_CONDITION_FOCUS_DIRECTION:
1411             {
1412                 FocusMoveDirection direction = ConvertStringToDirection(callbackInfo->condition_);
1413                 HILOG_INFO("direction is %{public}d", direction);
1414                 callbackInfo->ret_ = AccessibleAbilityClient::GetInstance()->GetNext(
1415                     *(callbackInfo->accessibilityElement_.elementInfo_), direction,
1416                     callbackInfo->nodeInfo_);
1417             }
1418             break;
1419         default:
1420             break;
1421     }
1422     HILOG_INFO("condition id[%{public}d], result[%{public}d]", callbackInfo->conditionId_, callbackInfo->ret_);
1423 }
1424 
FindElementComplete(napi_env env,napi_status status,void * data)1425 void NAccessibilityElement::FindElementComplete(napi_env env, napi_status status, void* data)
1426 {
1427     NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
1428     if (!callbackInfo) {
1429         HILOG_ERROR("callbackInfo is nullptr");
1430         return;
1431     }
1432 
1433     napi_value result[ARGS_SIZE_TWO] = {0};
1434     GetElement(callbackInfo, result[PARAM1]);
1435     result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
1436     if (callbackInfo->callback_) {
1437         HILOG_DEBUG("callback mode. result is %{public}d", callbackInfo->ret_);
1438         napi_value callback = 0;
1439         napi_get_reference_value(env, callbackInfo->callback_, &callback);
1440         napi_value returnVal;
1441         napi_value undefined = 0;
1442         napi_get_undefined(env, &undefined);
1443         napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
1444         napi_delete_reference(env, callbackInfo->callback_);
1445     } else {
1446         HILOG_DEBUG("promise mode. result is %{public}d", callbackInfo->ret_);
1447         if (callbackInfo->ret_ == RET_OK) {
1448             napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
1449         } else {
1450             napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
1451         }
1452     }
1453     napi_delete_async_work(env, callbackInfo->work_);
1454     delete callbackInfo;
1455     callbackInfo = nullptr;
1456 }
1457 
GetElement(NAccessibilityElementData * callbackInfo,napi_value & value)1458 void NAccessibilityElement::GetElement(NAccessibilityElementData *callbackInfo, napi_value &value)
1459 {
1460     HILOG_INFO("condition id[%{public}d]", callbackInfo->conditionId_);
1461     napi_env env = callbackInfo->env_;
1462     if (callbackInfo->ret_ != RET_OK) {
1463         HILOG_ERROR("GetElementInfo failed!");
1464         napi_get_undefined(env, &value);
1465         return;
1466     }
1467 
1468     switch (callbackInfo->conditionId_) {
1469         case FindElementCondition::FIND_ELEMENT_CONDITION_INVALID:
1470             HILOG_ERROR("condition id is invalid");
1471             callbackInfo->ret_ = RET_ERR_INVALID_PARAM;
1472             return;
1473         case FindElementCondition::FIND_ELEMENT_CONDITION_CONTENT:
1474             napi_create_array(env, &value);
1475             ConvertElementInfosToJS(env, value, callbackInfo->nodeInfos_);
1476             break;
1477         case FindElementCondition::FIND_ELEMENT_CONDITION_FOCUS_TYPE:
1478             {
1479                 napi_value constructor = nullptr;
1480                 napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
1481                 napi_new_instance(env, constructor, 0, nullptr, &value);
1482                 ConvertElementInfoToJS(env, value, callbackInfo->nodeInfo_);
1483             }
1484             break;
1485         case FindElementCondition::FIND_ELEMENT_CONDITION_FOCUS_DIRECTION:
1486             {
1487                 napi_value constructor = nullptr;
1488                 napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
1489                 napi_new_instance(env, constructor, 0, nullptr, &value);
1490                 ConvertElementInfoToJS(env, value, callbackInfo->nodeInfo_);
1491             }
1492             break;
1493         default:
1494             break;
1495     }
1496 }
1497 
ErrorOperation(NAccessibilityElementData * callbackInfo)1498 napi_value NAccessibilityElement::ErrorOperation(NAccessibilityElementData *callbackInfo)
1499 {
1500     HILOG_INFO();
1501     napi_value promise = nullptr;
1502     if (!callbackInfo) {
1503         HILOG_ERROR("callbackInfo is nullptr");
1504         return nullptr;
1505     }
1506     napi_env env = callbackInfo->env_;
1507     if (callbackInfo->callback_) {
1508         HILOG_DEBUG("callback mode");
1509         napi_get_undefined(env, &promise);
1510     } else {
1511         HILOG_DEBUG("promise mode");
1512         napi_create_promise(env, &callbackInfo->deferred_, &promise);
1513     }
1514 
1515     napi_value resource = nullptr;
1516     napi_create_string_utf8(env, "ErrorOperation", NAPI_AUTO_LENGTH, &resource);
1517     napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {},
1518         // Execute the complete function
1519         [](napi_env env, napi_status status, void* data) {
1520             NAccessibilityElementData* callbackInfo = static_cast<NAccessibilityElementData*>(data);
1521             if (!callbackInfo) {
1522                 HILOG_ERROR("callbackInfo is nullptr");
1523                 return;
1524             }
1525 
1526             napi_value result[ARGS_SIZE_TWO] = {0};
1527             napi_value callback = 0;
1528             napi_value undefined = 0;
1529             napi_get_undefined(env, &undefined);
1530             result[PARAM0] = CreateBusinessError(env, callbackInfo->ret_);
1531             if (callbackInfo->callback_) {
1532                 // Callback mode
1533                 result[PARAM1] = undefined;
1534                 napi_get_reference_value(env, callbackInfo->callback_, &callback);
1535                 napi_value returnVal;
1536                 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &returnVal);
1537                 napi_delete_reference(env, callbackInfo->callback_);
1538             } else {
1539                 // Promise mode
1540                 napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM0]);
1541             }
1542             napi_delete_async_work(env, callbackInfo->work_);
1543             delete callbackInfo;
1544             callbackInfo = nullptr;
1545         },
1546         reinterpret_cast<void*>(callbackInfo),
1547         &callbackInfo->work_);
1548     napi_queue_async_work_with_qos(env, callbackInfo->work_, napi_qos_user_initiated);
1549     return promise;
1550 }
1551 
ConvertStringToCondition(const std::string & str)1552 FindElementCondition NAccessibilityElement::ConvertStringToCondition(const std::string &str)
1553 {
1554     static const std::map<std::string, FindElementCondition> findElementConditionTable = {
1555         {"content", FindElementCondition::FIND_ELEMENT_CONDITION_CONTENT},
1556         {"focusType", FindElementCondition::FIND_ELEMENT_CONDITION_FOCUS_TYPE},
1557         {"focusDirection", FindElementCondition::FIND_ELEMENT_CONDITION_FOCUS_DIRECTION}
1558     };
1559 
1560     if (findElementConditionTable.find(str) == findElementConditionTable.end()) {
1561         return FindElementCondition::FIND_ELEMENT_CONDITION_INVALID;
1562     }
1563 
1564     return findElementConditionTable.at(str);
1565 }
1566 
ConvertStringToDirection(const std::string & str)1567 FocusMoveDirection NAccessibilityElement::ConvertStringToDirection(const std::string &str)
1568 {
1569     static const std::map<std::string, FocusMoveDirection> focusMoveDirectionTable = {
1570         {"up", FocusMoveDirection::UP},
1571         {"down", FocusMoveDirection::DOWN},
1572         {"left", FocusMoveDirection::LEFT},
1573         {"right", FocusMoveDirection::RIGHT},
1574         {"forward", FocusMoveDirection::FORWARD},
1575         {"backward", FocusMoveDirection::BACKWARD}
1576     };
1577 
1578     if (focusMoveDirectionTable.find(str) == focusMoveDirectionTable.end()) {
1579         return FocusMoveDirection::DIRECTION_INVALID;
1580     }
1581 
1582     return focusMoveDirectionTable.at(str);
1583 }
1584 
ConvertStringToFocusType(const std::string & str)1585 int32_t NAccessibilityElement::ConvertStringToFocusType(const std::string &str)
1586 {
1587     static const std::map<std::string, int32_t> focusTypeTable = {
1588         {"normal", FOCUS_TYPE_INPUT},
1589         {"accessibility", FOCUS_TYPE_ACCESSIBILITY}
1590     };
1591 
1592     if (focusTypeTable.find(str) == focusTypeTable.end()) {
1593         return FOCUS_TYPE_INVALID;
1594     }
1595     return focusTypeTable.at(str);
1596 }