• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 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_extension_context.h"
17 
18 #include <uv.h>
19 #include "display_manager.h"
20 #include "js_extension_context.h"
21 #include "js_runtime_utils.h"
22 #include "hilog_wrapper.h"
23 #include "napi_accessibility_element.h"
24 #include "accessibility_utils.h"
25 #include "napi_common_want.h"
26 #include "napi_common_start_options.h"
27 #include "api_reporter_helper.h"
28 
29 using namespace OHOS::AbilityRuntime;
30 using namespace OHOS::AccessibilityNapi;
31 
32 namespace OHOS {
33 namespace Accessibility {
34 namespace {
35 constexpr int32_t REPORTER_THRESHOLD_VALUE = 1000;
36 
ConvertAccessibilityWindowInfoToJS(napi_env env,napi_value result,const AccessibilityWindowInfo & accessibilityWindowInfo)37 static void ConvertAccessibilityWindowInfoToJS(
38     napi_env env, napi_value result, const AccessibilityWindowInfo& accessibilityWindowInfo)
39 {
40     // Bind js object to a Native object
41     std::shared_ptr<AccessibilityWindowInfo> windowInfo =
42         std::make_shared<AccessibilityWindowInfo>(accessibilityWindowInfo);
43     AccessibilityElement* pAccessibilityElement = new(std::nothrow) AccessibilityElement(windowInfo);
44     if (pAccessibilityElement == nullptr) {
45         HILOG_ERROR("Failed to create work.");
46         return;
47     }
48 
49     napi_status sts = napi_wrap(
50         env,
51         result,
52         pAccessibilityElement,
53         [](napi_env env, void* data, void* hint) {
54             AccessibilityElement* info = static_cast<AccessibilityElement*>(data);
55             delete info;
56             info = nullptr;
57         },
58         nullptr,
59         nullptr);
60     if (sts != napi_ok) {
61         delete pAccessibilityElement;
62         pAccessibilityElement = nullptr;
63         HILOG_ERROR("failed to wrap JS object");
64     }
65     HILOG_DEBUG("napi_wrap status: %{public}d", (int)sts);
66 }
67 
ConvertAccessibilityWindowInfosToJS(napi_env env,napi_value result,const std::vector<AccessibilityWindowInfo> & accessibilityWindowInfos)68 static void ConvertAccessibilityWindowInfosToJS(
69     napi_env env, napi_value result, const std::vector<AccessibilityWindowInfo>& accessibilityWindowInfos)
70 {
71     HILOG_DEBUG();
72     size_t idx = 0;
73 
74     if (accessibilityWindowInfos.empty()) {
75         return;
76     }
77     napi_value constructor = nullptr;
78     napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
79 
80     for (const auto& windowInfo : accessibilityWindowInfos) {
81         napi_value obj = nullptr;
82         napi_new_instance(env, constructor, 0, nullptr, &obj);
83         ConvertAccessibilityWindowInfoToJS(env, obj, windowInfo);
84         napi_set_element(env, result, idx, obj);
85         idx++;
86     }
87 }
88 
IsNapiFunction(napi_env env,napi_value param)89 static bool IsNapiFunction(napi_env env, napi_value param)
90 {
91     napi_valuetype valueType = napi_null;
92     napi_status status = napi_typeof(env, param, &valueType);
93     if (status != napi_ok) {
94         HILOG_ERROR("napi_typeof error and status is %{public}d", status);
95         return false;
96     }
97 
98     if (valueType != napi_function) {
99         HILOG_ERROR("SubscribeState args[PARAM1] format is wrong");
100         return false;
101     }
102     return true;
103 }
104 
IsNapiBool(napi_env env,napi_value param)105 static bool IsNapiBool(napi_env env, napi_value param)
106 {
107     napi_valuetype valuetype = napi_null;
108     napi_status status = napi_typeof(env, param, &valuetype);
109     if (status != napi_ok) {
110         HILOG_ERROR("napi_typeof error and status is %{public}d", status);
111         return false;
112     }
113 
114     if (valuetype != napi_boolean) {
115         HILOG_ERROR("Wrong argument type. Boolean expected.");
116         return false;
117     }
118     return true;
119 }
120 
IsNapiNumber(napi_env env,napi_value param)121 static bool IsNapiNumber(napi_env env, napi_value param)
122 {
123     napi_valuetype valuetype = napi_null;
124     napi_status status = napi_typeof(env, param, &valuetype);
125     if (status != napi_ok) {
126         HILOG_ERROR("napi_typeof error and status is %{public}d", status);
127         return false;
128     }
129 
130     if (valuetype != napi_number) {
131         HILOG_ERROR("Wrong argument type. uint32 expected.");
132         return false;
133     }
134     return true;
135 }
136 
IsNapiString(napi_env env,napi_value param)137 static bool IsNapiString(napi_env env, napi_value param)
138 {
139     napi_valuetype valuetype = napi_null;
140     napi_status status = napi_typeof(env, param, &valuetype);
141     if (status != napi_ok) {
142         HILOG_ERROR("napi_typeof error and status is %{public}d", status);
143         return false;
144     }
145 
146     if (valuetype != napi_string) {
147         HILOG_ERROR("Wrong argument type. string expected.");
148         return false;
149     }
150     return true;
151 }
152 
GetLastParamForTwo(napi_env env,NapiCallbackInfo & info,napi_value & lastParam,bool & isAccessibilityFocus)153 static void GetLastParamForTwo(napi_env env, NapiCallbackInfo& info, napi_value& lastParam,
154     bool& isAccessibilityFocus)
155 {
156     if (info.argv[PARAM0] != nullptr && info.argv[PARAM1] != nullptr &&
157         IsNapiBool(env, info.argv[PARAM0]) && IsNapiFunction(env, info.argv[PARAM1])) {
158         lastParam = ConvertFromJsValue(env, info.argv[PARAM0], isAccessibilityFocus) ?
159             info.argv[PARAM1] : nullptr;
160     } else if (info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) {
161         HILOG_INFO("argc is more than two, use callback: situation 1");
162         lastParam = info.argv[PARAM1];
163     } else if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
164         HILOG_INFO("argc is more than two, use callback: situation 2");
165         lastParam = info.argv[PARAM0];
166     } else if (info.argv[PARAM0] != nullptr && IsNapiBool(env, info.argv[PARAM0])) {
167         HILOG_INFO("argc is more than two, use promise: situation 3");
168         lastParam = nullptr;
169         ConvertFromJsValue(env, info.argv[PARAM0], isAccessibilityFocus);
170     } else {
171         lastParam = nullptr;
172         HILOG_INFO("argc is more than two, use promise");
173     }
174 }
175 
CheckStartAbilityInputParam(napi_env env,NapiCallbackInfo & info,AAFwk::Want & want)176 static bool CheckStartAbilityInputParam(napi_env env, NapiCallbackInfo& info,
177     AAFwk::Want& want)
178 {
179     if (info.argc < ARGS_SIZE_ONE) {
180         return false;
181     }
182     if (!AppExecFwk::UnwrapWant(env, info.argv[PARAM0], want)) {
183         return false;
184     }
185     if (!want.HasParameter(Want::PARAM_BACK_TO_OTHER_MISSION_STACK)) {
186         want.SetParam(Want::PARAM_BACK_TO_OTHER_MISSION_STACK, true);
187     }
188     return true;
189 }
190 
191 class NAccessibilityExtensionContext final {
192 public:
NAccessibilityExtensionContext(const std::shared_ptr<AccessibilityExtensionContext> & context)193     explicit NAccessibilityExtensionContext(
194         const std::shared_ptr<AccessibilityExtensionContext>& context) : context_(context) {}
195     ~NAccessibilityExtensionContext() = default;
196 
Finalizer(napi_env env,void * data,void * hint)197     static void Finalizer(napi_env env, void* data, void* hint)
198     {
199         HILOG_INFO();
200         std::unique_ptr<NAccessibilityExtensionContext>(static_cast<NAccessibilityExtensionContext*>(data));
201     }
202 
SetTargetBundleName(napi_env env,napi_callback_info info)203     static napi_value SetTargetBundleName(napi_env env, napi_callback_info info)
204     {
205         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnSetTargetBundleName);
206     }
207 
GetFocusElement(napi_env env,napi_callback_info info)208     static napi_value GetFocusElement(napi_env env, napi_callback_info info)
209     {
210         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetFocusElement);
211     }
212 
GetFocusElementSys(napi_env env,napi_callback_info info)213     static napi_value GetFocusElementSys(napi_env env, napi_callback_info info)
214     {
215         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetFocusElementSys);
216     }
217 
GetWindowRootElement(napi_env env,napi_callback_info info)218     static napi_value GetWindowRootElement(napi_env env, napi_callback_info info)
219     {
220         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetWindowRootElement);
221     }
222 
GetWindowRootElementSys(napi_env env,napi_callback_info info)223     static napi_value GetWindowRootElementSys(napi_env env, napi_callback_info info)
224     {
225         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetWindowRootElementSys);
226     }
227 
GetWindows(napi_env env,napi_callback_info info)228     static napi_value GetWindows(napi_env env, napi_callback_info info)
229     {
230         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetWindows);
231     }
232 
GetAccessibilityWindowsSync(napi_env env,napi_callback_info info)233     static napi_value GetAccessibilityWindowsSync(napi_env env, napi_callback_info info)
234     {
235         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetAccessibilityWindowsSync);
236     }
237 
InjectGesture(napi_env env,napi_callback_info info)238     static napi_value InjectGesture(napi_env env, napi_callback_info info)
239     {
240         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGestureInject);
241     }
242 
InjectGestureSync(napi_env env,napi_callback_info info)243     static napi_value InjectGestureSync(napi_env env, napi_callback_info info)
244     {
245         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGestureInjectSync);
246     }
247 
StartAbility(napi_env env,napi_callback_info info)248     static napi_value StartAbility(napi_env env, napi_callback_info info)
249     {
250         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnStartAbility);
251     }
252 
EnableScreenCurtain(napi_env env,napi_callback_info info)253     static napi_value EnableScreenCurtain(napi_env env, napi_callback_info info)
254     {
255         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnEnableScreenCurtain);
256     }
257 
GetElements(napi_env env,napi_callback_info info)258     static napi_value GetElements(napi_env env, napi_callback_info info)
259     {
260         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetElements);
261     }
262 
GetDefaultFocusedElementIds(napi_env env,napi_callback_info info)263     static napi_value GetDefaultFocusedElementIds(napi_env env, napi_callback_info info)
264     {
265         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnGetDefaultFocusedElementIds);
266     }
267 
HoldRunningLock(napi_env env,napi_callback_info info)268     static napi_value HoldRunningLock(napi_env env, napi_callback_info info)
269     {
270         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnHoldRunningLock);
271     }
272 
UnholdRunningLock(napi_env env,napi_callback_info info)273     static napi_value UnholdRunningLock(napi_env env, napi_callback_info info)
274     {
275         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnUnholdRunningLock);
276     }
277 
RegisterCallback(napi_env env,napi_callback_info info)278     static napi_value RegisterCallback(napi_env env, napi_callback_info info)
279     {
280         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnRegisterCallback);
281     }
282 
UnRegisterCallback(napi_env env,napi_callback_info info)283     static napi_value UnRegisterCallback(napi_env env, napi_callback_info info)
284     {
285         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnUnRegisterCallback);
286     }
287 
NotifyDisconnect(napi_env env,napi_callback_info info)288     static napi_value NotifyDisconnect(napi_env env, napi_callback_info info)
289     {
290         GET_NAPI_INFO_AND_CALL(env, info, NAccessibilityExtensionContext, OnNotifyDisconnect);
291     }
292 
293 private:
294     std::weak_ptr<AccessibilityExtensionContext> context_;
295 
OnSetTargetBundleName(napi_env env,NapiCallbackInfo & info)296     napi_value OnSetTargetBundleName(napi_env env, NapiCallbackInfo& info)
297     {
298         HILOG_INFO();
299         NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
300         if (info.argc < ARGS_SIZE_ONE) {
301             HILOG_ERROR("Not enough params");
302             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
303         }
304 
305         std::vector<std::string> targetBundleNames;
306         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
307             if (ConvertJSToStringVec(env, info.argv[PARAM0], targetBundleNames)) {
308                 HILOG_INFO("targetBundleNames's size = %{public}zu", targetBundleNames.size());
309             } else {
310                 errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
311             }
312         }
313 
314         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
315             HILOG_ERROR("invalid param");
316             napi_throw(env, CreateJsError(env,
317                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
318                 ERROR_MESSAGE_PARAMETER_ERROR));
319             return CreateJsUndefined(env);
320         }
321 
322         return SetTargetBundleNameCompleteTask(env, targetBundleNames, info);
323     }
324 
SetTargetBundleNameCompleteTask(napi_env env,std::vector<std::string> targetBundleNames,NapiCallbackInfo & info)325     napi_value SetTargetBundleNameCompleteTask(napi_env env, std::vector<std::string> targetBundleNames,
326         NapiCallbackInfo& info)
327         {
328         auto ret = std::make_shared<RetError>(RET_OK);
329         NapiAsyncTask::ExecuteCallback execute = [weak = context_, targetBundleNames, ret] () {
330             HILOG_INFO("SetTargetBundleName begin");
331             auto context = weak.lock();
332             if (!context) {
333                 HILOG_ERROR("context is released");
334                 *ret = RET_ERR_FAILED;
335                 return;
336             }
337 
338             *ret = context->SetTargetBundleName(targetBundleNames);
339         };
340         NapiAsyncTask::CompleteCallback complete =
341             [ret](napi_env env, NapiAsyncTask& task, int32_t status) {
342             if (*ret == RET_OK) {
343                 task.Resolve(env, CreateJsUndefined(env));
344             } else {
345                 HILOG_ERROR("set target bundle name failed. ret: %{public}d.", *ret);
346                 task.Reject(env, CreateJsError(env,
347                     static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
348                     ERROR_MESSAGE_SYSTEM_ABNORMALITY));
349             }
350         };
351 
352         napi_value lastParam = (info.argc == ARGS_SIZE_ONE) ? nullptr :
353             ((info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) ? info.argv[PARAM1] : nullptr);
354         napi_value result = nullptr;
355         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::OnSetTargetBundleName",
356             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
357         return result;
358     }
359 
OnGetFocusElementSys(napi_env env,NapiCallbackInfo & info)360     napi_value OnGetFocusElementSys(napi_env env, NapiCallbackInfo& info)
361     {
362         return OnGetFocusElementInner(env, info, true);
363     }
364 
OnGetFocusElement(napi_env env,NapiCallbackInfo & info)365     napi_value OnGetFocusElement(napi_env env, NapiCallbackInfo& info)
366     {
367         return OnGetFocusElementInner(env, info, false);
368     }
369 
OnGetFocusElementInner(napi_env env,NapiCallbackInfo & info,bool systemApi)370     napi_value OnGetFocusElementInner(napi_env env, NapiCallbackInfo& info, bool systemApi)
371     {
372         HILOG_INFO();
373         bool isAccessibilityFocus = false;
374         napi_value lastParam = nullptr;
375         if (info.argc >= ARGS_SIZE_TWO) {
376             GetLastParamForTwo(env, info, lastParam, isAccessibilityFocus);
377         } else if (info.argc == ARGS_SIZE_ONE) {
378             if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
379                 lastParam = info.argv[PARAM0];
380             } else {
381                 if (info.argv[PARAM0] != nullptr && IsNapiBool(env, info.argv[PARAM0])) {
382                     ConvertFromJsValue(env, info.argv[PARAM0], isAccessibilityFocus);
383                 }
384                 lastParam = nullptr;
385                 HILOG_INFO("argc is one, use promise");
386             }
387         } else {
388             lastParam = nullptr;
389             HILOG_INFO("argc is others, use promise");
390         }
391 
392         int32_t focus = isAccessibilityFocus ? FOCUS_TYPE_ACCESSIBILITY : FOCUS_TYPE_INPUT;
393         HILOG_DEBUG("focus type is [%{public}d]", focus);
394         return GetFoucusElementCompleteTask(env, focus, lastParam, systemApi);
395     }
396 
GetFoucusElementCompleteTask(napi_env env,int32_t focus,napi_value lastParam,bool systemApi)397     napi_value GetFoucusElementCompleteTask(napi_env env, int32_t focus, napi_value lastParam, bool systemApi)
398     {
399         auto elementInfo = std::make_shared<OHOS::Accessibility::AccessibilityElementInfo>();
400         auto ret = std::make_shared<RetError>(RET_OK);
401         NapiAsyncTask::ExecuteCallback execute = [weak = context_, elementInfo, focus, systemApi, ret] () {
402             HILOG_INFO("GetFoucusElement begin");
403             auto context = weak.lock();
404             if (!context) {
405                 HILOG_ERROR("context is released");
406                 *ret = RET_ERR_FAILED;
407                 return;
408             }
409 
410             *ret = context->GetFocus(focus, *elementInfo, systemApi);
411         };
412         NapiAsyncTask::CompleteCallback complete =
413             [ret, elementInfo](napi_env env, NapiAsyncTask& task, int32_t status) {
414             if (*ret == RET_OK) {
415                 napi_value constructor = nullptr;
416                 napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
417                 napi_value napiElementInfo = nullptr;
418                 napi_new_instance(env, constructor, 0, nullptr, &napiElementInfo);
419                 NAccessibilityElement::ConvertElementInfoToJS(env, napiElementInfo, *elementInfo);
420                 task.Resolve(env, napiElementInfo);
421             } else {
422                 HILOG_ERROR("Get focus elementInfo failed. ret: %{public}d", *ret);
423                 NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
424                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
425             }
426         };
427 
428         napi_value result = nullptr;
429         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::OnGetFocusElement",
430             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
431         return result;
432     }
433 
OnGetWindowRootElementSys(napi_env env,NapiCallbackInfo & info)434     napi_value OnGetWindowRootElementSys(napi_env env, NapiCallbackInfo& info)
435     {
436         return OnGetWindowRootElementInner(env, info, true);
437     }
438 
OnGetWindowRootElement(napi_env env,NapiCallbackInfo & info)439     napi_value OnGetWindowRootElement(napi_env env, NapiCallbackInfo& info)
440     {
441         return OnGetWindowRootElementInner(env, info, false);
442     }
443 
OnGetWindowRootElementInner(napi_env env,NapiCallbackInfo & info,bool systemApi)444     napi_value OnGetWindowRootElementInner(napi_env env, NapiCallbackInfo& info, bool systemApi)
445     {
446         HILOG_INFO();
447         int32_t windowId = INVALID_WINDOW_ID;
448         bool isActiveWindow = true;
449         napi_value lastParam = nullptr;
450         if (info.argc >= ARGS_SIZE_TWO) {
451             if (info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) {
452                 HILOG_INFO("argc is more than two, use callback: situation 1");
453                 lastParam = info.argv[PARAM1];
454             } else if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
455                 HILOG_INFO("argc is more than two, use callback: situation 2");
456                 lastParam = info.argv[PARAM0];
457             } else {
458                 lastParam = nullptr;
459                 HILOG_INFO("argc is two, use promise");
460             }
461             if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
462                 HILOG_INFO("argc is more than two, use promise: situation 3");
463                 isActiveWindow = !ConvertFromJsValue(env, info.argv[PARAM0], windowId);
464             }
465         } else if (info.argc == ARGS_SIZE_ONE) {
466             if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
467                 lastParam = info.argv[PARAM0];
468             } else if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
469                 isActiveWindow = !ConvertFromJsValue(env, info.argv[PARAM0], windowId);
470                 lastParam = nullptr;
471                 HILOG_INFO("argc is one, use promise");
472             }
473         } else {
474             lastParam = nullptr;
475             HILOG_INFO("argc is others, use promise");
476         }
477         return GetWindowRootElementCompleteTask(env, windowId, isActiveWindow, lastParam, systemApi);
478     }
479 
GetWindowRootElementCompleteTask(napi_env env,int32_t windowId,bool isActiveWindow,napi_value lastParam,bool systemApi)480     napi_value GetWindowRootElementCompleteTask(
481         napi_env env, int32_t windowId, bool isActiveWindow, napi_value lastParam, bool systemApi)
482     {
483         auto elementInfo = std::make_shared<OHOS::Accessibility::AccessibilityElementInfo>();
484         auto ret = std::make_shared<RetError>(RET_OK);
485         NapiAsyncTask::ExecuteCallback execute = [weak = context_, isActiveWindow, windowId, elementInfo, systemApi,
486                                                      ret]() {
487             HILOG_INFO("GetWindowRootElement begin");
488             auto context = weak.lock();
489             if (!context) {
490                 HILOG_ERROR("context is released");
491                 *ret = RET_ERR_FAILED;
492                 return;
493             }
494             if (isActiveWindow) {
495                 *ret = context->GetRoot(*elementInfo, systemApi);
496             } else {
497                 AccessibilityWindowInfo windowInfo;
498                 windowInfo.SetWindowId(windowId);
499                 *ret = context->GetRootByWindow(windowInfo, *elementInfo, systemApi);
500             }
501         };
502 
503         NapiAsyncTask::CompleteCallback complete =
504             [ret, elementInfo](napi_env env, NapiAsyncTask& task, int32_t status) {
505             if (*ret == RET_OK) {
506                 napi_value constructor = nullptr;
507                 napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
508                 napi_value napiElementInfo = nullptr;
509                 napi_status result = napi_new_instance(env, constructor, 0, nullptr, &napiElementInfo);
510                 HILOG_DEBUG("napi_new_instance result is %{public}d", result);
511                 NAccessibilityElement::ConvertElementInfoToJS(env, napiElementInfo, *elementInfo);
512                 task.Resolve(env, napiElementInfo);
513             } else {
514                 HILOG_ERROR("Get root elementInfo failed. ret : %{public}d", *ret);
515                 NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
516                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
517             }
518         };
519 
520         napi_value result = nullptr;
521         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::OnGetWindowRootElement",
522             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
523         return result;
524     }
525 
OnGetWindows(napi_env env,NapiCallbackInfo & info)526     napi_value OnGetWindows(napi_env env, NapiCallbackInfo& info)
527     {
528         HILOG_INFO();
529 
530         int64_t displayId = 0;
531         bool hasDisplayId = false;
532         napi_value lastParam = nullptr;
533         if (info.argc >= ARGS_SIZE_TWO) {
534             if (info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) {
535                 HILOG_INFO("argc is more than two, use callback: situation 1");
536                 lastParam = info.argv[PARAM1];
537             } else if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
538                 HILOG_INFO("argc is more than two, use callback: situation 2");
539                 lastParam = info.argv[PARAM0];
540             } else {
541                 lastParam = nullptr;
542             }
543             if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
544                 hasDisplayId = ConvertFromJsValue(env, info.argv[PARAM0], displayId);
545                 HILOG_INFO("argc is more than two, use promise: situation 3");
546             }
547         } else if (info.argc == ARGS_SIZE_ONE) {
548             if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
549                 lastParam = info.argv[PARAM0];
550             } else if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
551                 hasDisplayId = ConvertFromJsValue(env, info.argv[PARAM0], displayId);
552                 lastParam = nullptr;
553                 HILOG_INFO("argc is one, use promise");
554             }
555         } else {
556             lastParam = nullptr;
557             HILOG_INFO("argc is others, use promise");
558         }
559 
560         return hasDisplayId ? GetWindowsByDisplayIdAsync(env, lastParam, displayId) :
561             GetWindowsAsync(env, lastParam);
562     }
563 
GetWindowsAsync(napi_env env,napi_value lastParam)564     napi_value GetWindowsAsync(napi_env env, napi_value lastParam)
565     {
566         HILOG_INFO();
567         auto accessibilityWindows = std::make_shared<std::vector<OHOS::Accessibility::AccessibilityWindowInfo>>();
568         auto ret = std::make_shared<RetError>(RET_OK);
569         NapiAsyncTask::ExecuteCallback execute = [weak = context_, accessibilityWindows, ret] () {
570             HILOG_INFO("Getwindows begin");
571             auto context = weak.lock();
572             if (!context) {
573                 HILOG_ERROR("context is released");
574                 *ret = RET_ERR_FAILED;
575                 return;
576             }
577             *ret = context->GetWindows(*accessibilityWindows);
578         };
579 
580         NapiAsyncTask::CompleteCallback complete =
581             [ret, accessibilityWindows] (napi_env env, NapiAsyncTask& task, int32_t status) {
582                 if (*ret == RET_OK) {
583                     napi_value napiWindowInfos = nullptr;
584                     napi_create_array(env, &napiWindowInfos);
585                     ConvertAccessibilityWindowInfosToJS(env, napiWindowInfos, *accessibilityWindows);
586                     task.Resolve(env, napiWindowInfos);
587                 } else {
588                     HILOG_ERROR("Get windowInfos failed.");
589                     NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
590                     task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
591                 }
592         };
593 
594         napi_value result = nullptr;
595         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::GetWindowsAsync",
596             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
597         return result;
598     }
599 
GetWindowsByDisplayIdAsync(napi_env env,napi_value lastParam,int64_t displayId)600     napi_value GetWindowsByDisplayIdAsync(napi_env env, napi_value lastParam, int64_t displayId)
601     {
602         HILOG_INFO();
603         auto accessibilityWindows = std::make_shared<std::vector<OHOS::Accessibility::AccessibilityWindowInfo>>();
604         auto ret = std::make_shared<RetError>(RET_OK);
605         NapiAsyncTask::ExecuteCallback execute = [weak = context_, accessibilityWindows, ret, displayId] () {
606             HILOG_INFO("GetwindowsByDisplayId begin");
607             auto context = weak.lock();
608             if (!context) {
609                 HILOG_ERROR("context is released");
610                 *ret = RET_ERR_FAILED;
611                 return;
612             }
613             if (displayId < 0) {
614                 HILOG_ERROR("displayId is error: %{public}" PRId64 "", displayId);
615                 *ret = RET_ERR_INVALID_PARAM;
616                 return;
617             }
618             *ret = context->GetWindows(static_cast<uint64_t>(displayId), *accessibilityWindows);
619         };
620 
621         NapiAsyncTask::CompleteCallback complete =
622             [ret, accessibilityWindows] (napi_env env, NapiAsyncTask& task, int32_t status) {
623                 if (*ret == RET_OK) {
624                     napi_value napiWindowInfos = nullptr;
625                     napi_create_array(env, &napiWindowInfos);
626                     ConvertAccessibilityWindowInfosToJS(env, napiWindowInfos, *accessibilityWindows);
627                     task.Resolve(env, napiWindowInfos);
628                 } else {
629                     HILOG_ERROR("Get windowInfosByDisplayId failed.");
630                     NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
631                     task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
632                 }
633         };
634 
635         napi_value result = nullptr;
636         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::GetWindowsByDisplayIdAsync",
637             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
638         return result;
639     }
640 
OnGetAccessibilityWindowsSync(napi_env env,NapiCallbackInfo & info)641     napi_value OnGetAccessibilityWindowsSync(napi_env env, NapiCallbackInfo& info)
642     {
643         HILOG_INFO();
644         if (info.argc > ARGS_SIZE_ONE) {
645             HILOG_ERROR("invalid param");
646             napi_throw(env, CreateJsError(env,
647                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
648                 ERROR_MESSAGE_PARAMETER_ERROR));
649             return CreateJsUndefined(env);
650         }
651         int64_t displayId = 0;
652         bool hasDisplayId = false;
653         if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
654             hasDisplayId = ConvertFromJsValue(env, info.argv[PARAM0], displayId);
655         }
656         auto context = context_.lock();
657         if (!context) {
658             HILOG_ERROR("context is released");
659             napi_throw(env, CreateJsError(env,
660                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
661                 ERROR_MESSAGE_PARAMETER_ERROR));
662             return CreateJsUndefined(env);
663         }
664         auto accessibilityWindows = std::make_shared<std::vector<OHOS::Accessibility::AccessibilityWindowInfo>>();
665         RetError ret = RET_OK;
666         if (hasDisplayId) {
667             if (displayId < 0) {
668                 HILOG_ERROR("displayId is error: %{public}" PRId64 "", displayId);
669                 napi_throw(env, CreateJsError(env,
670                     static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
671                     ERROR_MESSAGE_PARAMETER_ERROR));
672                 return CreateJsUndefined(env);
673             }
674             ret = context->GetWindows(static_cast<uint64_t>(displayId), *accessibilityWindows, true);
675         } else {
676             ret = context->GetWindows(*accessibilityWindows, true);
677         }
678         if (ret != RET_OK) {
679             HILOG_ERROR("result error, ret %{public}d", ret);
680             NAccessibilityErrMsg errMsg = QueryRetMsg(ret);
681             napi_throw(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
682             return CreateJsUndefined(env);
683         }
684         napi_value napiWindowInfos = nullptr;
685         napi_create_array(env, &napiWindowInfos);
686         ConvertAccessibilityWindowInfosToJS(env, napiWindowInfos, *accessibilityWindows);
687         HILOG_DEBUG("OnGetAccessibilityWindowsSync success");
688         return napiWindowInfos;
689     }
690 
OnGestureInjectSync(napi_env env,NapiCallbackInfo & info)691     napi_value OnGestureInjectSync(napi_env env, NapiCallbackInfo& info)
692     {
693 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
694     ApiReportHelper reporter("NAccessibilityExtensionContext.OnGestureInjectSync");
695 #endif // ACCESSIBILITY_EMULATOR_DEFINED
696         HILOG_INFO();
697         NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
698         if (info.argc != ARGS_SIZE_TWO) {
699             HILOG_ERROR("invalid param");
700             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
701         }
702 
703         napi_value nGesturePaths = reinterpret_cast<napi_value>(info.argv[PARAM0]);
704         std::shared_ptr<AccessibilityGestureInjectPath> gesturePath =
705             std::make_shared<AccessibilityGestureInjectPath>();
706         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
707             if (!ConvertGesturePathJSToNAPI(env, nGesturePaths, gesturePath)) {
708                 errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
709                 HILOG_ERROR("invalid param");
710             }
711         }
712 
713         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
714             napi_throw(env, CreateJsError(env,
715                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
716                 ERROR_MESSAGE_PARAMETER_ERROR));
717             return CreateJsUndefined(env);
718         }
719 
720         auto context = context_.lock();
721         RetError ret = context->InjectGesture(gesturePath);
722         if (ret != RET_OK) {
723             HILOG_ERROR("result error, ret %{public}d", ret);
724             napi_throw(env, CreateJsError(env,
725                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
726                 ERROR_MESSAGE_PARAMETER_ERROR));
727             return CreateJsUndefined(env);
728         }
729 
730         HILOG_DEBUG("OnGestureInjectSync success");
731         return CreateJsUndefined(env);
732     }
733 
OnGestureInject(napi_env env,NapiCallbackInfo & info)734     napi_value OnGestureInject(napi_env env, NapiCallbackInfo& info)
735     {
736         HILOG_INFO();
737         NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
738         if (info.argc < ARGS_SIZE_ONE) {
739             HILOG_ERROR("Not enough params");
740             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
741         }
742 
743         napi_value nGesturePaths = info.argv[PARAM0];
744         std::shared_ptr<AccessibilityGestureInjectPath> gesturePath =
745             std::make_shared<AccessibilityGestureInjectPath>();
746         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
747             if (!ConvertGesturePathJSToNAPI(env, nGesturePaths, gesturePath)) {
748                 errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
749             }
750         }
751 
752         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
753             HILOG_ERROR("invalid param");
754             napi_throw(env, CreateJsError(env,
755                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
756                 ERROR_MESSAGE_PARAMETER_ERROR));
757             return CreateJsUndefined(env);
758         }
759         return GestureInjectCompleteTask(env, info, gesturePath);
760     }
761 
GestureInjectCompleteTask(napi_env env,NapiCallbackInfo & info,std::shared_ptr<AccessibilityGestureInjectPath> gesturePath)762     napi_value GestureInjectCompleteTask(
763         napi_env env, NapiCallbackInfo& info, std::shared_ptr<AccessibilityGestureInjectPath> gesturePath)
764     {
765 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
766     ApiReportHelper reporter("NAccessibilityExtensionContext.OnGestureInject");
767 #endif // ACCESSIBILITY_EMULATOR_DEFINED
768         auto ret = std::make_shared<RetError>(RET_OK);
769         NapiAsyncTask::ExecuteCallback execute = [weak = context_, gesturePath, ret] () {
770             HILOG_INFO("GestureInject begin");
771             auto context = weak.lock();
772             if (!context) {
773                 HILOG_ERROR("context is released");
774                 *ret = RET_ERR_FAILED;
775                 return;
776             }
777 
778             *ret = context->InjectGesture(gesturePath);
779         };
780         NapiAsyncTask::CompleteCallback complete =
781             [ret, gesturePath](napi_env env, NapiAsyncTask& task, int32_t status) {
782             if (*ret == RET_OK) {
783                 task.Resolve(env, CreateJsUndefined(env));
784             } else {
785                 HILOG_ERROR("Gesture inject failed. ret: %{public}d.", *ret);
786                 NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
787                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
788             }
789         };
790 
791         napi_value lastParam = (info.argc == ARGS_SIZE_ONE) ? nullptr :
792             ((info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) ? info.argv[PARAM1] : nullptr);
793         napi_value result = nullptr;
794         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::OnGestureInject",
795             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
796         return result;
797     }
798 
OnStartAbility(napi_env env,NapiCallbackInfo & info)799     napi_value OnStartAbility(napi_env env, NapiCallbackInfo& info)
800     {
801         if (info.argc < ARGS_SIZE_ONE) {
802             HILOG_ERROR("Start ability failed, not enough params.");
803             napi_throw(env, CreateJsError(env,
804                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM)));
805             return CreateJsUndefined(env);
806         }
807 
808         AAFwk::Want want;
809         if (!CheckStartAbilityInputParam(env, info, want)) {
810             napi_throw(env, CreateJsError(env,
811                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM)));
812             return CreateJsUndefined(env);
813         }
814 
815         napi_value lastParam = (info.argc == ARGS_SIZE_ONE) ? nullptr :
816             ((info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) ? info.argv[PARAM1] : nullptr);
817         napi_value result = nullptr;
818         std::unique_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
819         auto asyncTask = [weak = context_, want, env, task = napiAsyncTask.get()]() {
820             HILOG_INFO("startAbility begin");
821             auto context = weak.lock();
822             if (context == nullptr) {
823                 HILOG_ERROR("context is released");
824                 task->Reject(env, CreateJsError(env,
825                     static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
826                     ERROR_MESSAGE_PARAMETER_ERROR));
827                 return;
828             }
829 
830             auto ret = std::make_shared<RetError>(RET_OK);
831             *ret = context->StartAbility(want);
832             if (*ret == RET_OK) {
833                 task->Resolve(env, CreateJsUndefined(env));
834             } else {
835                 HILOG_ERROR("startAbility failed. ret: %{public}d.", *ret);
836                 NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
837                 task->Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
838             }
839         };
840         // NAccessibilityExtensionContext::OnStartAbility
841         if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
842             napiAsyncTask->Reject(env, CreateJsError(env,
843                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
844                 ERROR_MESSAGE_SYSTEM_ABNORMALITY));
845         } else {
846             napiAsyncTask.release();
847         }
848         return result;
849     }
850 
OnEnableScreenCurtain(napi_env env,NapiCallbackInfo & info)851     napi_value OnEnableScreenCurtain(napi_env env, NapiCallbackInfo& info)
852     {
853         HILOG_INFO();
854         if (info.argc != ARGS_SIZE_ONE) {
855             HILOG_ERROR("Not enough params");
856             napi_throw(env, CreateJsError(env,
857                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
858                 ERROR_MESSAGE_PARAMETER_ERROR));
859             return CreateJsUndefined(env);
860         }
861 
862         bool isEnable = false;
863         napi_get_value_bool(env, info.argv[PARAM0], &isEnable);
864         auto context = context_.lock();
865         RetError ret = context->EnableScreenCurtain(isEnable);
866         if (ret != RET_OK) {
867             HILOG_ERROR("result error, ret %{public}d", ret);
868             napi_throw(env, CreateJsError(env,
869                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
870                 ERROR_MESSAGE_PARAMETER_ERROR));
871             return CreateJsUndefined(env);
872         }
873 
874         HILOG_INFO("OnEnableScreenCurtain success");
875         return CreateJsUndefined(env);
876     }
877 
OnGetElements(napi_env env,NapiCallbackInfo & info)878     napi_value OnGetElements(napi_env env, NapiCallbackInfo& info)
879     {
880         int32_t windowId = 0;
881         int64_t elementId = -1;
882         napi_value lastParam = nullptr;
883 
884         if (info.argc >= ARGS_SIZE_TWO) {
885             if (info.argv[PARAM1] != nullptr && IsNapiNumber(env, info.argv[PARAM1])) {
886                 ConvertFromJsValue(env, info.argv[PARAM1], elementId);
887             }
888             if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
889                 ConvertFromJsValue(env, info.argv[PARAM0], windowId);
890             }
891         } else if (info.argc == ARGS_SIZE_ONE) {
892             if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
893                 ConvertFromJsValue(env, info.argv[PARAM0], windowId);
894             }
895         } else {
896             HILOG_ERROR("Not enough params");
897         }
898         HILOG_INFO("windowId: %{public}d, elementId: %{public}" PRId64 "", windowId, elementId);
899         return GetElementsAsync(env, lastParam, windowId, elementId);
900     }
901 
GetElementsAsync(napi_env env,napi_value lastParam,int32_t windowId,int64_t elementId)902     napi_value GetElementsAsync(napi_env env, napi_value lastParam, int32_t windowId, int64_t elementId)
903     {
904 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
905         Accessibility::ApiReportHelper reporter("NAccessibilityExtensionContext.GetElements", REPORTER_THRESHOLD_VALUE);
906 #endif // ACCESSIBILITY_EMULATOR_DEFINED
907         auto accessibilityElements = std::make_shared<std::vector<OHOS::Accessibility::AccessibilityElementInfo>>();
908         auto ret = std::make_shared<RetError>(RET_OK);
909         NapiAsyncTask::ExecuteCallback execute = [weak = context_, accessibilityElements, ret, windowId, elementId] () {
910             HILOG_INFO("GetElementsAsync begin");
911             auto context = weak.lock();
912             if (!context) {
913                 HILOG_ERROR("context is released");
914                 *ret = RET_ERR_FAILED;
915                 return;
916             }
917 
918             if (windowId <= 0) {
919                 HILOG_ERROR("windowId is error: %{public}d", windowId);
920                 *ret = RET_ERR_INVALID_PARAM;
921                 return;
922             }
923 
924             if (elementId < -1) {
925                 HILOG_ERROR("elementId is error: %{public}" PRId64 "", elementId);
926                 *ret = RET_ERR_INVALID_PARAM;
927                 return;
928             }
929             *ret = context->GetElements(windowId, elementId, *accessibilityElements);
930         };
931 
932         NapiAsyncTask::CompleteCallback complete =
933             [ret, accessibilityElements] (napi_env env, NapiAsyncTask& task, int32_t status) {
934                 if (*ret == RET_OK) {
935                     napi_value napiElementInfos = nullptr;
936                     napi_create_array(env, &napiElementInfos);
937                     NAccessibilityElement::ConvertElementInfosToJS(env, napiElementInfos, *accessibilityElements);
938                     task.Resolve(env, napiElementInfos);
939                 } else {
940                     HILOG_ERROR("Get GetElementsAsync failed.");
941                     NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
942                     task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
943                 }
944         };
945 
946         napi_value result = nullptr;
947         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::GetElementsAsync",
948             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
949         return result;
950     }
951 
OnGetDefaultFocusedElementIds(napi_env env,NapiCallbackInfo & info)952     napi_value OnGetDefaultFocusedElementIds(napi_env env, NapiCallbackInfo& info)
953     {
954         HILOG_INFO();
955         int32_t windowId = INVALID_WINDOW_ID;
956         napi_value lastParam = nullptr;
957 
958         if (info.argc >= ARGS_SIZE_TWO) {
959             if (info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) {
960                 HILOG_INFO("argc is more than two, use callback: situation 1");
961                 lastParam = info.argv[PARAM1];
962             } else if (info.argv[PARAM0] != nullptr && IsNapiFunction(env, info.argv[PARAM0])) {
963                 HILOG_INFO("argc is more than two, use callback: situation 2");
964                 lastParam = info.argv[PARAM0];
965             } else {
966                 lastParam = nullptr;
967             }
968             if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
969                 ConvertFromJsValue(env, info.argv[PARAM0], windowId);
970             }
971         } else if (info.argc == ARGS_SIZE_ONE) {
972             if (info.argv[PARAM0] != nullptr && IsNapiNumber(env, info.argv[PARAM0])) {
973                 ConvertFromJsValue(env, info.argv[PARAM0], windowId);
974             }
975         } else {
976             HILOG_ERROR("Not enough params");
977         }
978         HILOG_DEBUG("input windowId: %{public}d", windowId);
979         return GetDefaultFocusedElementIdsAsync(env, lastParam, windowId);
980     }
981 
GetDefaultFocusedElementIdsAsync(napi_env env,napi_value lastParam,int32_t windowId)982     napi_value GetDefaultFocusedElementIdsAsync(napi_env env, napi_value lastParam, int32_t windowId)
983     {
984         auto accessibilityElements = std::make_shared<std::vector<OHOS::Accessibility::AccessibilityElementInfo>>();
985         auto ret = std::make_shared<RetError>(RET_OK);
986         NapiAsyncTask::ExecuteCallback execute = [weak = context_, accessibilityElements, ret, windowId] () {
987             auto context = weak.lock();
988             if (!context) {
989                 HILOG_ERROR("context is released");
990                 *ret = RET_ERR_FAILED;
991                 return;
992             }
993 
994             if (windowId <= 0) {
995                 HILOG_ERROR("windowId is error: %{public}d", windowId);
996                 *ret = RET_ERR_INVALID_PARAM;
997                 return;
998             }
999 
1000             *ret = context->GetDefaultFocusedElementIds(windowId, *accessibilityElements);
1001         };
1002 
1003         NapiAsyncTask::CompleteCallback complete =
1004             [ret, accessibilityElements] (napi_env env, NapiAsyncTask& task, int32_t status) {
1005                 if (*ret == RET_OK) {
1006                     napi_value napiElementIds = nullptr;
1007                     napi_create_array(env, &napiElementIds);
1008                     NAccessibilityElement::ConvertElementIdVecToJS(env, napiElementIds, *accessibilityElements);
1009                     task.Resolve(env, napiElementIds);
1010                 } else {
1011                     HILOG_ERROR("Get GetDefaultFocusedElementIdsAsync failed.");
1012                     NAccessibilityErrMsg errMsg = QueryRetMsg(*ret);
1013                     task.Reject(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
1014                 }
1015         };
1016 
1017         napi_value result = nullptr;
1018         NapiAsyncTask::Schedule("NAccessibilityExtensionContext::GetDefaultFocusedElementIdsAsync",
1019             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1020         return result;
1021     }
1022 
OnHoldRunningLock(napi_env env,NapiCallbackInfo & info)1023     napi_value OnHoldRunningLock(napi_env env, NapiCallbackInfo& info)
1024     {
1025         HILOG_INFO();
1026         if (info.argc > ARGS_SIZE_ZERO) {
1027             HILOG_ERROR("argc is more than zero");
1028             napi_throw(env, CreateJsError(env,
1029                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
1030                 ERROR_MESSAGE_PARAMETER_ERROR));
1031             return CreateJsUndefined(env);
1032         }
1033 
1034         auto context = context_.lock();
1035         RetError ret = context->HoldRunningLock();
1036         if (ret != RET_OK) {
1037             HILOG_ERROR("result error, ret %{public}d", ret);
1038             NAccessibilityErrMsg errMsg = QueryRetMsg(ret);
1039             napi_throw(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
1040             return CreateJsUndefined(env);
1041         }
1042 
1043         HILOG_INFO("OnHoldRunningLock success");
1044         return CreateJsUndefined(env);
1045     }
1046 
OnUnholdRunningLock(napi_env env,NapiCallbackInfo & info)1047     napi_value OnUnholdRunningLock(napi_env env, NapiCallbackInfo& info)
1048     {
1049         HILOG_INFO();
1050         if (info.argc > ARGS_SIZE_ZERO) {
1051             HILOG_ERROR("argc is more than zero");
1052             napi_throw(env, CreateJsError(env,
1053                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
1054                 ERROR_MESSAGE_PARAMETER_ERROR));
1055             return CreateJsUndefined(env);
1056         }
1057 
1058         auto context = context_.lock();
1059         RetError ret = context->UnholdRunningLock();
1060         if (ret != RET_OK) {
1061             HILOG_ERROR("result error, ret %{public}d", ret);
1062             NAccessibilityErrMsg errMsg = QueryRetMsg(ret);
1063             napi_throw(env, CreateJsError(env, static_cast<int32_t>(errMsg.errCode), errMsg.message));
1064             return CreateJsUndefined(env);
1065         }
1066 
1067         HILOG_INFO("OnUnholdRunningLock success");
1068         return CreateJsUndefined(env);
1069     }
1070 
OnRegisterCallback(napi_env env,NapiCallbackInfo & info)1071     napi_value OnRegisterCallback(napi_env env, NapiCallbackInfo &info)
1072     {
1073         HILOG_INFO();
1074         std::string type;
1075         napi_ref ref = nullptr;
1076 
1077         if (info.argc >= ARGS_SIZE_TWO) {
1078             if (info.argv[PARAM0] != nullptr && IsNapiString(env, info.argv[PARAM0])) {
1079                 ConvertFromJsValue(env, info.argv[PARAM0], type);
1080             }
1081             if (info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) {
1082                 napi_create_reference(env, info.argv[PARAM1], 1, &ref);
1083             } else {
1084                 HILOG_ERROR("argc one is not function");
1085             }
1086         } else {
1087             HILOG_ERROR("Not enough params");
1088         }
1089 
1090         if (type == "preDisconnect" && ref != nullptr) {
1091             std::shared_ptr<DisconnectCallback> callback = std::make_shared<DisconnectCallback>(env, ref);
1092             context_.lock()->RegisterDisconnectCallback(callback);
1093         }
1094         return nullptr;
1095     }
1096 
OnUnRegisterCallback(napi_env env,NapiCallbackInfo & info)1097     napi_value OnUnRegisterCallback(napi_env env, NapiCallbackInfo &info)
1098     {
1099         HILOG_INFO();
1100         std::string type;
1101         napi_ref ref = nullptr;
1102 
1103         if (info.argc >= ARGS_SIZE_ONE) {
1104             if (info.argv[PARAM0] != nullptr && IsNapiString(env, info.argv[PARAM0])) {
1105                 ConvertFromJsValue(env, info.argv[PARAM0], type);
1106             }
1107             if (info.argv[PARAM1] != nullptr && IsNapiFunction(env, info.argv[PARAM1])) {
1108                 napi_create_reference(env, info.argv[PARAM1], 1, &ref);
1109             } else {
1110                 HILOG_ERROR("argc one is not function");
1111             }
1112         } else {
1113             HILOG_ERROR("Not enough params");
1114         }
1115 
1116         if (type == "preDisconnect") {
1117             std::shared_ptr<DisconnectCallback> callback = std::make_shared<DisconnectCallback>(env, ref);
1118             context_.lock()->UnRegisterDisconnectCallback(callback);
1119         }
1120         return nullptr;
1121     }
1122 
OnNotifyDisconnect(napi_env env,NapiCallbackInfo & info)1123     napi_value OnNotifyDisconnect(napi_env env, NapiCallbackInfo &info)
1124     {
1125         HILOG_INFO();
1126         RetError ret = context_.lock()->NotifyDisconnect();
1127         return nullptr;
1128     }
1129 };
1130 } // namespace
1131 
CreateJsAccessibilityExtensionContext(napi_env env,std::shared_ptr<AccessibilityExtensionContext> context)1132 napi_value CreateJsAccessibilityExtensionContext(
1133     napi_env env, std::shared_ptr<AccessibilityExtensionContext> context)
1134 {
1135     HILOG_INFO();
1136     napi_value object = CreateJsExtensionContext(env, context);
1137     std::unique_ptr<NAccessibilityExtensionContext> jsContext =
1138         std::make_unique<NAccessibilityExtensionContext>(context);
1139     if (!object) {
1140         HILOG_ERROR("object is nullptr.");
1141         return nullptr;
1142     }
1143     napi_wrap(env, object, jsContext.release(), NAccessibilityExtensionContext::Finalizer, nullptr, nullptr);
1144     const char *moduleName = "NAccessibilityExtensionContext";
1145     BindNativeFunction(env, object, "setTargetBundleName", moduleName,
1146         NAccessibilityExtensionContext::SetTargetBundleName);
1147     BindNativeFunction(env, object, "getFocusElement", moduleName,
1148         NAccessibilityExtensionContext::GetFocusElement);
1149     BindNativeFunction(env, object, "getWindowRootElement", moduleName,
1150         NAccessibilityExtensionContext::GetWindowRootElement);
1151     BindNativeFunction(env, object, "getWindows", moduleName, NAccessibilityExtensionContext::GetWindows);
1152     BindNativeFunction(env, object, "injectGesture", moduleName, NAccessibilityExtensionContext::InjectGesture);
1153     BindNativeFunction(env, object, "injectGestureSync", moduleName, NAccessibilityExtensionContext::InjectGestureSync);
1154     BindNativeFunction(env, object, "startAbility", moduleName, NAccessibilityExtensionContext::StartAbility);
1155     BindNativeFunction(env, object, "enableScreenCurtain", moduleName,
1156         NAccessibilityExtensionContext::EnableScreenCurtain);
1157     BindNativeFunction(env, object, "getElements", moduleName, NAccessibilityExtensionContext::GetElements);
1158     BindNativeFunction(env, object, "getDefaultFocusedElementIds", moduleName,
1159         NAccessibilityExtensionContext::GetDefaultFocusedElementIds);
1160     BindNativeFunction(env, object, "holdRunningLockSync", moduleName,
1161         NAccessibilityExtensionContext::HoldRunningLock);
1162     BindNativeFunction(env, object, "unholdRunningLockSync", moduleName,
1163         NAccessibilityExtensionContext::UnholdRunningLock);
1164     BindNativeFunction(env, object, "on", moduleName,
1165         NAccessibilityExtensionContext::RegisterCallback);
1166     BindNativeFunction(env, object, "off", moduleName,
1167         NAccessibilityExtensionContext::UnRegisterCallback);
1168     BindNativeFunction(env, object, "notifyDisconnect", moduleName,
1169         NAccessibilityExtensionContext::NotifyDisconnect);
1170     BindNativeFunction(env, object, "getAccessibilityFocusedElement", moduleName,
1171         NAccessibilityExtensionContext::GetFocusElementSys);
1172     BindNativeFunction(env, object, "getRootInActiveWindow", moduleName,
1173         NAccessibilityExtensionContext::GetWindowRootElementSys);
1174     BindNativeFunction(env, object, "getAccessibilityWindowsSync", moduleName,
1175         NAccessibilityExtensionContext::GetAccessibilityWindowsSync);
1176     return object;
1177 }
1178 } // namespace Accessibility
1179 } // namespace OHOS