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