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