• 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_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 "napi_accessibility_utils.h"
25 #include "native_engine/native_value.h"
26 
27 using namespace OHOS::AbilityRuntime;
28 using namespace OHOS::AccessibilityNapi;
29 
30 namespace OHOS {
31 namespace Accessibility {
32 namespace {
ConvertAccessibilityWindowInfoToJS(napi_env env,napi_value result,const AccessibilityWindowInfo & accessibilityWindowInfo)33 static void ConvertAccessibilityWindowInfoToJS(
34     napi_env env, napi_value result, const AccessibilityWindowInfo& accessibilityWindowInfo)
35 {
36     // Bind js object to a Native object
37     std::shared_ptr<AccessibilityWindowInfo> windowInfo =
38         std::make_shared<AccessibilityWindowInfo>(accessibilityWindowInfo);
39     AccessibilityElement* pAccessibilityElement = new(std::nothrow) AccessibilityElement(windowInfo);
40     if (!pAccessibilityElement) {
41         HILOG_ERROR("Failed to create work.");
42         return;
43     }
44 
45     napi_status sts = napi_wrap(
46         env,
47         result,
48         pAccessibilityElement,
49         [](napi_env env, void* data, void* hint) {
50             AccessibilityElement* info = static_cast<AccessibilityElement*>(data);
51             delete info;
52             info = nullptr;
53         },
54         nullptr,
55         nullptr);
56     HILOG_DEBUG("napi_wrap status: %{public}d", (int)sts);
57 }
58 
ConvertAccessibilityWindowInfosToJS(napi_env env,napi_value result,const std::vector<AccessibilityWindowInfo> & accessibilityWindowInfos)59 static void ConvertAccessibilityWindowInfosToJS(
60     napi_env env, napi_value result, const std::vector<AccessibilityWindowInfo>& accessibilityWindowInfos)
61 {
62     HILOG_DEBUG();
63     size_t idx = 0;
64 
65     if (accessibilityWindowInfos.empty()) {
66         return;
67     }
68     napi_value constructor = nullptr;
69     napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
70 
71     for (const auto& windowInfo : accessibilityWindowInfos) {
72         napi_value obj = nullptr;
73         napi_new_instance(env, constructor, 0, nullptr, &obj);
74         ConvertAccessibilityWindowInfoToJS(env, obj, windowInfo);
75         napi_set_element(env, result, idx, obj);
76         idx++;
77     }
78 }
79 
80 class NAccessibilityExtensionContext final {
81 public:
NAccessibilityExtensionContext(const std::shared_ptr<AccessibilityExtensionContext> & context)82     explicit NAccessibilityExtensionContext(
83         const std::shared_ptr<AccessibilityExtensionContext>& context) : context_(context) {}
84     ~NAccessibilityExtensionContext() = default;
85 
Finalizer(NativeEngine * engine,void * data,void * hint)86     static void Finalizer(NativeEngine* engine, void* data, void* hint)
87     {
88         HILOG_INFO();
89         std::unique_ptr<NAccessibilityExtensionContext>(static_cast<NAccessibilityExtensionContext*>(data));
90     }
91 
SetTargetBundleName(NativeEngine * engine,NativeCallbackInfo * info)92     static NativeValue* SetTargetBundleName(NativeEngine* engine, NativeCallbackInfo* info)
93     {
94         NAccessibilityExtensionContext* me = CheckParamsAndGetThis<NAccessibilityExtensionContext>(engine, info);
95         return (me != nullptr) ? me->OnSetTargetBundleName(*engine, *info) : nullptr;
96     }
97 
GetFocusElement(NativeEngine * engine,NativeCallbackInfo * info)98     static NativeValue* GetFocusElement(NativeEngine* engine, NativeCallbackInfo* info)
99     {
100         NAccessibilityExtensionContext* me = CheckParamsAndGetThis<NAccessibilityExtensionContext>(engine, info);
101         return (me != nullptr) ? me->OnGetFocusElement(*engine, *info) : nullptr;
102     }
103 
GetWindowRootElement(NativeEngine * engine,NativeCallbackInfo * info)104     static NativeValue* GetWindowRootElement(NativeEngine* engine, NativeCallbackInfo* info)
105     {
106         NAccessibilityExtensionContext* me = CheckParamsAndGetThis<NAccessibilityExtensionContext>(engine, info);
107         return (me != nullptr) ? me->OnGetWindowRootElement(*engine, *info) : nullptr;
108     }
109 
GetWindows(NativeEngine * engine,NativeCallbackInfo * info)110     static NativeValue* GetWindows(NativeEngine* engine, NativeCallbackInfo* info)
111     {
112         NAccessibilityExtensionContext* me = CheckParamsAndGetThis<NAccessibilityExtensionContext>(engine, info);
113         return (me != nullptr) ? me->OnGetWindows(*engine, *info) : nullptr;
114     }
115 
InjectGesture(NativeEngine * engine,NativeCallbackInfo * info)116     static NativeValue* InjectGesture(NativeEngine* engine, NativeCallbackInfo* info)
117     {
118         NAccessibilityExtensionContext* me = CheckParamsAndGetThis<NAccessibilityExtensionContext>(engine, info);
119         return (me != nullptr) ? me->OnGestureInject(*engine, *info) : nullptr;
120     }
121 
122 private:
123     std::weak_ptr<AccessibilityExtensionContext> context_;
124 
OnSetTargetBundleName(NativeEngine & engine,NativeCallbackInfo & info)125     NativeValue* OnSetTargetBundleName(NativeEngine& engine, NativeCallbackInfo& info)
126     {
127         HILOG_INFO();
128         NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
129         if (info.argc < ARGS_SIZE_ONE) {
130             HILOG_ERROR("Not enough params");
131             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
132         }
133 
134         std::vector<std::string> targetBundleNames;
135         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
136             if (ConvertJSToStringVec(reinterpret_cast<napi_env>(&engine),
137                 reinterpret_cast<napi_value>(info.argv[PARAM0]), targetBundleNames)) {
138                 HILOG_INFO("targetBundleNames's size = %{public}zu", targetBundleNames.size());
139             } else {
140                 errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
141             }
142         }
143 
144         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
145             HILOG_ERROR("invalid param");
146             engine.Throw(CreateJsError(engine,
147                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
148                 ERROR_MESSAGE_PARAMETER_ERROR));
149             return engine.CreateUndefined();
150         }
151 
152         AsyncTask::CompleteCallback complete =
153             [weak = context_, targetBundleNames](NativeEngine& engine, AsyncTask& task, int32_t status) {
154                 HILOG_INFO("SetTargetBundleName begin");
155                 auto context = weak.lock();
156                 if (!context) {
157                     HILOG_ERROR("context is released");
158                     task.Reject(engine, CreateJsError(engine,
159                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
160                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
161                     return;
162                 }
163 
164                 RetError ret = context->SetTargetBundleName(targetBundleNames);
165                 if (ret == RET_OK) {
166                     task.Resolve(engine, engine.CreateUndefined());
167                 } else {
168                     HILOG_ERROR("set target bundle name failed. ret: %{public}d.", ret);
169                     task.Reject(engine, CreateJsError(engine,
170                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
171                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
172                 }
173             };
174 
175         NativeValue* lastParam = (info.argc == ARGS_SIZE_ONE) ? nullptr :
176             ((info.argv[PARAM1] != nullptr && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) ?
177             info.argv[PARAM1] : nullptr);
178         NativeValue* result = nullptr;
179         AsyncTask::Schedule("NAccessibilityExtensionContext::OnSetTargetBundleName",
180             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
181         return result;
182     }
183 
OnGetFocusElement(NativeEngine & engine,NativeCallbackInfo & info)184     NativeValue* OnGetFocusElement(NativeEngine& engine, NativeCallbackInfo& info)
185     {
186         HILOG_INFO();
187         bool isAccessibilityFocus = false;
188         NativeValue* lastParam = nullptr;
189         if (info.argc >= ARGS_SIZE_TWO) {
190             if (info.argv[PARAM0] != nullptr && info.argv[PARAM1] != nullptr &&
191                 info.argv[PARAM0]->TypeOf() == NATIVE_BOOLEAN && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
192                 lastParam = ConvertFromJsValue(engine, info.argv[PARAM0], isAccessibilityFocus) ?
193                     info.argv[PARAM1] : nullptr;
194             } else if (info.argv[PARAM1] != nullptr && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
195                 HILOG_INFO("argc is more than two, use callback: situation 1");
196                 lastParam = info.argv[PARAM1];
197             } else if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_FUNCTION) {
198                 HILOG_INFO("argc is more than two, use callback: situation 2");
199                 lastParam = info.argv[PARAM0];
200             } else if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_BOOLEAN) {
201                 HILOG_INFO("argc is more than two, use promise: situation 3");
202                 lastParam = nullptr;
203                 ConvertFromJsValue(engine, info.argv[PARAM0], isAccessibilityFocus);
204             } else {
205                 lastParam = nullptr;
206                 HILOG_INFO("argc is more than two, use promise");
207             }
208         } else if (info.argc == ARGS_SIZE_ONE) {
209             if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_FUNCTION) {
210                 lastParam = info.argv[PARAM0];
211             } else {
212                 if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_BOOLEAN) {
213                     ConvertFromJsValue(engine, info.argv[PARAM0], isAccessibilityFocus);
214                 }
215                 lastParam = nullptr;
216                 HILOG_INFO("argc is one, use promise");
217             }
218         } else {
219             lastParam = nullptr;
220             HILOG_INFO("argc is others, use promise");
221         }
222 
223         int32_t focus = isAccessibilityFocus ? FOCUS_TYPE_ACCESSIBILITY : FOCUS_TYPE_INPUT;
224         HILOG_DEBUG("focus type is [%{public}d]", focus);
225 
226         AsyncTask::CompleteCallback complete =
227             [weak = context_, focus](NativeEngine& engine, AsyncTask& task, int32_t status) {
228                 HILOG_INFO("GetFocusElement begin");
229                 auto context = weak.lock();
230                 if (!context) {
231                     HILOG_ERROR("context is released");
232                     task.Reject(engine, CreateJsError(engine,
233                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
234                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
235                     return;
236                 }
237 
238                 OHOS::Accessibility::AccessibilityElementInfo elementInfo;
239                 RetError ret = context->GetFocus(focus, elementInfo);
240                 if (ret == RET_OK) {
241                     napi_value constructor = nullptr;
242                     napi_get_reference_value(reinterpret_cast<napi_env>(&engine), NAccessibilityElement::consRef_,
243                         &constructor);
244                     napi_value napiElementInfo = nullptr;
245                     napi_new_instance(reinterpret_cast<napi_env>(&engine), constructor, 0, nullptr, &napiElementInfo);
246                     NAccessibilityElement::ConvertElementInfoToJS(reinterpret_cast<napi_env>(&engine),
247                         napiElementInfo, elementInfo);
248                     NativeValue* nativeElementInfo = reinterpret_cast<NativeValue*>(napiElementInfo);
249                     task.Resolve(engine, nativeElementInfo);
250                 } else {
251                     HILOG_ERROR("Get focus elementInfo failed. ret: %{public}d", ret);
252                     task.Reject(engine, CreateJsError(engine,
253                         static_cast<int32_t>(ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).errCode),
254                         ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).message));
255                 }
256             };
257 
258         NativeValue* result = nullptr;
259         AsyncTask::Schedule("NAccessibilityExtensionContext::OnGetFocusElement",
260             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
261         return result;
262     }
263 
OnGetWindowRootElement(NativeEngine & engine,NativeCallbackInfo & info)264     NativeValue* OnGetWindowRootElement(NativeEngine& engine, NativeCallbackInfo& info)
265     {
266         HILOG_INFO();
267         int32_t windowId = INVALID_WINDOW_ID;
268         bool isActiveWindow = true;
269         NativeValue* lastParam = nullptr;
270         if (info.argc >= ARGS_SIZE_TWO) {
271             if (info.argv[PARAM0] != nullptr && info.argv[PARAM1] != nullptr &&
272                 info.argv[PARAM0]->TypeOf() == NATIVE_NUMBER && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
273                 if (ConvertFromJsValue(engine, info.argv[PARAM0], windowId)) {
274                     lastParam = info.argv[PARAM1];
275                     isActiveWindow = false;
276                 } else {
277                     HILOG_ERROR("argc is more than two, convert window id failed");
278                     lastParam = info.argv[PARAM1];
279                 }
280             } else if (info.argv[PARAM1] != nullptr && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
281                 HILOG_INFO("argc is more than two, use callback: situation 1");
282                 lastParam = info.argv[PARAM1];
283             } else if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_FUNCTION) {
284                 HILOG_INFO("argc is more than two, use callback: situation 2");
285                 lastParam = info.argv[PARAM0];
286             } else if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_NUMBER) {
287                 HILOG_INFO("argc is more than two, use promise: situation 3");
288                 lastParam = nullptr;
289                 isActiveWindow = !ConvertFromJsValue(engine, info.argv[PARAM0], windowId);
290             } else {
291                 lastParam = nullptr;
292                 HILOG_INFO("argc is two, use promise");
293             }
294         } else if (info.argc == ARGS_SIZE_ONE) {
295             if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_FUNCTION) {
296                 lastParam = info.argv[PARAM0];
297             } else {
298                 if ((info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_NUMBER) &&
299                     ConvertFromJsValue(engine, info.argv[PARAM0], windowId)) {
300                     isActiveWindow = false;
301                 }
302                 lastParam = nullptr;
303                 HILOG_INFO("argc is one, use promise");
304             }
305         } else {
306             lastParam = nullptr;
307             HILOG_INFO("argc is others, use promise");
308         }
309 
310         AsyncTask::CompleteCallback complete =
311             [weak = context_, windowId, isActiveWindow](NativeEngine& engine, AsyncTask& task, int32_t status) {
312                 HILOG_INFO("GetWindowRootElement begin");
313                 auto context = weak.lock();
314                 if (!context) {
315                     HILOG_ERROR("context is released");
316                     task.Reject(engine, CreateJsError(engine,
317                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
318                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
319                     return;
320                 }
321 
322                 HILOG_DEBUG("isActiveWindow[%{public}d] windowId[%{public}d]", isActiveWindow, windowId);
323                 OHOS::Accessibility::AccessibilityElementInfo elementInfo;
324                 RetError ret = RET_OK;
325                 if (isActiveWindow) {
326                     ret = context->GetRoot(elementInfo);
327                 } else {
328                     AccessibilityWindowInfo windowInfo;
329                     windowInfo.SetWindowId(windowId);
330                     ret = context->GetRootByWindow(windowInfo, elementInfo);
331                 }
332                 if (ret == RET_OK) {
333                     napi_value constructor = nullptr;
334                     napi_get_reference_value(reinterpret_cast<napi_env>(&engine), NAccessibilityElement::consRef_,
335                         &constructor);
336                     napi_value napiElementInfo = nullptr;
337                     napi_status result = napi_new_instance(reinterpret_cast<napi_env>(&engine), constructor, 0, nullptr,
338                         &napiElementInfo);
339                     HILOG_DEBUG("napi_new_instance result is %{public}d", result);
340                     NAccessibilityElement::ConvertElementInfoToJS(reinterpret_cast<napi_env>(&engine),
341                         napiElementInfo, elementInfo);
342                     NativeValue* nativeElementInfo = reinterpret_cast<NativeValue*>(napiElementInfo);
343                     task.Resolve(engine, nativeElementInfo);
344                 } else {
345                     HILOG_ERROR("Get root elementInfo failed. ret : %{public}d", ret);
346                     task.Reject(engine, CreateJsError(engine,
347                         static_cast<int32_t>(ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).errCode),
348                         ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).message));
349                 }
350             };
351 
352         NativeValue* result = nullptr;
353         AsyncTask::Schedule("NAccessibilityExtensionContext::OnGetWindowRootElement",
354             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
355         return result;
356     }
357 
OnGetWindows(NativeEngine & engine,NativeCallbackInfo & info)358     NativeValue* OnGetWindows(NativeEngine& engine, NativeCallbackInfo& info)
359     {
360         HILOG_INFO();
361 
362         int64_t displayId = 0;
363         bool hasDisplayId = false;
364         NativeValue* lastParam = nullptr;
365         if (info.argc >= ARGS_SIZE_TWO) {
366             if (info.argv[PARAM0] != nullptr && info.argv[PARAM1] != nullptr &&
367                 info.argv[PARAM0]->TypeOf() == NATIVE_NUMBER && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
368                 if (ConvertFromJsValue(engine, info.argv[PARAM0], displayId)) {
369                     lastParam = info.argv[PARAM1];
370                     hasDisplayId = true;
371                 } else {
372                     HILOG_ERROR("Convert displayId from js value failed");
373                     lastParam = info.argv[PARAM1];
374                 }
375             } else if (info.argv[PARAM1] != nullptr && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
376                 HILOG_INFO("argc is more than two, use callback: situation 1");
377                 lastParam = info.argv[PARAM1];
378             } else if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_FUNCTION) {
379                 HILOG_INFO("argc is more than two, use callback: situation 2");
380                 lastParam = info.argv[PARAM0];
381             } else if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_NUMBER) {
382                 HILOG_INFO("argc is more than two, use promise: situation 3");
383                 lastParam = nullptr;
384                 hasDisplayId = ConvertFromJsValue(engine, info.argv[PARAM0], displayId);
385             } else {
386                 lastParam = nullptr;
387                 HILOG_INFO("argc is more than two, use promise");
388             }
389         } else if (info.argc == ARGS_SIZE_ONE) {
390             if (info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_FUNCTION) {
391                 lastParam = info.argv[PARAM0];
392             } else {
393                 if ((info.argv[PARAM0] != nullptr && info.argv[PARAM0]->TypeOf() == NATIVE_NUMBER) &&
394                     ConvertFromJsValue(engine, info.argv[PARAM0], displayId)) {
395                     hasDisplayId = true;
396                 }
397                 lastParam = nullptr;
398                 HILOG_INFO("argc is one, use promise");
399             }
400         } else {
401             lastParam = nullptr;
402             HILOG_INFO("argc is others, use promise");
403         }
404 
405         return hasDisplayId ? GetWindowsByDisplayIdAsync(engine, lastParam, displayId) :
406             GetWindowsAsync(engine, lastParam);
407     }
408 
GetWindowsAsync(NativeEngine & engine,NativeValue * lastParam)409     NativeValue* GetWindowsAsync(NativeEngine& engine, NativeValue* lastParam)
410     {
411         HILOG_INFO();
412         AsyncTask::CompleteCallback complete =
413             [weak = context_](NativeEngine& engine, AsyncTask& task, int32_t status) {
414                 HILOG_INFO("GetWindows begin");
415                 auto context = weak.lock();
416                 if (!context) {
417                     HILOG_ERROR("context is released");
418                     task.Reject(engine, CreateJsError(engine,
419                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
420                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
421                     return;
422                 }
423 
424                 std::vector<OHOS::Accessibility::AccessibilityWindowInfo> accessibilityWindows;
425                 RetError ret = context->GetWindows(accessibilityWindows);
426                 if (ret == RET_OK) {
427                     napi_value napiWindowInfos = nullptr;
428                     napi_create_array(reinterpret_cast<napi_env>(&engine), &napiWindowInfos);
429                     ConvertAccessibilityWindowInfosToJS(
430                         reinterpret_cast<napi_env>(&engine), napiWindowInfos, accessibilityWindows);
431                     NativeValue* nativeWindowInfos = reinterpret_cast<NativeValue*>(napiWindowInfos);
432                     task.Resolve(engine, nativeWindowInfos);
433                 } else {
434                     HILOG_ERROR("Get windowInfos failed.");
435                     task.Reject(engine, CreateJsError(engine,
436                         static_cast<int32_t>(ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).errCode),
437                         ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).message));
438                 }
439             };
440 
441         NativeValue* result = nullptr;
442         AsyncTask::Schedule("NAccessibilityExtensionContext::GetWindowsAsync",
443             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
444         return result;
445     }
446 
GetWindowsByDisplayIdAsync(NativeEngine & engine,NativeValue * lastParam,int64_t displayId)447     NativeValue* GetWindowsByDisplayIdAsync(NativeEngine& engine, NativeValue* lastParam, int64_t displayId)
448     {
449         HILOG_INFO();
450         AsyncTask::CompleteCallback complete =
451             [weak = context_, displayId](NativeEngine& engine, AsyncTask& task, int32_t status) {
452                 HILOG_INFO("GetWindows begin");
453                 auto context = weak.lock();
454                 if (!context) {
455                     HILOG_ERROR("context is released");
456                     task.Reject(engine, CreateJsError(engine,
457                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
458                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
459                     return;
460                 }
461 
462                 if (displayId < 0) {
463                     HILOG_ERROR("displayId is error: %{public}" PRId64 "", displayId);
464                     task.Reject(engine, CreateJsError(engine,
465                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
466                         ERROR_MESSAGE_PARAMETER_ERROR));
467                     return;
468                 }
469 
470                 std::vector<OHOS::Accessibility::AccessibilityWindowInfo> accessibilityWindows;
471                 RetError ret = context->GetWindows(static_cast<uint64_t>(displayId), accessibilityWindows);
472                 if (ret == RET_OK) {
473                     napi_value napiWindowInfos = nullptr;
474                     napi_create_array(reinterpret_cast<napi_env>(&engine), &napiWindowInfos);
475                     ConvertAccessibilityWindowInfosToJS(
476                         reinterpret_cast<napi_env>(&engine), napiWindowInfos, accessibilityWindows);
477                     NativeValue* nativeWindowInfos = reinterpret_cast<NativeValue*>(napiWindowInfos);
478                     task.Resolve(engine, nativeWindowInfos);
479                 } else {
480                     HILOG_ERROR("Get windowInfos failed.");
481                     task.Reject(engine, CreateJsError(engine,
482                         static_cast<int32_t>(ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).errCode),
483                         ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).message));
484                 }
485             };
486 
487         NativeValue* result = nullptr;
488         AsyncTask::Schedule("NAccessibilityExtensionContext::GetWindowsByDisplayIdAsync",
489             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
490         return result;
491     }
492 
OnGestureInject(NativeEngine & engine,NativeCallbackInfo & info)493     NativeValue* OnGestureInject(NativeEngine& engine, NativeCallbackInfo& info)
494     {
495         HILOG_INFO();
496         NAccessibilityErrorCode errCode = NAccessibilityErrorCode::ACCESSIBILITY_OK;
497         if (info.argc < ARGS_SIZE_ONE) {
498             HILOG_ERROR("Not enough params");
499             errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
500         }
501 
502         napi_value nGesturePaths = reinterpret_cast<napi_value>(info.argv[PARAM0]);
503         std::shared_ptr<AccessibilityGestureInjectPath> gesturePath =
504             std::make_shared<AccessibilityGestureInjectPath>();
505         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_OK) {
506             if (!ConvertGesturePathJSToNAPI(reinterpret_cast<napi_env>(&engine), nGesturePaths, gesturePath)) {
507                 errCode = NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM;
508             }
509         }
510 
511         if (errCode == NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM) {
512             HILOG_ERROR("invalid param");
513             engine.Throw(CreateJsError(engine,
514                 static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_INVALID_PARAM),
515                 ERROR_MESSAGE_PARAMETER_ERROR));
516             return engine.CreateUndefined();
517         }
518 
519         AsyncTask::CompleteCallback complete =
520             [weak = context_, gesturePath](
521             NativeEngine& engine, AsyncTask& task, int32_t status) {
522                 auto context = weak.lock();
523                 if (!context) {
524                     HILOG_ERROR("context is released");
525                     task.Reject(engine, CreateJsError(engine,
526                         static_cast<int32_t>(NAccessibilityErrorCode::ACCESSIBILITY_ERROR_SYSTEM_ABNORMALITY),
527                         ERROR_MESSAGE_SYSTEM_ABNORMALITY));
528                     return;
529                 }
530                 RetError ret = context->InjectGesture(gesturePath);
531                 if (ret == RET_OK) {
532                     task.Resolve(engine, engine.CreateUndefined());
533                 } else {
534                     HILOG_ERROR("Gesture inject failed. ret: %{public}d.", ret);
535                     task.Reject(engine, CreateJsError(engine,
536                         static_cast<int32_t>(ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).errCode),
537                         ACCESSIBILITY_JS_TO_ERROR_CODE_MAP.at(ret).message));
538                 }
539             };
540 
541         NativeValue* lastParam = (info.argc == ARGS_SIZE_ONE) ? nullptr :
542             ((info.argv[PARAM1] != nullptr && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) ?
543             info.argv[PARAM1] : nullptr);
544         NativeValue* result = nullptr;
545         AsyncTask::Schedule("NAccessibilityExtensionContext::OnGestureInject",
546             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
547         return result;
548     }
549 };
550 } // namespace
551 
CreateJsAccessibilityExtensionContext(NativeEngine & engine,std::shared_ptr<AccessibilityExtensionContext> context)552 NativeValue* CreateJsAccessibilityExtensionContext(
553     NativeEngine& engine, std::shared_ptr<AccessibilityExtensionContext> context)
554 {
555     HILOG_INFO();
556     NativeValue* objValue = CreateJsExtensionContext(engine, context);
557     NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
558 
559     std::unique_ptr<NAccessibilityExtensionContext> jsContext =
560         std::make_unique<NAccessibilityExtensionContext>(context);
561     if (!object) {
562         HILOG_ERROR("object is nullptr.");
563         return nullptr;
564     }
565     object->SetNativePointer(jsContext.release(), NAccessibilityExtensionContext::Finalizer, nullptr);
566 
567     const char *moduleName = "NAccessibilityExtensionContext";
568     BindNativeFunction(engine, *object, "setTargetBundleName", moduleName,
569         NAccessibilityExtensionContext::SetTargetBundleName);
570     BindNativeFunction(engine, *object, "getFocusElement", moduleName,
571         NAccessibilityExtensionContext::GetFocusElement);
572     BindNativeFunction(engine, *object, "getWindowRootElement", moduleName,
573         NAccessibilityExtensionContext::GetWindowRootElement);
574     BindNativeFunction(engine, *object, "getWindows", moduleName, NAccessibilityExtensionContext::GetWindows);
575     BindNativeFunction(engine, *object, "injectGesture", moduleName, NAccessibilityExtensionContext::InjectGesture);
576 
577     return objValue;
578 }
579 } // namespace Accessibility
580 } // namespace OHOS