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