1 /*
2 * Copyright (c) 2021-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 #include "feature_ability.h"
16
17 #include <cstring>
18 #include <uv.h>
19 #include <vector>
20
21 #include "../inner/napi_common/napi_common_ability.h"
22 #include "../inner/napi_common/js_napi_common_ability.h"
23 #include "ability_process.h"
24 #include "element_name.h"
25 #include "hilog_wrapper.h"
26 #include "hitrace_meter.h"
27 #include "js_runtime_utils.h"
28 #ifdef SUPPORT_GRAPHICS
29 #include "js_window.h"
30 #endif
31 #include "napi_common_util.h"
32 #include "napi_context.h"
33 #include "napi_data_ability_helper.h"
34 #include "napi/native_api.h"
35 #include "napi/native_node_api.h"
36 #include "securec.h"
37
38 using namespace OHOS::AAFwk;
39 using namespace OHOS::AppExecFwk;
40
41 namespace OHOS {
42 namespace AppExecFwk {
43 using namespace OHOS::AbilityRuntime;
44 static int64_t dummyRequestCode_ = 0;
45 CallbackInfo g_aceCallbackInfo;
46
47 const int PARA_SIZE_IS_ONE = 1;
48 const int PARA_SIZE_IS_TWO = 2;
49
50 /**
51 * @brief FeatureAbility NAPI module registration.
52 *
53 * @param env The environment that the Node-API call is invoked under.
54 * @param exports An empty object via the exports parameter as a convenience.
55 *
56 * @return The return value from Init is treated as the exports object for the module.
57 */
FeatureAbilityInit(napi_env env,napi_value exports)58 napi_value FeatureAbilityInit(napi_env env, napi_value exports)
59 {
60 HILOG_INFO("%{public}s,called", __func__);
61 napi_property_descriptor properties[] = {
62 DECLARE_NAPI_FUNCTION("startAbility", NAPI_StartAbility),
63 DECLARE_NAPI_FUNCTION("startAbilityForResult", NAPI_StartAbilityForResult),
64 DECLARE_NAPI_FUNCTION("finishWithResult", NAPI_SetResult),
65 DECLARE_NAPI_FUNCTION("terminateSelfWithResult", NAPI_SetResult),
66 DECLARE_NAPI_FUNCTION("terminateSelf", NAPI_TerminateAbility),
67 DECLARE_NAPI_FUNCTION("getContext", NAPI_GetContext),
68 DECLARE_NAPI_FUNCTION("getAppType", NAPI_GetAppType),
69 DECLARE_NAPI_FUNCTION("getAbilityName", NAPI_GetAbilityName),
70 DECLARE_NAPI_FUNCTION("getAbilityInfo", NAPI_GetAbilityInfo),
71 DECLARE_NAPI_FUNCTION("getHapModuleInfo", NAPI_GetHapModuleInfo),
72 DECLARE_NAPI_FUNCTION("getDataAbilityHelper", NAPI_GetDataAbilityHelper),
73 DECLARE_NAPI_FUNCTION("acquireDataAbilityHelper", NAPI_AcquireDataAbilityHelper),
74 DECLARE_NAPI_FUNCTION("continueAbility", NAPI_FAContinueAbility),
75 DECLARE_NAPI_FUNCTION("getWantSync", NAPI_GetWantSync),
76 DECLARE_NAPI_FUNCTION("getWindow", NAPI_GetWindow),
77 };
78 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
79
80 return reinterpret_cast<napi_value>(JsFeatureAbilityInit(reinterpret_cast<NativeEngine*>(env),
81 reinterpret_cast<NativeValue*>(exports)));
82 }
83
84 class JsFeatureAbility : public JsNapiCommon {
85 public:
86 JsFeatureAbility() = default;
87 virtual ~JsFeatureAbility() override = default;
88
89 Ability* GetAbility(NativeEngine &engine);
90 static void Finalizer(NativeEngine *engine, void *data, void *hint);
91 static NativeValue* HasWindowFocus(NativeEngine *engine, NativeCallbackInfo *info);
92 static NativeValue* ConnectAbility(NativeEngine *engine, NativeCallbackInfo *info);
93 static NativeValue* DisconnectAbility(NativeEngine *engine, NativeCallbackInfo *info);
94 static NativeValue* GetWant(NativeEngine *engine, NativeCallbackInfo *info);
95 private:
96 #ifdef SUPPORT_GRAPHICS
97 NativeValue* OnHasWindowFocus(NativeEngine &engine, const NativeCallbackInfo &info);
98 #endif
99 };
100
Finalizer(NativeEngine * engine,void * data,void * hint)101 void JsFeatureAbility::Finalizer(NativeEngine *engine, void *data, void *hint)
102 {
103 HILOG_DEBUG("JsFeatureAbility::Finalizer is called");
104 auto pthis = std::unique_ptr<JsFeatureAbility>(static_cast<JsFeatureAbility*>(data));
105 if (pthis) {
106 pthis->RemoveAllCallbacksLocked();
107 }
108 }
109
JsFeatureAbilityInit(NativeEngine * engine,NativeValue * exports)110 NativeValue* JsFeatureAbilityInit(NativeEngine *engine, NativeValue *exports)
111 {
112 HILOG_DEBUG("JsFeatureAbilityInit is called");
113 if (engine == nullptr || exports == nullptr) {
114 HILOG_ERROR("Invalid input parameters");
115 return exports;
116 }
117
118 NativeObject *object = ConvertNativeValueTo<NativeObject>(exports);
119 if (object == nullptr) {
120 HILOG_ERROR("object is nullptr");
121 return exports;
122 }
123
124 std::unique_ptr<JsFeatureAbility> jsFeatureAbility = std::make_unique<JsFeatureAbility>();
125 jsFeatureAbility->ability_ = jsFeatureAbility->GetAbility(*engine);
126 object->SetNativePointer(jsFeatureAbility.release(), JsFeatureAbility::Finalizer, nullptr);
127
128 const char *moduleName = "JsFeatureAbility";
129 BindNativeFunction(*engine, *object, "getWant", moduleName, JsFeatureAbility::GetWant);
130 BindNativeFunction(*engine, *object, "hasWindowFocus", moduleName, JsFeatureAbility::HasWindowFocus);
131 BindNativeFunction(*engine, *object, "connectAbility", moduleName, JsFeatureAbility::ConnectAbility);
132 BindNativeFunction(*engine, *object, "disconnectAbility", moduleName, JsFeatureAbility::DisconnectAbility);
133
134 return exports;
135 }
136
GetWant(NativeEngine * engine,NativeCallbackInfo * info)137 NativeValue* JsFeatureAbility::GetWant(NativeEngine *engine, NativeCallbackInfo *info)
138 {
139 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
140 return (me != nullptr) ? me->JsGetWant(*engine, *info, AbilityType::PAGE) : nullptr;
141 }
142
HasWindowFocus(NativeEngine * engine,NativeCallbackInfo * info)143 NativeValue *JsFeatureAbility::HasWindowFocus(NativeEngine *engine, NativeCallbackInfo *info)
144 {
145 #ifdef SUPPORT_GRAPHICS
146 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
147 return (me != nullptr) ? me->OnHasWindowFocus(*engine, *info) : nullptr;
148 #else
149 return nullptr;
150 #endif
151 }
152
ConnectAbility(NativeEngine * engine,NativeCallbackInfo * info)153 NativeValue* JsFeatureAbility::ConnectAbility(NativeEngine *engine, NativeCallbackInfo *info)
154 {
155 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
156 return (me != nullptr) ? me->JsConnectAbility(*engine, *info, AbilityType::PAGE) : nullptr;
157 }
158
DisconnectAbility(NativeEngine * engine,NativeCallbackInfo * info)159 NativeValue* JsFeatureAbility::DisconnectAbility(NativeEngine *engine, NativeCallbackInfo *info)
160 {
161 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
162 return (me != nullptr) ? me->JsDisConnectAbility(*engine, *info, AbilityType::PAGE) : nullptr;
163 }
164
165 #ifdef SUPPORT_GRAPHICS
OnHasWindowFocus(NativeEngine & engine,const NativeCallbackInfo & info)166 NativeValue* JsFeatureAbility::OnHasWindowFocus(NativeEngine &engine, const NativeCallbackInfo &info)
167 {
168 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
169 if (info.argc > ARGS_ONE || info.argc < ARGS_ZERO) {
170 HILOG_ERROR(" wrong number of arguments.");
171 return engine.CreateUndefined();
172 }
173 AsyncTask::CompleteCallback complete =
174 [obj = this](NativeEngine &engine, AsyncTask &task, int32_t status) {
175 if (obj->ability_ == nullptr) {
176 HILOG_ERROR("HasWindowFocus execute error, the ability is nullptr");
177 task.Reject(engine, CreateJsError(engine, NAPI_ERR_ACE_ABILITY, "HasWindowFocus failed"));
178 return;
179 }
180 auto ret = obj->ability_->HasWindowFocus();
181 task.Resolve(engine, CreateJsValue(engine, ret));
182 };
183 NativeValue *result = nullptr;
184 NativeValue *lastParam = (info.argc == ARGS_ZERO) ? nullptr : info.argv[PARAM0];
185 AsyncTask::Schedule("JSFeatureAbility::OnHasWindowFocus",
186 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
187 HILOG_DEBUG("OnHasWindowFocus is called end");
188 return result;
189 }
190 #endif
191
GetAbility(NativeEngine & engine)192 Ability* JsFeatureAbility::GetAbility(NativeEngine &engine)
193 {
194 napi_status ret;
195 napi_value global = nullptr;
196 auto env = reinterpret_cast<napi_env>(&engine);
197 const napi_extended_error_info *errorInfo = nullptr;
198 ret = napi_get_global(env, &global);
199 if (ret != napi_ok) {
200 napi_get_last_error_info(env, &errorInfo);
201 HILOG_ERROR("get_global=%{public}d err:%{public}s", ret, errorInfo->error_message);
202 return nullptr;
203 }
204
205 napi_value abilityObj = nullptr;
206 ret = napi_get_named_property(env, global, "ability", &abilityObj);
207 if (ret != napi_ok) {
208 napi_get_last_error_info(env, &errorInfo);
209 HILOG_ERROR("get_named_property=%{public}d err:%{public}s", ret, errorInfo->error_message);
210 return nullptr;
211 }
212
213 Ability *ability = nullptr;
214 ret = napi_get_value_external(env, abilityObj, reinterpret_cast<void **>(&ability));
215 if (ret != napi_ok) {
216 napi_get_last_error_info(env, &errorInfo);
217 HILOG_ERROR("get_value_external=%{public}d err:%{public}s", ret, errorInfo->error_message);
218 return nullptr;
219 }
220
221 return ability;
222 }
223
224 /**
225 * @brief FeatureAbility NAPI method : startAbility.
226 *
227 * @param env The environment that the Node-API call is invoked under.
228 * @param info The callback info passed into the callback function.
229 *
230 * @return The return value from NAPI C++ to JS for the module.
231 */
NAPI_StartAbility(napi_env env,napi_callback_info info)232 napi_value NAPI_StartAbility(napi_env env, napi_callback_info info)
233 {
234 HILOG_INFO("%{public}s called.", __func__);
235 return NAPI_StartAbilityCommon(env, info, AbilityType::PAGE);
236 }
237
238 /**
239 * @brief FeatureAbility NAPI method : startAbilityForResult.
240 *
241 * @param env The environment that the Node-API call is invoked under.
242 * @param info The callback info passed into the callback function.
243 *
244 * @return The return value from NAPI C++ to JS for the module.
245 */
NAPI_StartAbilityForResult(napi_env env,napi_callback_info info)246 napi_value NAPI_StartAbilityForResult(napi_env env, napi_callback_info info)
247 {
248 HILOG_INFO("%{public}s,called.", __func__);
249 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
250 if (asyncCallbackInfo == nullptr) {
251 return WrapVoidToJS(env);
252 }
253
254 napi_value ret = StartAbilityForResultWrap(env, info, asyncCallbackInfo);
255 if (ret == nullptr) {
256 if (asyncCallbackInfo != nullptr) {
257 delete asyncCallbackInfo;
258 asyncCallbackInfo = nullptr;
259 }
260 ret = WrapVoidToJS(env);
261 }
262 HILOG_INFO("%{public}s,end.", __func__);
263 return ret;
264 }
265
266 /**
267 * @brief StartAbilityForResult processing function.
268 *
269 * @param env The environment that the Node-API call is invoked under.
270 * @param asyncCallbackInfo Process data asynchronously.
271 *
272 * @return Return JS data successfully, otherwise return nullptr.
273 */
StartAbilityForResultWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)274 napi_value StartAbilityForResultWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
275 {
276 HILOG_INFO("%{public}s,called", __func__);
277 size_t argcAsync = 2;
278 const size_t argcPromise = 1;
279 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
280 napi_value args[ARGS_MAX_COUNT] = {nullptr};
281 napi_value ret = nullptr;
282
283 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
284 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
285 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
286 return nullptr;
287 }
288
289 CallAbilityParam param;
290 if (UnwrapForResultParam(param, env, args[0]) == nullptr) {
291 HILOG_ERROR("%{public}s, call UnwrapForResultParam failed.", __func__);
292 asyncCallbackInfo->errCode = NAPI_ERR_PARAM_INVALID;
293 }
294 asyncCallbackInfo->param = param;
295 asyncCallbackInfo->aceCallback.env = env;
296 if (argcAsync > PARAM1) {
297 napi_valuetype valuetype = napi_undefined;
298 napi_typeof(env, args[PARAM1], &valuetype);
299 if (valuetype == napi_function) {
300 // resultCallback: AsyncCallback<StartAbilityResult>
301 napi_create_reference(env, args[PARAM1], 1, &(asyncCallbackInfo->aceCallback.callback));
302 }
303 }
304
305 if (argcAsync > argcPromise) {
306 ret = StartAbilityForResultAsync(env, asyncCallbackInfo);
307 } else {
308 ret = StartAbilityForResultPromise(env, asyncCallbackInfo);
309 }
310 HILOG_INFO("%{public}s,end.", __func__);
311 return ret;
312 }
313
StartAbilityForResultAsync(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)314 napi_value StartAbilityForResultAsync(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
315 {
316 HILOG_INFO("%{public}s, asyncCallback.", __func__);
317 if (asyncCallbackInfo == nullptr) {
318 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
319 return nullptr;
320 }
321 napi_value resourceName = nullptr;
322 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
323
324 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
325 [](napi_env env, void *data) {
326 HILOG_INFO("NAPI_StartAbilityForResult, worker pool thread execute.");
327 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
328 if (asyncCallbackInfo != nullptr) {
329 if (asyncCallbackInfo->errCode != NAPI_ERR_NO_ERROR) {
330 HILOG_ERROR("%{public}s errCode:%{public}d", __func__, asyncCallbackInfo->errCode);
331 AbilityProcess::GetInstance()->AddAbilityResultCallback(asyncCallbackInfo->ability,
332 asyncCallbackInfo->param, asyncCallbackInfo->errCode, asyncCallbackInfo->aceCallback);
333 return;
334 }
335 asyncCallbackInfo->errCode = AbilityProcess::GetInstance()->StartAbility(
336 asyncCallbackInfo->ability, asyncCallbackInfo->param, asyncCallbackInfo->aceCallback);
337 } else {
338 HILOG_ERROR("NAPI_StartAbilityForResult, asyncCallbackInfo == nullptr");
339 }
340 HILOG_INFO("NAPI_StartAbilityForResult, worker pool thread execute end.");
341 },
342 [](napi_env env, napi_status status, void *data) {
343 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
344 HILOG_INFO("NAPI_StartAbilityForResult, complete. err:%{public}d", asyncCallbackInfo->errCode);
345 if (asyncCallbackInfo->errCode != ERR_OK) {
346 Want resultData; // Callback the errcode when StartAbilityForResult failed.
347 AbilityProcess::GetInstance()->OnAbilityResult(asyncCallbackInfo->ability,
348 asyncCallbackInfo->param.requestCode, 0, resultData);
349 }
350 // remove asynccallback from startabilityforresult
351 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
352 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
353 }
354 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
355 delete asyncCallbackInfo;
356 HILOG_INFO("NAPI_StartAbilityForResult, main event thread complete end.");
357 },
358 static_cast<void *>(asyncCallbackInfo),
359 &asyncCallbackInfo->asyncWork));
360 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
361 napi_value result = nullptr;
362 NAPI_CALL(env, napi_get_null(env, &result));
363 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
364 return result;
365 }
366
StartAbilityForResultPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)367 napi_value StartAbilityForResultPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
368 {
369 HILOG_INFO("%{public}s, promise.", __func__);
370 if (asyncCallbackInfo == nullptr) {
371 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
372 return nullptr;
373 }
374 napi_value resourceName = nullptr;
375 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
376 napi_deferred deferred;
377 napi_value promise = nullptr;
378 napi_create_promise(env, &deferred, &promise);
379 asyncCallbackInfo->aceCallback.callback = nullptr;
380 asyncCallbackInfo->aceCallback.deferred = deferred;
381
382 napi_create_async_work(env, nullptr, resourceName,
383 [](napi_env env, void *data) {
384 HILOG_INFO("NAPI_StartAbilityForResult, worker pool thread execute.");
385 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
386 if (asyncCallbackInfo != nullptr) {
387 if (asyncCallbackInfo->errCode != NAPI_ERR_NO_ERROR) {
388 HILOG_ERROR("%{public}s errCode:%{public}d", __func__, asyncCallbackInfo->errCode);
389 AbilityProcess::GetInstance()->AddAbilityResultCallback(asyncCallbackInfo->ability,
390 asyncCallbackInfo->param, asyncCallbackInfo->errCode, asyncCallbackInfo->aceCallback);
391 return;
392 }
393 asyncCallbackInfo->errCode = AbilityProcess::GetInstance()->StartAbility(
394 asyncCallbackInfo->ability, asyncCallbackInfo->param, asyncCallbackInfo->aceCallback);
395 } else {
396 HILOG_ERROR("NAPI_StartAbilityForResult, asyncCallbackInfo == nullptr");
397 }
398 HILOG_INFO("NAPI_StartAbilityForResult, worker pool thread execute end.");
399 },
400 [](napi_env env, napi_status status, void *data) {
401 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
402 HILOG_INFO("NAPI_StartAbilityForResult, complete. err:%{public}d", asyncCallbackInfo->errCode);
403 if (asyncCallbackInfo->errCode != ERR_OK) {
404 Want resultData; // Callback the errcode when StartAbilityForResult failed.
405 AbilityProcess::GetInstance()->OnAbilityResult(asyncCallbackInfo->ability,
406 asyncCallbackInfo->param.requestCode, 0, resultData);
407 }
408 // resolve it when call onAbilityResult
409 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
410 delete asyncCallbackInfo;
411 HILOG_INFO("NAPI_StartAbilityForResult, main event thread complete end.");
412 },
413 static_cast<void *>(asyncCallbackInfo),
414 &asyncCallbackInfo->asyncWork);
415 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
416 HILOG_INFO("%{public}s, promise end.", __func__);
417 return promise;
418 }
419
420 /**
421 * @brief FeatureAbility NAPI method : setResult.
422 *
423 * @param env The environment that the Node-API call is invoked under.
424 * @param info The callback info passed into the callback function.
425 *
426 * @return The return value from NAPI C++ to JS for the module.
427 */
NAPI_SetResult(napi_env env,napi_callback_info info)428 napi_value NAPI_SetResult(napi_env env, napi_callback_info info)
429 {
430 HILOG_INFO("%{public}s,called", __func__);
431 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
432 if (asyncCallbackInfo == nullptr) {
433 HILOG_ERROR("%{public}s,asyncCallbackInfo == nullptr", __func__);
434 return WrapVoidToJS(env);
435 }
436
437 napi_value ret = SetResultWrap(env, info, asyncCallbackInfo);
438 if (ret == nullptr) {
439 HILOG_ERROR("%{public}s,ret == nullptr", __func__);
440 if (asyncCallbackInfo != nullptr) {
441 delete asyncCallbackInfo;
442 asyncCallbackInfo = nullptr;
443 }
444 ret = WrapVoidToJS(env);
445 }
446 HILOG_INFO("%{public}s,end", __func__);
447 return ret;
448 }
449
450 /**
451 * @brief SetResult processing function.
452 *
453 * @param env The environment that the Node-API call is invoked under.
454 * @param asyncCallbackInfo Process data asynchronously.
455 *
456 * @return Return JS data successfully, otherwise return nullptr.
457 */
SetResultWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)458 napi_value SetResultWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
459 {
460 HILOG_INFO("%{public}s,called", __func__);
461 size_t argcAsync = 2;
462 const size_t argcPromise = 1;
463 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
464 napi_value args[ARGS_MAX_COUNT] = {nullptr};
465 napi_value ret = nullptr;
466
467 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
468 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
469 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
470 return nullptr;
471 }
472
473 CallAbilityParam param;
474 if (UnwrapAbilityResult(param, env, args[0]) == nullptr) {
475 HILOG_ERROR("%{public}s, call unwrapWant failed.", __func__);
476 return nullptr;
477 }
478 asyncCallbackInfo->param = param;
479
480 if (argcAsync > argcPromise) {
481 ret = SetResultAsync(env, args, 1, asyncCallbackInfo);
482 } else {
483 ret = SetResultPromise(env, asyncCallbackInfo);
484 }
485 HILOG_INFO("%{public}s,end", __func__);
486 return ret;
487 }
488
SetResultAsync(napi_env env,napi_value * args,const size_t argCallback,AsyncCallbackInfo * asyncCallbackInfo)489 napi_value SetResultAsync(
490 napi_env env, napi_value *args, const size_t argCallback, AsyncCallbackInfo *asyncCallbackInfo)
491 {
492 HILOG_INFO("%{public}s, asyncCallback.", __func__);
493 if (args == nullptr || asyncCallbackInfo == nullptr) {
494 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
495 return nullptr;
496 }
497 napi_value resourceName = nullptr;
498 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
499
500 napi_valuetype valuetype = napi_undefined;
501 NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
502 if (valuetype == napi_function) {
503 napi_create_reference(env, args[argCallback], 1, &asyncCallbackInfo->cbInfo.callback);
504 }
505
506 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
507 [](napi_env env, void *data) {
508 HILOG_INFO("NAPI_SetResult, worker pool thread execute.");
509 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
510 if (asyncCallbackInfo->ability != nullptr) {
511 asyncCallbackInfo->ability->SetResult(
512 asyncCallbackInfo->param.requestCode, asyncCallbackInfo->param.want);
513 asyncCallbackInfo->ability->TerminateAbility();
514 } else {
515 HILOG_ERROR("NAPI_SetResult, ability == nullptr");
516 }
517 HILOG_INFO("NAPI_SetResult, worker pool thread execute end.");
518 },
519 [](napi_env env, napi_status status, void *data) {
520 HILOG_INFO("NAPI_SetResult, main event thread complete.");
521 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
522 napi_value result[ARGS_TWO] = {nullptr};
523 napi_value callback = nullptr;
524 napi_value undefined = nullptr;
525 napi_value callResult = nullptr;
526 napi_get_undefined(env, &undefined);
527 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
528 napi_get_null(env, &result[PARAM1]);
529 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
530 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
531
532 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
533 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
534 }
535 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
536 delete asyncCallbackInfo;
537 HILOG_INFO("NAPI_SetResult, main event thread complete end.");
538 },
539 static_cast<void *>(asyncCallbackInfo),
540 &asyncCallbackInfo->asyncWork));
541 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
542 napi_value result = nullptr;
543 NAPI_CALL(env, napi_get_null(env, &result));
544 HILOG_INFO("%{public}s, asyncCallback end", __func__);
545 return result;
546 }
547
SetResultPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)548 napi_value SetResultPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
549 {
550 HILOG_INFO("%{public}s, promise.", __func__);
551 if (asyncCallbackInfo == nullptr) {
552 HILOG_ERROR("SetResultPromise, param == nullptr.");
553 return nullptr;
554 }
555 napi_value resourceName = nullptr;
556 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
557 napi_deferred deferred;
558 napi_value promise = nullptr;
559 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
560 asyncCallbackInfo->deferred = deferred;
561
562 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
563 [](napi_env env, void *data) {
564 HILOG_INFO("NAPI_SetResult, worker pool thread execute.");
565 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
566 if (asyncCallbackInfo->ability != nullptr) {
567 asyncCallbackInfo->ability->SetResult(
568 asyncCallbackInfo->param.requestCode, asyncCallbackInfo->param.want);
569 asyncCallbackInfo->ability->TerminateAbility();
570 } else {
571 HILOG_ERROR("NAPI_SetResult, ability == nullptr");
572 }
573 HILOG_INFO("NAPI_SetResult, worker pool thread execute end.");
574 },
575 [](napi_env env, napi_status status, void *data) {
576 HILOG_INFO("NAPI_SetResult, main event thread complete.");
577 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
578 napi_value result = nullptr;
579 napi_get_null(env, &result);
580 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
581 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
582 delete asyncCallbackInfo;
583 HILOG_INFO("NAPI_SetResult, main event thread complete end.");
584 },
585 static_cast<void *>(asyncCallbackInfo),
586 &asyncCallbackInfo->asyncWork));
587 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
588 HILOG_INFO("%{public}s, promise end", __func__);
589 return promise;
590 }
591
592 /**
593 * @brief FeatureAbility NAPI method : terminateAbility.
594 *
595 * @param env The environment that the Node-API call is invoked under.
596 * @param info The callback info passed into the callback function.
597 *
598 * @return The return value from NAPI C++ to JS for the module.
599 */
NAPI_TerminateAbility(napi_env env,napi_callback_info info)600 napi_value NAPI_TerminateAbility(napi_env env, napi_callback_info info)
601 {
602 HILOG_INFO("%{public}s,called", __func__);
603 return NAPI_TerminateAbilityCommon(env, info);
604 }
605
606 /**
607 * @brief Checks whether the main window of this ability has window focus.
608 *
609 * @param env The environment that the Node-API call is invoked under.
610 * @param info The callback info passed into the callback function.
611 *
612 * @return The return value from NAPI C++ to JS for the module.
613 */
NAPI_HasWindowFocus(napi_env env,napi_callback_info info)614 napi_value NAPI_HasWindowFocus(napi_env env, napi_callback_info info)
615 {
616 #ifdef SUPPORT_GRAPHICS
617 HILOG_INFO("%{public}s,called", __func__);
618 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
619 if (asyncCallbackInfo == nullptr) {
620 HILOG_ERROR("%{public}s,asyncCallbackInfo == nullptr", __func__);
621 return WrapVoidToJS(env);
622 }
623
624 napi_value ret = HasWindowFocusWrap(env, info, asyncCallbackInfo);
625 if (ret == nullptr) {
626 HILOG_ERROR("%{public}s,ret == nullptr", __func__);
627 if (asyncCallbackInfo != nullptr) {
628 delete asyncCallbackInfo;
629 asyncCallbackInfo = nullptr;
630 }
631 ret = WrapVoidToJS(env);
632 }
633 HILOG_INFO("%{public}s,end", __func__);
634 return ret;
635 #else
636 return nullptr;
637 #endif
638 }
639
640 /**
641 * @brief Get context.
642 *
643 * @param env The environment that the Node-API call is invoked under.
644 * @param info The callback info passed into the callback function.
645 *
646 * @return The return value from NAPI C++ to JS for the module.
647 */
NAPI_GetContext(napi_env env,napi_callback_info info)648 napi_value NAPI_GetContext(napi_env env, napi_callback_info info)
649 {
650 HILOG_INFO("%{public}s called.", __func__);
651 return NAPI_GetContextCommon(env, info, AbilityType::PAGE);
652 }
653
654 /**
655 * @brief HasWindowFocus processing function.
656 *
657 * @param env The environment that the Node-API call is invoked under.
658 * @param asyncCallbackInfo Process data asynchronously.
659 *
660 * @return Return JS data successfully, otherwise return nullptr.
661 */
HasWindowFocusWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)662 napi_value HasWindowFocusWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
663 {
664 #ifdef SUPPORT_GRAPHICS
665 HILOG_INFO("%{public}s, asyncCallback.", __func__);
666 if (asyncCallbackInfo == nullptr) {
667 HILOG_ERROR("%{public}s, asyncCallbackInfo == nullptr.", __func__);
668 return nullptr;
669 }
670
671 size_t argcAsync = 1;
672 const size_t argcPromise = 0;
673 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
674 napi_value args[ARGS_MAX_COUNT] = {nullptr};
675 napi_value ret = nullptr;
676
677 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
678 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
679 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
680 return nullptr;
681 }
682
683 if (argcAsync > argcPromise) {
684 ret = HasWindowFocusAsync(env, args, 0, asyncCallbackInfo);
685 } else {
686 ret = HasWindowFocusPromise(env, asyncCallbackInfo);
687 }
688 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
689 return ret;
690 #else
691 return nullptr;
692 #endif
693 }
694
695 #ifdef SUPPORT_GRAPHICS
HasWindowFocusAsync(napi_env env,napi_value * args,const size_t argCallback,AsyncCallbackInfo * asyncCallbackInfo)696 napi_value HasWindowFocusAsync(
697 napi_env env, napi_value *args, const size_t argCallback, AsyncCallbackInfo *asyncCallbackInfo)
698 {
699 HILOG_INFO("%{public}s, asyncCallback.", __func__);
700 if (args == nullptr || asyncCallbackInfo == nullptr) {
701 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
702 return nullptr;
703 }
704 napi_value resourceName = nullptr;
705 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
706
707 napi_valuetype valuetype = napi_undefined;
708 NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
709 if (valuetype == napi_function) {
710 NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &asyncCallbackInfo->cbInfo.callback));
711 }
712 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
713 [](napi_env env, void *data) {
714 HILOG_INFO("NAPI_HasWindowFocus, worker pool thread execute.");
715 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
716 if (asyncCallbackInfo->ability != nullptr) {
717 asyncCallbackInfo->native_result = asyncCallbackInfo->ability->HasWindowFocus();
718 } else {
719 HILOG_ERROR("NAPI_HasWindowFocus, ability == nullptr");
720 }
721 HILOG_INFO("NAPI_HasWindowFocus, worker pool thread execute end.");
722 },
723 [](napi_env env, napi_status status, void *data) {
724 HILOG_INFO("NAPI_HasWindowFocus, main event thread complete.");
725 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
726 napi_value callback = nullptr;
727 napi_value undefined = nullptr;
728 napi_value result[ARGS_TWO] = {nullptr};
729 napi_value callResult = nullptr;
730 napi_get_undefined(env, &undefined);
731 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
732 napi_get_boolean(env, asyncCallbackInfo->native_result, &result[PARAM1]);
733 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
734 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
735
736 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
737 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
738 }
739 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
740 delete asyncCallbackInfo;
741 asyncCallbackInfo = nullptr;
742 HILOG_INFO("NAPI_HasWindowFocus, main event thread complete end.");
743 },
744 static_cast<void *>(asyncCallbackInfo),
745 &asyncCallbackInfo->asyncWork));
746 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
747 napi_value result = nullptr;
748 NAPI_CALL(env, napi_get_null(env, &result));
749 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
750 return result;
751 }
752
HasWindowFocusPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)753 napi_value HasWindowFocusPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
754 {
755 HILOG_INFO("%{public}s, promise.", __func__);
756 if (asyncCallbackInfo == nullptr) {
757 HILOG_ERROR("HasWindowFocusPromise, param == nullptr.");
758 return nullptr;
759 }
760 napi_value resourceName = nullptr;
761 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
762 napi_deferred deferred;
763 napi_value promise = nullptr;
764 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
765 asyncCallbackInfo->deferred = deferred;
766
767 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
768 [](napi_env env, void *data) {
769 HILOG_INFO("NAPI_HasWindowFocus, worker pool thread execute.");
770 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
771 if (asyncCallbackInfo->ability != nullptr) {
772 asyncCallbackInfo->native_result = asyncCallbackInfo->ability->HasWindowFocus();
773 } else {
774 HILOG_INFO("NAPI_HasWindowFocus, ability == nullptr");
775 }
776 HILOG_INFO("NAPI_HasWindowFocus, worker pool thread execute end.");
777 },
778 [](napi_env env, napi_status status, void *data) {
779 HILOG_INFO("NAPI_HasWindowFocus, main event thread complete.");
780 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
781 napi_value result = nullptr;
782 napi_get_boolean(env, asyncCallbackInfo->native_result, &result);
783 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
784 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
785 delete asyncCallbackInfo;
786 asyncCallbackInfo = nullptr;
787 HILOG_INFO("NAPI_HasWindowFocus, main event thread complete end.");
788 },
789 static_cast<void *>(asyncCallbackInfo),
790 &asyncCallbackInfo->asyncWork));
791 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
792 HILOG_INFO("%{public}s, promise end.", __func__);
793 return promise;
794 }
795 #else
HasWindowFocusAsync(napi_env env,napi_value * args,const size_t argCallback,AsyncCallbackInfo * asyncCallbackInfo)796 napi_value HasWindowFocusAsync(
797 napi_env env, napi_value *args, const size_t argCallback, AsyncCallbackInfo *asyncCallbackInfo)
798 {
799 return nullptr;
800 }
801
HasWindowFocusPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)802 napi_value HasWindowFocusPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
803 {
804 return nullptr;
805 }
806 #endif
807
808 EXTERN_C_START
809 /**
810 * @brief The interface of onAbilityResult provided for ACE to call back to JS.
811 *
812 * @param requestCode Indicates the request code returned after the ability is started.
813 * @param resultCode Indicates the result code returned after the ability is started.
814 * @param resultData Indicates the data returned after the ability is started.
815 * @param cb The environment and call back info that the Node-API call is invoked under.
816 *
817 * @return The return value from NAPI C++ to JS for the module.
818 */
CallOnAbilityResult(int requestCode,int resultCode,const Want & resultData,CallbackInfo callbackInfo)819 void CallOnAbilityResult(int requestCode, int resultCode, const Want &resultData, CallbackInfo callbackInfo)
820 {
821 HILOG_INFO("%{public}s,called", __func__);
822 uv_loop_s *loop = nullptr;
823
824 napi_get_uv_event_loop(callbackInfo.env, &loop);
825 if (loop == nullptr) {
826 return;
827 }
828
829 auto work = new uv_work_t;
830 auto onAbilityCB = new OnAbilityCallback;
831 onAbilityCB->requestCode = requestCode;
832 onAbilityCB->resultCode = resultCode;
833 onAbilityCB->resultData = resultData;
834 onAbilityCB->cb = callbackInfo;
835
836 work->data = static_cast<void *>(onAbilityCB);
837
838 int rev = uv_queue_work(
839 loop,
840 work,
841 [](uv_work_t *work) {},
842 [](uv_work_t *work, int status) {
843 HILOG_INFO("CallOnAbilityResult, uv_queue_work");
844 // JS Thread
845 if (work == nullptr) {
846 HILOG_ERROR("%{public}s, uv_queue_work work == nullptr.", __func__);
847 return;
848 }
849 auto onAbilityCB = static_cast<OnAbilityCallback *>(work->data);
850 if (onAbilityCB == nullptr) {
851 HILOG_ERROR("%{public}s, uv_queue_work onAbilityCB == nullptr.", __func__);
852 delete work;
853 work = nullptr;
854 return;
855 }
856 napi_value result[ARGS_TWO] = {0};
857 int32_t errCode = GetStartAbilityErrorCode(onAbilityCB->cb.errCode);
858 result[PARAM0] = GetCallbackErrorValue(onAbilityCB->cb.env, errCode);
859
860 napi_create_object(onAbilityCB->cb.env, &result[PARAM1]);
861 // create resultCode
862 napi_value jsValue = 0;
863 napi_create_int32(onAbilityCB->cb.env, onAbilityCB->resultCode, &jsValue);
864 napi_set_named_property(onAbilityCB->cb.env, result[PARAM1], "resultCode", jsValue);
865 // create want
866 napi_value jsWant = WrapWant(onAbilityCB->cb.env, onAbilityCB->resultData);
867 napi_set_named_property(onAbilityCB->cb.env, result[PARAM1], "want", jsWant);
868
869 if (onAbilityCB->cb.callback != nullptr) {
870 // asynccallback
871 HILOG_INFO("CallOnAbilityResult, asynccallback");
872 napi_value callback = 0;
873 napi_value undefined = 0;
874 napi_get_undefined(onAbilityCB->cb.env, &undefined);
875 napi_value callResult = 0;
876 napi_get_reference_value(onAbilityCB->cb.env, onAbilityCB->cb.callback, &callback);
877
878 napi_call_function(onAbilityCB->cb.env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
879 if (onAbilityCB->cb.callback != nullptr) {
880 napi_delete_reference(onAbilityCB->cb.env, onAbilityCB->cb.callback);
881 }
882 HILOG_INFO("CallOnAbilityResult, asynccallback end");
883 } else {
884 // promise
885 HILOG_INFO("CallOnAbilityResult, promise");
886 if (onAbilityCB->cb.errCode != ERR_OK) {
887 napi_reject_deferred(onAbilityCB->cb.env, onAbilityCB->cb.deferred, result[PARAM0]);
888 } else {
889 napi_resolve_deferred(onAbilityCB->cb.env, onAbilityCB->cb.deferred, result[PARAM1]);
890 }
891 HILOG_INFO("CallOnAbilityResult, promise end");
892 }
893
894 delete onAbilityCB;
895 onAbilityCB = nullptr;
896 delete work;
897 work = nullptr;
898 HILOG_INFO("CallOnAbilityResult, uv_queue_work end");
899 });
900 if (rev != 0) {
901 if (onAbilityCB != nullptr) {
902 delete onAbilityCB;
903 onAbilityCB = nullptr;
904 }
905 if (work != nullptr) {
906 delete work;
907 work = nullptr;
908 }
909 }
910 HILOG_INFO("%{public}s,end", __func__);
911 }
912 EXTERN_C_END
913
InnerUnwrapWant(napi_env env,napi_value args,Want & want)914 bool InnerUnwrapWant(napi_env env, napi_value args, Want &want)
915 {
916 HILOG_INFO("%{public}s called", __func__);
917 napi_valuetype valueType = napi_undefined;
918 NAPI_CALL_BASE(env, napi_typeof(env, args, &valueType), false);
919 if (valueType != napi_object) {
920 HILOG_ERROR("%{public}s wrong argument type", __func__);
921 return false;
922 }
923
924 napi_value jsWant = GetPropertyValueByPropertyName(env, args, "want", napi_object);
925 if (jsWant == nullptr) {
926 HILOG_ERROR("%{public}s jsWant == nullptr", __func__);
927 return false;
928 }
929
930 return UnwrapWant(env, jsWant, want);
931 }
932
933 /**
934 * @brief Parse the parameters.
935 *
936 * @param param Indicates the parameters saved the parse result.
937 * @param env The environment that the Node-API call is invoked under.
938 * @param args Indicates the arguments passed into the callback.
939 *
940 * @return The return value from NAPI C++ to JS for the module.
941 */
UnwrapForResultParam(CallAbilityParam & param,napi_env env,napi_value args)942 napi_value UnwrapForResultParam(CallAbilityParam ¶m, napi_env env, napi_value args)
943 {
944 HILOG_INFO("%{public}s,called", __func__);
945 // dummy requestCode for NativeC++ interface and onabilityresult callback
946 param.requestCode = dummyRequestCode_;
947 param.forResultOption = true;
948 dummyRequestCode_ = (dummyRequestCode_ < INT32_MAX) ? (dummyRequestCode_ + 1) : 0;
949 HILOG_INFO("%{public}s, reqCode=%{public}d forResultOption=%{public}d.",
950 __func__,
951 param.requestCode,
952 param.forResultOption);
953
954 // unwrap the param : want object
955 if (!InnerUnwrapWant(env, args, param.want)) {
956 HILOG_ERROR("Failed to InnerUnwrapWant");
957 return nullptr;
958 }
959
960 // unwrap the param : abilityStartSetting (optional)
961 napi_value jsSettingObj = GetPropertyValueByPropertyName(env, args, "abilityStartSetting", napi_object);
962 if (jsSettingObj != nullptr) {
963 param.setting = AbilityStartSetting::GetEmptySetting();
964 if (!UnwrapAbilityStartSetting(env, jsSettingObj, *(param.setting))) {
965 HILOG_ERROR("%{public}s, unwrap abilityStartSetting failed.", __func__);
966 }
967 HILOG_INFO("%{public}s abilityStartSetting", __func__);
968 }
969
970 napi_value result;
971 NAPI_CALL(env, napi_create_int32(env, 1, &result));
972 HILOG_INFO("%{public}s,end", __func__);
973 return result;
974 }
975
976 /**
977 * @brief Parse the abilityResult parameters.
978 *
979 * @param param Indicates the want parameters saved the parse result.
980 * @param env The environment that the Node-API call is invoked under.
981 * @param args Indicates the arguments passed into the callback.
982 *
983 * @return The return value from NAPI C++ to JS for the module.
984 */
UnwrapAbilityResult(CallAbilityParam & param,napi_env env,napi_value args)985 napi_value UnwrapAbilityResult(CallAbilityParam ¶m, napi_env env, napi_value args)
986 {
987 HILOG_INFO("%{public}s,called", __func__);
988 // unwrap the param
989 napi_valuetype valueType = napi_undefined;
990 NAPI_CALL(env, napi_typeof(env, args, &valueType));
991 NAPI_ASSERT(env, valueType == napi_object, "param type mismatch!");
992 // get resultCode property
993 napi_value property = nullptr;
994 NAPI_CALL(env, napi_get_named_property(env, args, "resultCode", &property));
995 NAPI_CALL(env, napi_typeof(env, property, &valueType));
996 NAPI_ASSERT(env, valueType == napi_number, "property type mismatch!");
997 NAPI_CALL(env, napi_get_value_int32(env, property, ¶m.requestCode));
998 HILOG_INFO("%{public}s, requestCode=%{public}d.", __func__, param.requestCode);
999
1000 // unwrap the param : want object
1001 InnerUnwrapWant(env, args, param.want);
1002
1003 napi_value result;
1004 NAPI_CALL(env, napi_create_int32(env, 1, &result));
1005 HILOG_INFO("%{public}s,end", __func__);
1006 return result;
1007 }
1008
1009 #ifdef SUPPORT_GRAPHICS
GetWindowWrapAsync(napi_env env,napi_value * args,const size_t argCallback,AsyncCallbackInfo * asyncCallbackInfo)1010 napi_value GetWindowWrapAsync(
1011 napi_env env, napi_value *args, const size_t argCallback, AsyncCallbackInfo *asyncCallbackInfo)
1012 {
1013 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1014 if (args == nullptr || asyncCallbackInfo == nullptr) {
1015 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1016 return nullptr;
1017 }
1018 napi_value resourceName = nullptr;
1019 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1020
1021 napi_valuetype valuetype = napi_undefined;
1022 NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1023 if (valuetype == napi_function) {
1024 NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &asyncCallbackInfo->cbInfo.callback));
1025 }
1026 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
1027 [](napi_env env, void *data) {},
1028 [](napi_env env, napi_status status, void *data) {
1029 HILOG_INFO("GetWindowWrapAsync, main event thread complete.");
1030 AsyncCallbackInfo* asyncCallbackInfo = static_cast<AsyncCallbackInfo*>(data);
1031 if (asyncCallbackInfo == nullptr) {
1032 HILOG_ERROR("GetWindowWrapAsync, asyncCallbackInfo is nullptr");
1033 return;
1034 }
1035 if (asyncCallbackInfo->ability != nullptr) {
1036 HILOG_DEBUG("GetWindowWrapAsync, ability is valid.");
1037 auto engine = reinterpret_cast<NativeEngine*>(env);
1038 asyncCallbackInfo->window = asyncCallbackInfo->ability->GetWindow();
1039 auto jsWindow = OHOS::Rosen::CreateJsWindowObject(*engine, asyncCallbackInfo->window);
1040 napi_value result[ARGS_TWO] = {nullptr};
1041 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
1042 result[PARAM1] = reinterpret_cast<napi_value>(jsWindow);
1043 napi_value callback = nullptr;
1044 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
1045 napi_value callResult = nullptr;
1046 napi_value undefined = nullptr;
1047 napi_get_undefined(env, &undefined);
1048 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
1049 }
1050
1051 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
1052 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
1053 }
1054 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1055 delete asyncCallbackInfo;
1056 asyncCallbackInfo = nullptr;
1057 HILOG_INFO("GetWindowWrapAsync, main event thread complete end.");
1058 },
1059 static_cast<void *>(asyncCallbackInfo),
1060 &asyncCallbackInfo->asyncWork));
1061 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1062 napi_value result = nullptr;
1063 NAPI_CALL(env, napi_get_null(env, &result));
1064 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1065 return result;
1066 }
1067
GetWindowWrapPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1068 napi_value GetWindowWrapPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
1069 {
1070 HILOG_INFO("%{public}s, promise.", __func__);
1071 if (asyncCallbackInfo == nullptr) {
1072 HILOG_ERROR("GetWindowWrapPromise, param == nullptr.");
1073 return nullptr;
1074 }
1075 napi_value resourceName = nullptr;
1076 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1077 napi_deferred deferred;
1078 napi_value promise = nullptr;
1079 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1080 asyncCallbackInfo->deferred = deferred;
1081
1082 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
1083 [](napi_env env, void *data) {},
1084 [](napi_env env, napi_status status, void *data) {
1085 HILOG_INFO("GetWindowWrapPromise, main event thread complete.");
1086 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
1087 if (asyncCallbackInfo == nullptr) {
1088 HILOG_ERROR("GetWindowWrapPromise, asyncCallbackInfo is nullptr");
1089 return;
1090 }
1091 napi_value result = nullptr;
1092 if (asyncCallbackInfo->ability != nullptr) {
1093 auto engine = reinterpret_cast<NativeEngine*>(env);
1094 asyncCallbackInfo->window = asyncCallbackInfo->ability->GetWindow();
1095 auto jsWindow = OHOS::Rosen::CreateJsWindowObject(*engine, asyncCallbackInfo->window);
1096 result = reinterpret_cast<napi_value>(jsWindow);
1097 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
1098 } else {
1099 HILOG_WARN("GetWindowWrapPromise, ability is nullptr.");
1100 napi_get_null(env, &result);
1101 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
1102 }
1103 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1104 delete asyncCallbackInfo;
1105 asyncCallbackInfo = nullptr;
1106 HILOG_INFO("GetWindowWrapPromise, main event thread complete end.");
1107 },
1108 static_cast<void *>(asyncCallbackInfo),
1109 &asyncCallbackInfo->asyncWork));
1110 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1111 HILOG_INFO("%{public}s, promise end.", __func__);
1112 return promise;
1113 }
1114
1115 /**
1116 * @brief GetWindowWrap processing function.
1117 *
1118 * @param env The environment that the Node-API call is invoked under.
1119 * @param asyncCallbackInfo Process data asynchronously.
1120 *
1121 * @return Return JS data successfully, otherwise return nullptr.
1122 */
GetWindowWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)1123 napi_value GetWindowWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
1124 {
1125 HILOG_INFO("%{public}s, called.", __func__);
1126 if (asyncCallbackInfo == nullptr) {
1127 HILOG_ERROR("%{public}s, asyncCallbackInfo == nullptr.", __func__);
1128 return nullptr;
1129 }
1130
1131 size_t argcAsync = 1;
1132 const size_t argcPromise = 0;
1133 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1134 napi_value args[ARGS_MAX_COUNT] = {nullptr};
1135 napi_value ret = nullptr;
1136
1137 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
1138 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1139 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1140 return nullptr;
1141 }
1142
1143 if (argcAsync > argcPromise) {
1144 ret = GetWindowWrapAsync(env, args, 0, asyncCallbackInfo);
1145 } else {
1146 ret = GetWindowWrapPromise(env, asyncCallbackInfo);
1147 }
1148 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1149 return ret;
1150 }
1151
1152 /**
1153 * @brief Get window.
1154 *
1155 * @param env The environment that the Node-API call is invoked under.
1156 * @param info The callback info passed into the callback function.
1157 *
1158 * @return The return value from NAPI C++ to JS for the module.
1159 */
NAPI_GetWindow(napi_env env,napi_callback_info info)1160 napi_value NAPI_GetWindow(napi_env env, napi_callback_info info)
1161 {
1162 HILOG_INFO("%{public}s called.", __func__);
1163 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
1164 if (asyncCallbackInfo == nullptr) {
1165 return WrapVoidToJS(env);
1166 }
1167
1168 napi_value ret = GetWindowWrap(env, info, asyncCallbackInfo);
1169 if (ret == nullptr) {
1170 HILOG_ERROR("%{public}s,ret == nullptr", __func__);
1171 if (asyncCallbackInfo != nullptr) {
1172 delete asyncCallbackInfo;
1173 asyncCallbackInfo = nullptr;
1174 }
1175 ret = WrapVoidToJS(env);
1176 } else {
1177 HILOG_INFO("%{public}s, end.", __func__);
1178 }
1179 return ret;
1180 }
1181 #else
GetWindowWrapAsync(napi_env env,napi_value * args,const size_t argCallback,AsyncCallbackInfo * asyncCallbackInfo)1182 napi_value GetWindowWrapAsync(
1183 napi_env env, napi_value *args, const size_t argCallback, AsyncCallbackInfo *asyncCallbackInfo)
1184 {
1185 return nullptr;
1186 }
1187
GetWindowWrapPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1188 napi_value GetWindowWrapPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
1189 {
1190 return nullptr;
1191 }
1192
1193 /**
1194 * @brief GetWindowWrap processing function.
1195 *
1196 * @param env The environment that the Node-API call is invoked under.
1197 * @param asyncCallbackInfo Process data asynchronously.
1198 *
1199 * @return Return JS data successfully, otherwise return nullptr.
1200 */
GetWindowWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)1201 napi_value GetWindowWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
1202 {
1203 return nullptr;
1204 }
1205
1206 /**
1207 * @brief Get window.
1208 *
1209 * @param env The environment that the Node-API call is invoked under.
1210 * @param info The callback info passed into the callback function.
1211 *
1212 * @return The return value from NAPI C++ to JS for the module.
1213 */
NAPI_GetWindow(napi_env env,napi_callback_info info)1214 napi_value NAPI_GetWindow(napi_env env, napi_callback_info info)
1215 {
1216 return nullptr;
1217 }
1218 #endif
1219
1220 /**
1221 * @brief GetWantSyncWrap processing function.
1222 *
1223 * @param env The environment that the Node-API call is invoked under.
1224 * @param CallingBundleCB Process data asynchronously.
1225 *
1226 * @return Return JS data successfully, otherwise return nullptr.
1227 */
GetWantSyncWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)1228 napi_value GetWantSyncWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
1229 {
1230 HILOG_INFO("%{public}s, called.", __func__);
1231 if (asyncCallbackInfo == nullptr) {
1232 HILOG_ERROR("%{public}s, asyncCallbackInfo == nullptr.", __func__);
1233 return nullptr;
1234 }
1235
1236 asyncCallbackInfo->errCode = NAPI_ERR_NO_ERROR;
1237 if (asyncCallbackInfo->ability == nullptr) {
1238 HILOG_ERROR("%{public}s, ability == nullptr", __func__);
1239 asyncCallbackInfo->errCode = NAPI_ERR_ACE_ABILITY;
1240 return nullptr;
1241 }
1242
1243 std::shared_ptr<AAFwk::Want> ptrWant = asyncCallbackInfo->ability->GetWant();
1244 if (ptrWant != nullptr) {
1245 asyncCallbackInfo->param.want = *ptrWant;
1246 } else {
1247 asyncCallbackInfo->errCode = NAPI_ERR_ABILITY_CALL_INVALID;
1248 }
1249
1250 napi_value result = nullptr;
1251 if (asyncCallbackInfo->errCode == NAPI_ERR_NO_ERROR) {
1252 result = WrapWant(env, asyncCallbackInfo->param.want);
1253 } else {
1254 result = WrapVoidToJS(env);
1255 }
1256 HILOG_INFO("%{public}s, end.", __func__);
1257 return result;
1258 }
1259
1260 /**
1261 * @brief Get want(Sync).
1262 *
1263 * @param env The environment that the Node-API call is invoked under.
1264 * @param info The callback info passed into the callback function.
1265 *
1266 * @return The return value from NAPI C++ to JS for the module.
1267 */
NAPI_GetWantSync(napi_env env,napi_callback_info info)1268 napi_value NAPI_GetWantSync(napi_env env, napi_callback_info info)
1269 {
1270 HILOG_INFO("%{public}s called.", __func__);
1271 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
1272 if (asyncCallbackInfo == nullptr) {
1273 return WrapVoidToJS(env);
1274 }
1275
1276 asyncCallbackInfo->errCode = NAPI_ERR_NO_ERROR;
1277 napi_value ret = GetWantSyncWrap(env, info, asyncCallbackInfo);
1278
1279 delete asyncCallbackInfo;
1280 asyncCallbackInfo = nullptr;
1281
1282 if (ret == nullptr) {
1283 ret = WrapVoidToJS(env);
1284 HILOG_ERROR("%{public}s ret == nullptr", __func__);
1285 } else {
1286 HILOG_INFO("%{public}s, end.", __func__);
1287 }
1288 return ret;
1289 }
1290
1291 /**
1292 * @brief Get want.
1293 *
1294 * @param env The environment that the Node-API call is invoked under.
1295 * @param info The callback info passed into the callback function.
1296 *
1297 * @return The return value from NAPI C++ to JS for the module.
1298 */
NAPI_GetWant(napi_env env,napi_callback_info info)1299 napi_value NAPI_GetWant(napi_env env, napi_callback_info info)
1300 {
1301 HILOG_INFO("%{public}s called.", __func__);
1302 return NAPI_GetWantCommon(env, info, AbilityType::PAGE);
1303 }
1304
1305 /**
1306 * @brief Obtains the type of this application.
1307 *
1308 * @param env The environment that the Node-API call is invoked under.
1309 * @param info The callback info passed into the callback function.
1310 *
1311 * @return The return value from NAPI C++ to JS for the module.
1312 */
NAPI_GetAppType(napi_env env,napi_callback_info info)1313 napi_value NAPI_GetAppType(napi_env env, napi_callback_info info)
1314 {
1315 HILOG_INFO("%{public}s called.", __func__);
1316 return NAPI_GetAppTypeCommon(env, info, AbilityType::PAGE);
1317 }
1318
1319 /**
1320 * @brief Obtains the class name in this ability name, without the prefixed bundle name.
1321 *
1322 * @param env The environment that the Node-API call is invoked under.
1323 * @param info The callback info passed into the callback function.
1324 *
1325 * @return The return value from NAPI C++ to JS for the module.
1326 */
NAPI_GetAbilityName(napi_env env,napi_callback_info info)1327 napi_value NAPI_GetAbilityName(napi_env env, napi_callback_info info)
1328 {
1329 HILOG_INFO("%{public}s called.", __func__);
1330 return NAPI_GetAbilityNameCommon(env, info, AbilityType::PAGE);
1331 }
1332
1333 /**
1334 * @brief Obtains information about the current ability.
1335 *
1336 * @param env The environment that the Node-API call is invoked under.
1337 * @param info The callback info passed into the callback function.
1338 *
1339 * @return The return value from NAPI C++ to JS for the module.
1340 */
NAPI_GetAbilityInfo(napi_env env,napi_callback_info info)1341 napi_value NAPI_GetAbilityInfo(napi_env env, napi_callback_info info)
1342 {
1343 HILOG_INFO("%{public}s called.", __func__);
1344 return NAPI_GetAbilityInfoCommon(env, info, AbilityType::PAGE);
1345 }
1346
1347 /**
1348 * @brief Obtains the HapModuleInfo object of the application.
1349 *
1350 * @param env The environment that the Node-API call is invoked under.
1351 * @param info The callback info passed into the callback function.
1352 *
1353 * @return The return value from NAPI C++ to JS for the module.
1354 */
NAPI_GetHapModuleInfo(napi_env env,napi_callback_info info)1355 napi_value NAPI_GetHapModuleInfo(napi_env env, napi_callback_info info)
1356 {
1357 HILOG_INFO("%{public}s called.", __func__);
1358 return NAPI_GetHapModuleInfoCommon(env, info, AbilityType::PAGE);
1359 }
1360
1361 /**
1362 * @brief FeatureAbility NAPI method : getDataAbilityHelper.
1363 *
1364 * @param env The environment that the Node-API call is invoked under.
1365 * @param info The callback info passed into the callback function.
1366 *
1367 * @return The return value from NAPI C++ to JS for the module.
1368 */
NAPI_GetDataAbilityHelper(napi_env env,napi_callback_info info)1369 napi_value NAPI_GetDataAbilityHelper(napi_env env, napi_callback_info info)
1370 {
1371 HILOG_INFO("%{public}s,called", __func__);
1372 DataAbilityHelperCB *dataAbilityHelperCB = new (std::nothrow) DataAbilityHelperCB;
1373 if (dataAbilityHelperCB == nullptr) {
1374 HILOG_ERROR("%{public}s, dataAbilityHelperCB == nullptr", __func__);
1375 return WrapVoidToJS(env);
1376 }
1377 dataAbilityHelperCB->cbBase.cbInfo.env = env;
1378 napi_value ret = GetDataAbilityHelperWrap(env, info, dataAbilityHelperCB);
1379 if (ret == nullptr) {
1380 HILOG_ERROR("%{public}s, ret == nullptr", __func__);
1381 if (dataAbilityHelperCB != nullptr) {
1382 delete dataAbilityHelperCB;
1383 dataAbilityHelperCB = nullptr;
1384 }
1385 ret = WrapVoidToJS(env);
1386 }
1387 HILOG_INFO("%{public}s,end", __func__);
1388 return ret;
1389 }
1390
1391 /**
1392 * @brief getDataAbilityHelper processing function.
1393 *
1394 * @param env The environment that the Node-API call is invoked under.
1395 * @param dataAbilityHelperCB Process data asynchronously.
1396 *
1397 * @return Return JS data successfully, otherwise return nullptr.
1398 */
GetDataAbilityHelperWrap(napi_env env,napi_callback_info info,DataAbilityHelperCB * dataAbilityHelperCB)1399 napi_value GetDataAbilityHelperWrap(napi_env env, napi_callback_info info, DataAbilityHelperCB *dataAbilityHelperCB)
1400 {
1401 HILOG_INFO("%{public}s,called", __func__);
1402 if (dataAbilityHelperCB == nullptr) {
1403 HILOG_ERROR("%{public}s,dataAbilityHelperCB == nullptr", __func__);
1404 return nullptr;
1405 }
1406
1407 size_t argcAsync = 2;
1408 const size_t argcPromise = 1;
1409 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1410 napi_value args[ARGS_MAX_COUNT] = {nullptr};
1411 napi_value ret = nullptr;
1412
1413 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
1414 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1415 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1416 return nullptr;
1417 }
1418
1419 napi_valuetype valuetype = napi_undefined;
1420 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1421 if (valuetype == napi_string) {
1422 NAPI_CALL(env, napi_create_reference(env, args[PARAM0], 1, &dataAbilityHelperCB->uri));
1423 }
1424
1425 if (argcAsync > argcPromise) {
1426 ret = GetDataAbilityHelperAsync(env, args, 1, dataAbilityHelperCB);
1427 } else {
1428 ret = GetDataAbilityHelperPromise(env, dataAbilityHelperCB);
1429 }
1430 HILOG_INFO("%{public}s,end", __func__);
1431 return ret;
1432 }
1433
GetDataAbilityHelperAsync(napi_env env,napi_value * args,const size_t argCallback,DataAbilityHelperCB * dataAbilityHelperCB)1434 napi_value GetDataAbilityHelperAsync(
1435 napi_env env, napi_value *args, const size_t argCallback, DataAbilityHelperCB *dataAbilityHelperCB)
1436 {
1437 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1438 if (args == nullptr || dataAbilityHelperCB == nullptr) {
1439 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1440 return nullptr;
1441 }
1442 napi_value resourceName = nullptr;
1443 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1444
1445 napi_valuetype valuetype = napi_undefined;
1446 NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1447 if (valuetype == napi_function) {
1448 NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &dataAbilityHelperCB->cbBase.cbInfo.callback));
1449 }
1450
1451 NAPI_CALL(env,
1452 napi_create_async_work(env, nullptr, resourceName,
1453 [](napi_env env, void *data) { HILOG_INFO("NAPI_GetDataAbilityHelper, worker pool thread execute."); },
1454 GetDataAbilityHelperAsyncCompleteCB,
1455 static_cast<void *>(dataAbilityHelperCB),
1456 &dataAbilityHelperCB->cbBase.asyncWork));
1457 NAPI_CALL(env, napi_queue_async_work(env, dataAbilityHelperCB->cbBase.asyncWork));
1458 napi_value result = nullptr;
1459 NAPI_CALL(env, napi_get_null(env, &result));
1460 HILOG_INFO("%{public}s, asyncCallback end", __func__);
1461 return result;
1462 }
1463
GetDataAbilityHelperPromise(napi_env env,DataAbilityHelperCB * dataAbilityHelperCB)1464 napi_value GetDataAbilityHelperPromise(napi_env env, DataAbilityHelperCB *dataAbilityHelperCB)
1465 {
1466 HILOG_INFO("%{public}s, promise.", __func__);
1467 if (dataAbilityHelperCB == nullptr) {
1468 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1469 return nullptr;
1470 }
1471 napi_value resourceName;
1472 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1473 napi_deferred deferred;
1474 napi_value promise = nullptr;
1475 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1476 dataAbilityHelperCB->cbBase.deferred = deferred;
1477
1478 NAPI_CALL(env,
1479 napi_create_async_work(env, nullptr, resourceName,
1480 [](napi_env env, void *data) { HILOG_INFO("NAPI_GetDataAbilityHelper, worker pool thread execute."); },
1481 GetDataAbilityHelperPromiseCompleteCB,
1482 static_cast<void *>(dataAbilityHelperCB),
1483 &dataAbilityHelperCB->cbBase.asyncWork));
1484 NAPI_CALL(env, napi_queue_async_work(env, dataAbilityHelperCB->cbBase.asyncWork));
1485 HILOG_INFO("%{public}s, promise end.", __func__);
1486 return promise;
1487 }
1488
GetDataAbilityHelperAsyncCompleteCB(napi_env env,napi_status status,void * data)1489 void GetDataAbilityHelperAsyncCompleteCB(napi_env env, napi_status status, void *data)
1490 {
1491 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete.");
1492 DataAbilityHelperCB *dataAbilityHelperCB = static_cast<DataAbilityHelperCB *>(data);
1493 std::unique_ptr<DataAbilityHelperCB> callbackPtr {dataAbilityHelperCB};
1494 napi_value uri = nullptr;
1495 napi_value callback = nullptr;
1496 napi_value undefined = nullptr;
1497 napi_value result[ARGS_TWO] = {nullptr};
1498 napi_value callResult = nullptr;
1499 napi_get_undefined(env, &undefined);
1500 napi_get_reference_value(env, dataAbilityHelperCB->uri, &uri);
1501 napi_get_reference_value(env, dataAbilityHelperCB->cbBase.cbInfo.callback, &callback);
1502 napi_new_instance(env, GetGlobalDataAbilityHelper(env), 1, &uri, &dataAbilityHelperCB->result);
1503 if (IsTypeForNapiValue(env, dataAbilityHelperCB->result, napi_object)) {
1504 result[PARAM1] = dataAbilityHelperCB->result;
1505 } else {
1506 HILOG_INFO("NAPI_GetDataAbilityHelper, helper is nullptr.");
1507 result[PARAM1] = WrapVoidToJS(env);
1508 }
1509 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
1510 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
1511 if (dataAbilityHelperCB->cbBase.cbInfo.callback != nullptr) {
1512 napi_delete_reference(env, dataAbilityHelperCB->cbBase.cbInfo.callback);
1513 }
1514 if (dataAbilityHelperCB->uri != nullptr) {
1515 napi_delete_reference(env, dataAbilityHelperCB->uri);
1516 }
1517 napi_delete_async_work(env, dataAbilityHelperCB->cbBase.asyncWork);
1518 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete end.");
1519 }
1520
GetDataAbilityHelperPromiseCompleteCB(napi_env env,napi_status status,void * data)1521 void GetDataAbilityHelperPromiseCompleteCB(napi_env env, napi_status status, void *data)
1522 {
1523 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete.");
1524 DataAbilityHelperCB *dataAbilityHelperCB = static_cast<DataAbilityHelperCB *>(data);
1525 napi_value uri = nullptr;
1526 napi_value result = nullptr;
1527 napi_get_reference_value(env, dataAbilityHelperCB->uri, &uri);
1528 napi_new_instance(env, GetGlobalDataAbilityHelper(env), 1, &uri, &dataAbilityHelperCB->result);
1529 if (IsTypeForNapiValue(env, dataAbilityHelperCB->result, napi_object)) {
1530 result = dataAbilityHelperCB->result;
1531 napi_resolve_deferred(env, dataAbilityHelperCB->cbBase.deferred, result);
1532 } else {
1533 result = GetCallbackErrorValue(env, dataAbilityHelperCB->cbBase.errCode);
1534 napi_reject_deferred(env, dataAbilityHelperCB->cbBase.deferred, result);
1535 HILOG_INFO("NAPI_GetDataAbilityHelper, helper is nullptr.");
1536 }
1537
1538 if (dataAbilityHelperCB->uri != nullptr) {
1539 napi_delete_reference(env, dataAbilityHelperCB->uri);
1540 }
1541 napi_delete_async_work(env, dataAbilityHelperCB->cbBase.asyncWork);
1542 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete end.");
1543 }
1544
1545 /**
1546 * @brief FeatureAbility NAPI method : acquireDataAbilityHelper.
1547 *
1548 * @param env The environment that the Node-API call is invoked under.
1549 * @param info The callback info passed into the callback function.
1550 *
1551 * @return The return value from NAPI C++ to JS for the module.
1552 */
NAPI_AcquireDataAbilityHelper(napi_env env,napi_callback_info info)1553 napi_value NAPI_AcquireDataAbilityHelper(napi_env env, napi_callback_info info)
1554 {
1555 HILOG_INFO("%{public}s,called", __func__);
1556 return NAPI_AcquireDataAbilityHelperCommon(env, info, AbilityType::PAGE);
1557 }
1558
1559 /**
1560 * @brief FeatureAbility NAPI method : continueAbility.
1561 *
1562 * @param env The environment that the Node-API call is invoked under.
1563 * @param info The callback info passed into the callback function.
1564 *
1565 * @return The return value from NAPI C++ to JS for the module.
1566 */
NAPI_FAContinueAbility(napi_env env,napi_callback_info info)1567 napi_value NAPI_FAContinueAbility(napi_env env, napi_callback_info info)
1568 {
1569 HILOG_INFO("%{public}s,called", __func__);
1570 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
1571 if (asyncCallbackInfo == nullptr) {
1572 HILOG_ERROR("%{public}s, asyncCallbackInfo == nullptr.", __func__);
1573 return WrapVoidToJS(env);
1574 }
1575
1576 napi_value ret = ContinueAbilityWrap(env, info, asyncCallbackInfo);
1577 if (ret == nullptr) {
1578 if (asyncCallbackInfo != nullptr) {
1579 delete asyncCallbackInfo;
1580 asyncCallbackInfo = nullptr;
1581 }
1582 ret = WrapVoidToJS(env);
1583 }
1584 HILOG_INFO("%{public}s,end.", __func__);
1585 return ret;
1586 }
1587
1588 /**
1589 * @brief ContinueAbilityWrap processing function.
1590 *
1591 * @param env The environment that the Node-API call is invoked under.
1592 * @param asyncCallbackInfo Process data asynchronously.
1593 *
1594 * @return Return JS data successfully, otherwise return nullptr.
1595 */
ContinueAbilityWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)1596 napi_value ContinueAbilityWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
1597 {
1598 HILOG_INFO("%{public}s, called.", __func__);
1599 size_t argc = 2;
1600 napi_value args[ARGS_MAX_COUNT] = {nullptr};
1601 napi_value ret = nullptr;
1602 napi_valuetype valueType = napi_undefined;
1603
1604 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1605 NAPI_CALL(env, napi_typeof(env, args[0], &valueType));
1606 if (valueType != napi_object && valueType != napi_function) {
1607 HILOG_ERROR("%{public}s, Wrong argument type. Object or function expected.", __func__);
1608 return nullptr;
1609 }
1610 if (argc == 0) {
1611 ret = ContinueAbilityPromise(env, args, asyncCallbackInfo, argc);
1612 } else if (PARA_SIZE_IS_ONE == argc) {
1613 if (valueType == napi_function) {
1614 ret = ContinueAbilityAsync(env, args, asyncCallbackInfo, argc);
1615 } else {
1616 ret = ContinueAbilityPromise(env, args, asyncCallbackInfo, argc);
1617 }
1618 } else if (PARA_SIZE_IS_TWO == argc) {
1619 napi_valuetype value = napi_undefined;
1620 NAPI_CALL(env, napi_typeof(env, args[1], &value));
1621 if (value != napi_function) {
1622 HILOG_ERROR("%{public}s, Wrong argument type. function expected.", __func__);
1623 return nullptr;
1624 }
1625 ret = ContinueAbilityAsync(env, args, asyncCallbackInfo, argc);
1626 } else {
1627 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1628 }
1629 HILOG_INFO("%{public}s,end.", __func__);
1630 return ret;
1631 }
1632
ContinueAbilityAsync(napi_env env,napi_value * args,AsyncCallbackInfo * asyncCallbackInfo,size_t argc)1633 napi_value ContinueAbilityAsync(napi_env env, napi_value *args, AsyncCallbackInfo *asyncCallbackInfo, size_t argc)
1634 {
1635 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1636 if (args == nullptr || asyncCallbackInfo == nullptr) {
1637 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1638 return nullptr;
1639 }
1640 napi_value resourceName = nullptr;
1641 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1642
1643 if (PARA_SIZE_IS_TWO == argc) {
1644 // args[0] : ContinueAbilityOptions
1645 napi_valuetype valueTypeOptions = napi_undefined;
1646 NAPI_CALL(env, napi_typeof(env, args[0], &valueTypeOptions));
1647 if (valueTypeOptions != napi_object) {
1648 HILOG_ERROR("%{public}s, Wrong argument type. Object expected.", __func__);
1649 return nullptr;
1650 }
1651 if (GetContinueAbilityOptionsInfoCommon(env, args[0], asyncCallbackInfo->optionInfo) == nullptr) {
1652 HILOG_ERROR("%{public}s, GetContinueAbilityOptionsInfoCommonFail", __func__);
1653 return nullptr;
1654 }
1655
1656 // args[1] : callback
1657 napi_valuetype valueTypeCallBack = napi_undefined;
1658 napi_typeof(env, args[1], &valueTypeCallBack);
1659 if (valueTypeCallBack == napi_function) {
1660 napi_create_reference(env, args[1], 1, &asyncCallbackInfo->cbInfo.callback);
1661 }
1662 } else {
1663 // args[0] : callback
1664 napi_valuetype valueTypeCallBack = napi_undefined;
1665 napi_typeof(env, args[1], &valueTypeCallBack);
1666 if (valueTypeCallBack == napi_function) {
1667 napi_create_reference(env, args[0], 1, &asyncCallbackInfo->cbInfo.callback);
1668 }
1669 }
1670
1671 napi_create_async_work(env, nullptr, resourceName,
1672 [](napi_env env, void *data) {
1673 HILOG_INFO("NAPI_ContinueAbility, worker pool thread execute.");
1674 AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data;
1675 if (asyncCallbackInfo->ability != nullptr) {
1676 asyncCallbackInfo->ability->ContinueAbility(asyncCallbackInfo->optionInfo.deviceId);
1677 } else {
1678 HILOG_ERROR("NAPI_ContinueAbilityForResult, asyncCallbackInfo == nullptr");
1679 }
1680 HILOG_INFO("NAPI_ContinueAbilityForResult, worker pool thread execute end.");
1681 },
1682 [](napi_env env, napi_status status, void *data) {
1683 HILOG_INFO("NAPI_ContinueAbility, main event thread complete.");
1684 AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data;
1685 napi_value callback = nullptr;
1686 napi_value undefined = nullptr;
1687 napi_value result[ARGS_TWO] = {nullptr};
1688 napi_value callResult = nullptr;
1689 napi_get_undefined(env, &undefined);
1690 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
1691 napi_get_null(env, &result[PARAM1]);
1692 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
1693 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
1694
1695 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
1696 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
1697 }
1698 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1699 delete asyncCallbackInfo;
1700 HILOG_INFO("NAPI_ContinueAbilityForResult, main event thread complete end.");
1701 },
1702 static_cast<void *>(asyncCallbackInfo),
1703 &asyncCallbackInfo->asyncWork);
1704 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1705 napi_value result = nullptr;
1706 napi_get_null(env, &result);
1707 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1708 return result;
1709 }
1710
ContinueAbilityPromise(napi_env env,napi_value * args,AsyncCallbackInfo * asyncCallbackInfo,size_t argc)1711 napi_value ContinueAbilityPromise(napi_env env, napi_value *args, AsyncCallbackInfo *asyncCallbackInfo, size_t argc)
1712 {
1713 HILOG_INFO("%{public}s, promise.", __func__);
1714 if (asyncCallbackInfo == nullptr) {
1715 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1716 return nullptr;
1717 }
1718
1719 if (argc == PARA_SIZE_IS_ONE) {
1720 // args[0] : ContinueAbilityOptions
1721 napi_valuetype valueTypeOptions = napi_undefined;
1722 NAPI_CALL(env, napi_typeof(env, args[0], &valueTypeOptions));
1723 if (valueTypeOptions != napi_object) {
1724 HILOG_ERROR("%{public}s, Wrong argument type. Object expected.", __func__);
1725 return nullptr;
1726 }
1727 if (GetContinueAbilityOptionsInfoCommon(env, args[0], asyncCallbackInfo->optionInfo) == nullptr) {
1728 return nullptr;
1729 }
1730 }
1731
1732 napi_value resourceName = nullptr;
1733 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1734 napi_deferred deferred;
1735 napi_value promise = nullptr;
1736 napi_create_promise(env, &deferred, &promise);
1737
1738 asyncCallbackInfo->deferred = deferred;
1739
1740 napi_create_async_work(env, nullptr, resourceName,
1741 [](napi_env env, void *data) {
1742 HILOG_INFO("NAPI_ContinueAbility, worker pool thread execute.");
1743 AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data;
1744 if (asyncCallbackInfo->ability != nullptr) {
1745 asyncCallbackInfo->ability->ContinueAbility(asyncCallbackInfo->optionInfo.deviceId);
1746 } else {
1747 HILOG_ERROR("NAPI_ContinueAbilityForResult, asyncCallbackInfo == nullptr");
1748 }
1749 HILOG_INFO("NAPI_ContinueAbilityForResult, worker pool thread execute end.");
1750 },
1751 [](napi_env env, napi_status status, void *data) {
1752 HILOG_INFO("NAPI_ContinueAbility, main event thread complete.");
1753 AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data;
1754 napi_value result = nullptr;
1755 napi_get_null(env, &result);
1756 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
1757 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1758 delete asyncCallbackInfo;
1759 HILOG_INFO("NAPI_ContinueAbilityForResult, main event thread complete end.");
1760 },
1761 static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
1762 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1763 HILOG_INFO("%{public}s, promise end.", __func__);
1764 return promise;
1765 }
1766 } // namespace AppExecFwk
1767 } // namespace OHOS
1768