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.h"
17
18 #include <uv.h>
19 #include "accessible_ability_client.h"
20 #include "ability_info.h"
21 #include "hilog_wrapper.h"
22 #include "js_runtime.h"
23 #include "js_runtime_utils.h"
24 #include "napi_accessibility_event_info.h"
25 #include "napi_accessibility_extension_context.h"
26 #include "accessibility_utils.h"
27 #include "napi/native_api.h"
28 #include "napi/native_node_api.h"
29 #include "napi_accessibility_element.h"
30
31 using namespace OHOS::AbilityRuntime;
32 using namespace OHOS::AccessibilityNapi;
33
34 namespace OHOS {
35 namespace Accessibility {
36 namespace {
37 constexpr int32_t VIRTUAL_COMPONENT_ID = -1;
38 }
Create(const std::unique_ptr<AbilityRuntime::Runtime> & runtime)39 NAccessibilityExtension* NAccessibilityExtension::Create(const std::unique_ptr<AbilityRuntime::Runtime>& runtime)
40 {
41 HILOG_INFO();
42 return new(std::nothrow) NAccessibilityExtension(static_cast<AbilityRuntime::JsRuntime&>(*runtime));
43 }
44
NAccessibilityExtension(AbilityRuntime::JsRuntime & jsRuntime)45 NAccessibilityExtension::NAccessibilityExtension(AbilityRuntime::JsRuntime& jsRuntime) : jsRuntime_(jsRuntime)
46 {
47 listener_ = std::make_shared<AbilityListener>(*this);
48
49 HandleScope handleScope(jsRuntime_);
50 engine_ = &jsRuntime_.GetNativeEngine();
51 }
52
53 NAccessibilityExtension::~NAccessibilityExtension() = default;
54
OpenScope(napi_env env)55 napi_handle_scope OpenScope(napi_env env)
56 {
57 napi_handle_scope scope = nullptr;
58 NAPI_CALL(env, napi_open_handle_scope(env, &scope));
59 return scope;
60 }
61
Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> & record,const std::shared_ptr<AppExecFwk::OHOSApplication> & application,std::shared_ptr<AppExecFwk::AbilityHandler> & handler,const sptr<IRemoteObject> & token)62 void NAccessibilityExtension::Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &record,
63 const std::shared_ptr<AppExecFwk::OHOSApplication> &application,
64 std::shared_ptr<AppExecFwk::AbilityHandler> &handler, const sptr<IRemoteObject> &token)
65 {
66 HILOG_INFO();
67 AccessibilityExtension::Init(record, application, handler, token);
68 std::string srcPath = "";
69 std::string moduleName = "";
70 if (!GetSrcPathAndModuleName(srcPath, moduleName)) {
71 return;
72 }
73 jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
74 abilityInfo_->compileMode == CompileMode::ES_MODULE);
75 if (!jsObj_) {
76 HILOG_ERROR("Failed to get jsObj_");
77 return;
78 }
79 NativeObject* obj = ConvertNativeValueTo<NativeObject>(jsObj_->Get());
80 if (!obj) {
81 HILOG_ERROR("Failed to get NAccessibilityExtension object");
82 return;
83 }
84
85 auto context = GetContext();
86 if (!context) {
87 HILOG_ERROR("Failed to get context");
88 return;
89 }
90 NativeValue* contextObj = CreateJsAccessibilityExtensionContext(*engine_, context);
91 auto shellContextRef = jsRuntime_.LoadSystemModule("application.AccessibilityExtensionContext", &contextObj, 1);
92 if (!shellContextRef) {
93 HILOG_ERROR("shellContextRef is nullptr.");
94 return;
95 }
96 contextObj = shellContextRef->Get();
97 context->Bind(jsRuntime_, shellContextRef.release());
98 obj->SetProperty("context", contextObj);
99
100 auto nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
101 if (!nativeObj) {
102 HILOG_ERROR("Failed to get accessibility extension native object");
103 return;
104 }
105 nativeObj->SetNativePointer(new std::weak_ptr<AbilityRuntime::Context>(context),
106 [](NativeEngine*, void* data, void*) {
107 delete static_cast<std::weak_ptr<AbilityRuntime::Context>*>(data);
108 }, nullptr);
109 NAccessibilityElement::DefineJSAccessibilityElement(reinterpret_cast<napi_env>(engine_));
110 }
111
GetSrcPathAndModuleName(std::string & srcPath,std::string & moduleName)112 bool NAccessibilityExtension::GetSrcPathAndModuleName(std::string& srcPath, std::string& moduleName)
113 {
114 if (!Extension::abilityInfo_) {
115 HILOG_ERROR("abilityInfo_ is nullptr");
116 return false;
117 }
118 if (!Extension::abilityInfo_->isModuleJson) {
119 srcPath.append(Extension::abilityInfo_->package);
120 srcPath.append("/assets/js/");
121 if (!Extension::abilityInfo_->srcPath.empty()) {
122 srcPath.append(Extension::abilityInfo_->srcPath);
123 }
124 srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
125 } else if (!Extension::abilityInfo_->srcEntrance.empty()) {
126 srcPath.append(Extension::abilityInfo_->moduleName + "/");
127 srcPath.append(Extension::abilityInfo_->srcEntrance);
128 srcPath.erase(srcPath.rfind('.'));
129 srcPath.append(".abc");
130 } else {
131 HILOG_ERROR("Failed to get srcPath");
132 return false;
133 }
134 moduleName = Extension::abilityInfo_->moduleName;
135 moduleName.append("::").append(abilityInfo_->name);
136 HILOG_INFO("moduleName:%{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str());
137 return true;
138 }
139
OnConnect(const AAFwk::Want & want)140 sptr<IRemoteObject> NAccessibilityExtension::OnConnect(const AAFwk::Want &want)
141 {
142 HILOG_INFO();
143 Extension::OnConnect(want);
144 sptr<AccessibleAbilityClient> aaClient = AccessibleAbilityClient::GetInstance();
145 if (!aaClient) {
146 HILOG_ERROR("aaClient is nullptr");
147 return nullptr;
148 }
149 aaClient->RegisterAbilityListener(listener_);
150 return aaClient->GetRemoteObject();
151 }
152
OnAbilityConnected()153 void NAccessibilityExtension::OnAbilityConnected()
154 {
155 HILOG_INFO();
156 uv_loop_t *loop = engine_->GetUVLoop();
157 ExtensionCallbackInfo *callbackInfo = new(std::nothrow) ExtensionCallbackInfo();
158 if (!callbackInfo) {
159 HILOG_ERROR("Failed to create callbackInfo.");
160 return;
161 }
162 callbackInfo->extension_ = this;
163 uv_work_t *work = new(std::nothrow) uv_work_t;
164 if (!work) {
165 HILOG_ERROR("Failed to create data.");
166 delete callbackInfo;
167 callbackInfo = nullptr;
168 return;
169 }
170 work->data = static_cast<void*>(callbackInfo);
171
172 int ret = uv_queue_work_with_qos(
173 loop,
174 work,
175 [](uv_work_t *work) {},
176 [](uv_work_t *work, int status) {
177 ExtensionCallbackInfo *data = static_cast<ExtensionCallbackInfo*>(work->data);
178 data->extension_->CallObjectMethod("onConnect");
179 delete data;
180 data = nullptr;
181 delete work;
182 work = nullptr;
183 },
184 uv_qos_user_initiated);
185 if (ret) {
186 HILOG_ERROR("Failed to execute OnAbilityConnected work queue");
187 delete callbackInfo;
188 callbackInfo = nullptr;
189 delete work;
190 work = nullptr;
191 }
192 HILOG_INFO("end.");
193 }
194
OnAbilityDisconnected()195 void NAccessibilityExtension::OnAbilityDisconnected()
196 {
197 HILOG_INFO();
198 uv_loop_t *loop = engine_->GetUVLoop();
199 ExtensionCallbackInfo *callbackInfo = new(std::nothrow) ExtensionCallbackInfo();
200 if (!callbackInfo) {
201 HILOG_ERROR("Failed to create callbackInfo.");
202 return;
203 }
204 callbackInfo->extension_ = this;
205 uv_work_t *work = new(std::nothrow) uv_work_t;
206 if (!work) {
207 HILOG_ERROR("Failed to create data.");
208 delete callbackInfo;
209 callbackInfo = nullptr;
210 return;
211 }
212 work->data = static_cast<void*>(callbackInfo);
213 std::future syncFuture = callbackInfo->syncPromise_.get_future();
214
215 int ret = uv_queue_work_with_qos(
216 loop,
217 work,
218 [](uv_work_t *work) {},
219 [](uv_work_t *work, int status) {
220 ExtensionCallbackInfo *data = static_cast<ExtensionCallbackInfo*>(work->data);
221 data->extension_->CallObjectMethod("onDisconnect");
222 data->syncPromise_.set_value();
223 delete data;
224 data = nullptr;
225 delete work;
226 work = nullptr;
227 },
228 uv_qos_user_initiated);
229 if (ret) {
230 HILOG_ERROR("Failed to execute OnAbilityDisconnected work queue");
231 callbackInfo->syncPromise_.set_value();
232 delete callbackInfo;
233 callbackInfo = nullptr;
234 delete work;
235 work = nullptr;
236 }
237 syncFuture.get();
238 HILOG_INFO("end.");
239 }
240
GetElement(const AccessibilityEventInfo & eventInfo)241 std::shared_ptr<AccessibilityElement> NAccessibilityExtension::GetElement(const AccessibilityEventInfo& eventInfo)
242 {
243 HILOG_DEBUG();
244
245 sptr<AccessibleAbilityClient> aaClient = AccessibleAbilityClient::GetInstance();
246 if (!aaClient) {
247 return nullptr;
248 }
249 int32_t componentId = eventInfo.GetAccessibilityId();
250 int32_t windowId = eventInfo.GetWindowId();
251 std::shared_ptr<AccessibilityElement> element = nullptr;
252 if (componentId > 0) {
253 std::shared_ptr<AccessibilityElementInfo> elementInfo = std::make_shared<AccessibilityElementInfo>();
254 if (aaClient->GetSource(eventInfo, *elementInfo) == RET_OK) {
255 element = std::make_shared<AccessibilityElement>(elementInfo);
256 }
257 } else if (windowId > 0) {
258 std::shared_ptr<AccessibilityWindowInfo> windowInfo = std::make_shared<AccessibilityWindowInfo>();
259 if (aaClient->GetWindow(windowId, *windowInfo) == RET_OK) {
260 element = std::make_shared<AccessibilityElement>(windowInfo);
261 }
262 } else {
263 std::shared_ptr<AccessibilityElementInfo> elementInfo = std::make_shared<AccessibilityElementInfo>();
264 CreateElementInfoByEventInfo(eventInfo, elementInfo);
265 element = std::make_shared<AccessibilityElement>(elementInfo);
266 }
267 return element;
268 }
269
CreateElementInfoByEventInfo(const AccessibilityEventInfo & eventInfo,const std::shared_ptr<AccessibilityElementInfo> & elementInfo)270 void NAccessibilityExtension::CreateElementInfoByEventInfo(const AccessibilityEventInfo& eventInfo,
271 const std::shared_ptr<AccessibilityElementInfo> &elementInfo)
272 {
273 HILOG_DEBUG();
274 if (!elementInfo) {
275 return;
276 }
277 elementInfo->SetComponentId(VIRTUAL_COMPONENT_ID);
278 elementInfo->SetBundleName(eventInfo.GetBundleName());
279 elementInfo->SetComponentType(eventInfo.GetComponentType());
280 elementInfo->SetPageId(eventInfo.GetPageId());
281 elementInfo->SetDescriptionInfo(eventInfo.GetDescription());
282 elementInfo->SetTriggerAction(eventInfo.GetTriggerAction());
283 elementInfo->SetTextMovementStep(eventInfo.GetTextMovementStep());
284 elementInfo->SetContentList(eventInfo.GetContentList());
285 elementInfo->SetLatestContent(eventInfo.GetLatestContent());
286 elementInfo->SetBeginIndex(eventInfo.GetBeginIndex());
287 elementInfo->SetCurrentIndex(eventInfo.GetCurrentIndex());
288 elementInfo->SetEndIndex(eventInfo.GetEndIndex());
289 elementInfo->SetItemCounts(eventInfo.GetItemCounts());
290 }
291
ConvertAccessibilityElementToJS(napi_env env,napi_value objEventInfo,const std::shared_ptr<AccessibilityElement> & element)292 void ConvertAccessibilityElementToJS(napi_env env, napi_value objEventInfo,
293 const std::shared_ptr<AccessibilityElement>& element)
294 {
295 HILOG_DEBUG();
296 if (!element) {
297 HILOG_DEBUG("No element information.");
298 return;
299 }
300 AccessibilityElement* pAccessibilityElement = new(std::nothrow) AccessibilityElement(*element);
301 if (!pAccessibilityElement) {
302 HILOG_ERROR("Failed to create AccessibilityElement.");
303 return;
304 }
305 auto closeScope = [env](napi_handle_scope scope) { napi_close_handle_scope(env, scope); };
306 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(OpenScope(env), closeScope);
307 napi_value nTargetObject = nullptr;
308 napi_value constructor = nullptr;
309 napi_get_reference_value(env, NAccessibilityElement::consRef_, &constructor);
310 napi_new_instance(env, constructor, 0, nullptr, &nTargetObject);
311 // Bind js object to a Native object
312 napi_status sts = napi_wrap(
313 env,
314 nTargetObject,
315 pAccessibilityElement,
316 [](napi_env env, void* data, void* hint) {
317 AccessibilityElement* info = static_cast<AccessibilityElement*>(data);
318 delete info;
319 info = nullptr;
320 },
321 nullptr,
322 nullptr);
323 HILOG_DEBUG("napi_wrap status: %{public}d", (int)sts);
324 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objEventInfo, "target", nTargetObject));
325 }
326
OnAccessibilityEventExec(uv_work_t * work,uv_loop_t * loop)327 int NAccessibilityExtension::OnAccessibilityEventExec(uv_work_t *work, uv_loop_t *loop)
328 {
329 int ret = uv_queue_work_with_qos(
330 loop,
331 work,
332 [](uv_work_t *work) {},
333 [](uv_work_t *work, int status) {
334 AccessibilityEventInfoCallbackInfo *data = static_cast<AccessibilityEventInfoCallbackInfo*>(work->data);
335 auto closeScope = [data](napi_handle_scope scope) {
336 napi_close_handle_scope(reinterpret_cast<napi_env>(data->engine_), scope);
337 };
338 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
339 OpenScope(reinterpret_cast<napi_env>(data->engine_)), closeScope);
340 napi_value napiEventInfo = nullptr;
341 napi_create_object(reinterpret_cast<napi_env>(data->engine_), &napiEventInfo);
342
343 napi_value nType;
344 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
345 napi_create_string_utf8(reinterpret_cast<napi_env>(data->engine_), data->eventType_.c_str(),
346 NAPI_AUTO_LENGTH, &nType));
347 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
348 napi_set_named_property(reinterpret_cast<napi_env>(data->engine_), napiEventInfo, "eventType", nType));
349 HILOG_DEBUG("eventType[%{public}s]", data->eventType_.c_str());
350
351 napi_value nTimeStamp;
352 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
353 napi_create_int64(reinterpret_cast<napi_env>(data->engine_), data->timeStamp_, &nTimeStamp));
354 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
355 napi_set_named_property(reinterpret_cast<napi_env>(data->engine_),
356 napiEventInfo, "timeStamp", nTimeStamp));
357
358 ConvertAccessibilityElementToJS(reinterpret_cast<napi_env>(data->engine_), napiEventInfo, data->element_);
359 NativeValue* nativeEventInfo = reinterpret_cast<NativeValue*>(napiEventInfo);
360 NativeValue* argv[] = {nativeEventInfo};
361 data->extension_->CallObjectMethod("onAccessibilityEvent", argv, 1);
362 delete data;
363 data = nullptr;
364 delete work;
365 work = nullptr;
366 },
367 uv_qos_user_initiated);
368 return ret;
369 }
370
OnAccessibilityEvent(const AccessibilityEventInfo & eventInfo)371 void NAccessibilityExtension::OnAccessibilityEvent(const AccessibilityEventInfo& eventInfo)
372 {
373 HILOG_INFO();
374 std::string strType = "";
375 ConvertEventTypeToString(eventInfo, strType);
376 if (strType.empty()) {
377 HILOG_DEBUG("eventType is invalid.");
378 return;
379 }
380 uv_loop_t *loop = engine_->GetUVLoop();
381 AccessibilityEventInfoCallbackInfo *callbackInfo = new(std::nothrow) AccessibilityEventInfoCallbackInfo();
382 if (!callbackInfo) {
383 HILOG_ERROR("Failed to create callbackInfo.");
384 return;
385 }
386 callbackInfo->engine_ = engine_;
387 callbackInfo->extension_ = this;
388 callbackInfo->eventType_ = strType;
389 callbackInfo->timeStamp_ = eventInfo.GetTimeStamp();
390 callbackInfo->element_ = GetElement(eventInfo);
391 uv_work_t *work = new(std::nothrow) uv_work_t;
392 if (!work) {
393 HILOG_ERROR("Failed to create data.");
394 delete callbackInfo;
395 callbackInfo = nullptr;
396 return;
397 }
398 work->data = static_cast<void*>(callbackInfo);
399
400 if (OnAccessibilityEventExec(work, loop)) {
401 HILOG_ERROR("Failed to execute OnAccessibilityEvent work queue");
402 delete callbackInfo;
403 callbackInfo = nullptr;
404 delete work;
405 work = nullptr;
406 }
407 }
408
OnAccessibilityEventCompleteCallback(uv_work_t * work,int status)409 void NAccessibilityExtension::OnAccessibilityEventCompleteCallback(uv_work_t* work, int status)
410 {
411 AccessibilityEventInfoCallbackInfo *data = static_cast<AccessibilityEventInfoCallbackInfo*>(work->data);
412 auto closeScope = [data](napi_handle_scope scope) {
413 napi_close_handle_scope(reinterpret_cast<napi_env>(data->engine_), scope);
414 };
415 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
416 OpenScope(reinterpret_cast<napi_env>(data->engine_)), closeScope);
417 napi_value napiEventInfo = nullptr;
418 napi_create_object(reinterpret_cast<napi_env>(data->engine_), &napiEventInfo);
419
420 napi_value nType;
421 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
422 napi_create_string_utf8(reinterpret_cast<napi_env>(data->engine_), data->eventType_.c_str(),
423 NAPI_AUTO_LENGTH, &nType));
424 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
425 napi_set_named_property(reinterpret_cast<napi_env>(data->engine_), napiEventInfo, "eventType", nType));
426 HILOG_DEBUG("eventType[%{public}s]", data->eventType_.c_str());
427
428 napi_value nTimeStamp;
429 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
430 napi_create_int64(reinterpret_cast<napi_env>(data->engine_), data->timeStamp_, &nTimeStamp));
431 NAPI_CALL_RETURN_VOID(reinterpret_cast<napi_env>(data->engine_),
432 napi_set_named_property(reinterpret_cast<napi_env>(data->engine_),
433 napiEventInfo, "timeStamp", nTimeStamp));
434
435 ConvertAccessibilityElementToJS(reinterpret_cast<napi_env>(data->engine_), napiEventInfo, data->element_);
436 NativeValue* nativeEventInfo = reinterpret_cast<NativeValue*>(napiEventInfo);
437 NativeValue* argv[] = {nativeEventInfo};
438 data->extension_->CallObjectMethod("onAccessibilityEvent", argv, 1);
439 delete data;
440 data = nullptr;
441 delete work;
442 work = nullptr;
443 }
444
OnKeyPressEventExec(uv_work_t * work,uv_loop_t * loop)445 int NAccessibilityExtension::OnKeyPressEventExec(uv_work_t *work, uv_loop_t *loop)
446 {
447 int ret = uv_queue_work_with_qos(
448 loop,
449 work,
450 [](uv_work_t *work) {},
451 [](uv_work_t *work, int status) {
452 KeyEventCallbackInfo *data = static_cast<KeyEventCallbackInfo*>(work->data);
453 auto closeScope = [data](napi_handle_scope scope) {
454 napi_close_handle_scope(reinterpret_cast<napi_env>(data->engine_), scope);
455 };
456 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
457 OpenScope(reinterpret_cast<napi_env>(data->engine_)), closeScope);
458 napi_value napiEventInfo = nullptr;
459 if (napi_create_object(reinterpret_cast<napi_env>(data->engine_), &napiEventInfo) != napi_ok) {
460 HILOG_ERROR("Create keyEvent object failed.");
461 data->syncPromise_.set_value(false);
462 delete data;
463 data = nullptr;
464 delete work;
465 work = nullptr;
466 return;
467 }
468 ConvertKeyEventToJS(reinterpret_cast<napi_env>(data->engine_), napiEventInfo, data->keyEvent_);
469 NativeValue* nativeEventInfo = reinterpret_cast<NativeValue*>(napiEventInfo);
470 NativeValue* argv[] = {nativeEventInfo};
471 NativeValue* nativeResult = data->extension_->CallObjectMethod("onKeyEvent", argv, 1);
472
473 // Unwrap result
474 bool result = false;
475 if (!ConvertFromJsValue(*data->engine_, nativeResult, result)) {
476 HILOG_ERROR("ConvertFromJsValue failed");
477 data->syncPromise_.set_value(false);
478 delete data;
479 data = nullptr;
480 delete work;
481 work = nullptr;
482 return;
483 }
484 HILOG_INFO("OnKeyPressEvent result = %{public}d", result);
485 data->syncPromise_.set_value(result);
486 delete data;
487 data = nullptr;
488 delete work;
489 work = nullptr;
490 },
491 uv_qos_user_initiated);
492 return ret;
493 }
494
OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)495 bool NAccessibilityExtension::OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent)
496 {
497 HILOG_INFO();
498 uv_loop_t *loop = engine_->GetUVLoop();
499 KeyEventCallbackInfo *callbackInfo = new(std::nothrow) KeyEventCallbackInfo();
500 if (!callbackInfo) {
501 HILOG_ERROR("Failed to create callbackInfo.");
502 return false;
503 }
504 callbackInfo->engine_ = engine_;
505 callbackInfo->keyEvent_ = MMI::KeyEvent::Clone(keyEvent);
506 callbackInfo->extension_ = this;
507 uv_work_t *work = new(std::nothrow) uv_work_t;
508 if (!work) {
509 HILOG_ERROR("Failed to create data.");
510 delete callbackInfo;
511 callbackInfo = nullptr;
512 return false;
513 }
514 work->data = static_cast<void*>(callbackInfo);
515 std::future syncFuture = callbackInfo->syncPromise_.get_future();
516
517 if (OnKeyPressEventExec(work, loop)) {
518 HILOG_ERROR("Failed to execute OnKeyPressEvent work queue");
519 callbackInfo->syncPromise_.set_value(false);
520 delete callbackInfo;
521 callbackInfo = nullptr;
522 delete work;
523 work = nullptr;
524 }
525 bool callbackResult = syncFuture.get();
526 HILOG_INFO("OnKeyPressEvent callbackResult = %{public}d", callbackResult);
527 return callbackResult;
528 }
529
OnKeyPressEventCompleteCallback(uv_work_t * work,int status)530 void NAccessibilityExtension::OnKeyPressEventCompleteCallback(uv_work_t* work, int status)
531 {
532 KeyEventCallbackInfo *data = static_cast<KeyEventCallbackInfo*>(work->data);
533 auto closeScope = [data](napi_handle_scope scope) {
534 napi_close_handle_scope(reinterpret_cast<napi_env>(data->engine_), scope);
535 };
536 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes(
537 OpenScope(reinterpret_cast<napi_env>(data->engine_)), closeScope);
538 napi_value napiEventInfo = nullptr;
539 if (napi_create_object(reinterpret_cast<napi_env>(data->engine_), &napiEventInfo) != napi_ok) {
540 HILOG_ERROR("Create keyEvent object failed.");
541 data->syncPromise_.set_value(false);
542 delete data;
543 data = nullptr;
544 delete work;
545 work = nullptr;
546 return;
547 }
548 ConvertKeyEventToJS(reinterpret_cast<napi_env>(data->engine_), napiEventInfo, data->keyEvent_);
549 NativeValue* nativeEventInfo = reinterpret_cast<NativeValue*>(napiEventInfo);
550 NativeValue* argv[] = {nativeEventInfo};
551 NativeValue* nativeResult = data->extension_->CallObjectMethod("onKeyEvent", argv, 1);
552
553 // Unwrap result
554 bool result = false;
555 if (!ConvertFromJsValue(*data->engine_, nativeResult, result)) {
556 HILOG_ERROR("ConvertFromJsValue failed");
557 data->syncPromise_.set_value(false);
558 delete data;
559 data = nullptr;
560 delete work;
561 work = nullptr;
562 return;
563 }
564 HILOG_INFO("OnKeyPressEvent result = %{public}d", result);
565 data->syncPromise_.set_value(result);
566 delete data;
567 data = nullptr;
568 delete work;
569 work = nullptr;
570 }
571
CallObjectMethod(const char * name,NativeValue * const * argv,size_t argc)572 NativeValue* NAccessibilityExtension::CallObjectMethod(const char* name, NativeValue* const* argv, size_t argc)
573 {
574 HILOG_INFO("name:%{public}s", name);
575 if (!jsObj_) {
576 HILOG_ERROR("jsObj_ is nullptr");
577 return nullptr;
578 }
579
580 NativeValue* value = jsObj_->Get();
581 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
582 if (!obj) {
583 HILOG_ERROR("Failed to get AccessibilityExtension object");
584 return nullptr;
585 }
586
587 NativeValue* method = obj->GetProperty(name);
588 if (!method) {
589 HILOG_ERROR("Failed to get '%{public}s' from AccessibilityExtension object", name);
590 return nullptr;
591 }
592 HILOG_INFO("CallFunction(%{public}s), success", name);
593 return engine_->CallFunction(value, method, argv, argc);
594 }
595 } // namespace Accessibility
596 } // namespace OHOS
597