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 "napi_common_ability.h"
22 #include "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_DEBUG("called");
61 napi_property_descriptor properties[] = {
62 DECLARE_NAPI_FUNCTION("finishWithResult", NAPI_SetResult),
63 DECLARE_NAPI_FUNCTION("getAppType", NAPI_GetAppType),
64 DECLARE_NAPI_FUNCTION("getAbilityName", NAPI_GetAbilityName),
65 DECLARE_NAPI_FUNCTION("getAbilityInfo", NAPI_GetAbilityInfo),
66 DECLARE_NAPI_FUNCTION("getHapModuleInfo", NAPI_GetHapModuleInfo),
67 DECLARE_NAPI_FUNCTION("getDataAbilityHelper", NAPI_GetDataAbilityHelper),
68 DECLARE_NAPI_FUNCTION("acquireDataAbilityHelper", NAPI_AcquireDataAbilityHelper),
69 DECLARE_NAPI_FUNCTION("continueAbility", NAPI_FAContinueAbility),
70 DECLARE_NAPI_FUNCTION("getWantSync", NAPI_GetWantSync),
71 };
72 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
73
74 return JsFeatureAbilityInit(env, exports);
75 }
76
77 class JsFeatureAbility : public JsNapiCommon {
78 public:
79 JsFeatureAbility() = default;
80 virtual ~JsFeatureAbility() override = default;
81
82 Ability* GetAbility(napi_env env);
83 static void Finalizer(napi_env env, void *data, void *hint);
84 static napi_value StartAbility(napi_env env, napi_callback_info info);
85 static napi_value HasWindowFocus(napi_env env, napi_callback_info info);
86 static napi_value ConnectAbility(napi_env env, napi_callback_info info);
87 static napi_value DisconnectAbility(napi_env env, napi_callback_info info);
88 static napi_value GetWant(napi_env env, napi_callback_info info);
89 static napi_value StartAbilityForResult(napi_env env, napi_callback_info info);
90 static napi_value GetContext(napi_env env, napi_callback_info info);
91 static napi_value FinishWithResult(napi_env env, napi_callback_info info);
92 static napi_value TerminateAbility(napi_env env, napi_callback_info info);
93 static napi_value GetWindow(napi_env env, napi_callback_info info);
94 std::shared_ptr<NativeReference> GetFAContext();
95 void SetFAContext(std::shared_ptr<NativeReference> context);
96 private:
97 napi_value OnStartAbilityForResult(napi_env env, NapiCallbackInfo& info);
98 napi_value OnFinishWithResult(napi_env env, NapiCallbackInfo& info);
99 napi_value OnGetWindow(napi_env env, napi_callback_info info);
100 #ifdef SUPPORT_GRAPHICS
101 napi_value OnHasWindowFocus(napi_env env, const NapiCallbackInfo& info);
102 #endif
103 std::shared_ptr<NativeReference> context_;
104 };
105
Finalizer(napi_env env,void * data,void * hint)106 void JsFeatureAbility::Finalizer(napi_env env, void *data, void *hint)
107 {
108 HILOG_DEBUG("called");
109 std::unique_ptr<JsFeatureAbility>(static_cast<JsFeatureAbility*>(data));
110 }
111
JsFeatureAbilityInit(napi_env env,napi_value exports)112 napi_value JsFeatureAbilityInit(napi_env env, napi_value exports)
113 {
114 HILOG_DEBUG("JsFeatureAbilityInit is called");
115 if (env == nullptr || exports == nullptr) {
116 HILOG_ERROR("Invalid input parameters");
117 return exports;
118 }
119
120 if (!AppExecFwk::CheckTypeForNapiValue(env, exports, napi_object)) {
121 HILOG_ERROR("object is nullptr");
122 return exports;
123 }
124
125 std::unique_ptr<JsFeatureAbility> jsFeatureAbility = std::make_unique<JsFeatureAbility>();
126 jsFeatureAbility->ability_ = jsFeatureAbility->GetAbility(env);
127 napi_value contextValue = CreateNapiJSContext(env);
128 if (contextValue != nullptr) {
129 napi_ref contextRef = nullptr;
130 napi_create_reference(env, contextValue, 1, &contextRef);
131 jsFeatureAbility->SetFAContext(
132 std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(contextRef)));
133 }
134 napi_wrap(env, exports, jsFeatureAbility.release(), JsFeatureAbility::Finalizer, nullptr, nullptr);
135
136 const char *moduleName = "JsFeatureAbility";
137 BindNativeFunction(env, exports, "startAbility", moduleName, JsFeatureAbility::StartAbility);
138 BindNativeFunction(env, exports, "getWant", moduleName, JsFeatureAbility::GetWant);
139 BindNativeFunction(env, exports, "hasWindowFocus", moduleName, JsFeatureAbility::HasWindowFocus);
140 BindNativeFunction(env, exports, "connectAbility", moduleName, JsFeatureAbility::ConnectAbility);
141 BindNativeFunction(env, exports, "disconnectAbility", moduleName, JsFeatureAbility::DisconnectAbility);
142 BindNativeFunction(env, exports, "startAbilityForResult", moduleName, JsFeatureAbility::StartAbilityForResult);
143 BindNativeFunction(env, exports, "getContext", moduleName, JsFeatureAbility::GetContext);
144 BindNativeFunction(env, exports, "getWindow", moduleName, JsFeatureAbility::GetWindow);
145 BindNativeFunction(env, exports, "terminateSelfWithResult", moduleName, JsFeatureAbility::FinishWithResult);
146 BindNativeFunction(env, exports, "terminateSelf", moduleName, JsFeatureAbility::TerminateAbility);
147 return exports;
148 }
149
SetFAContext(std::shared_ptr<NativeReference> context)150 void JsFeatureAbility::SetFAContext(std::shared_ptr<NativeReference> context)
151 {
152 context_ = context;
153 }
154
GetFAContext()155 std::shared_ptr<NativeReference> JsFeatureAbility::GetFAContext()
156 {
157 return context_;
158 }
159
StartAbility(napi_env env,napi_callback_info info)160 napi_value JsFeatureAbility::StartAbility(napi_env env, napi_callback_info info)
161 {
162 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(env, info);
163 return (me != nullptr) ? me->JsStartAbility(env, info, AbilityType::PAGE) : nullptr;
164 }
165
GetWant(napi_env env,napi_callback_info info)166 napi_value JsFeatureAbility::GetWant(napi_env env, napi_callback_info info)
167 {
168 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(env, info);
169 return (me != nullptr) ? me->JsGetWant(env, info, AbilityType::PAGE) : nullptr;
170 }
171
HasWindowFocus(napi_env env,napi_callback_info info)172 napi_value JsFeatureAbility::HasWindowFocus(napi_env env, napi_callback_info info)
173 {
174 #ifdef SUPPORT_GRAPHICS
175 GET_NAPI_INFO_AND_CALL(env, info, JsFeatureAbility, OnHasWindowFocus);
176 #else
177 return nullptr;
178 #endif
179 }
180
ConnectAbility(napi_env env,napi_callback_info info)181 napi_value JsFeatureAbility::ConnectAbility(napi_env env, napi_callback_info info)
182 {
183 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(env, info);
184 return (me != nullptr) ? me->JsConnectAbility(env, info, AbilityType::PAGE) : nullptr;
185 }
186
DisconnectAbility(napi_env env,napi_callback_info info)187 napi_value JsFeatureAbility::DisconnectAbility(napi_env env, napi_callback_info info)
188 {
189 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(env, info);
190 return (me != nullptr) ? me->JsDisConnectAbility(env, info, AbilityType::PAGE) : nullptr;
191 }
192
StartAbilityForResult(napi_env env,napi_callback_info info)193 napi_value JsFeatureAbility::StartAbilityForResult(napi_env env, napi_callback_info info)
194 {
195 GET_NAPI_INFO_AND_CALL(env, info, JsFeatureAbility, OnStartAbilityForResult);
196 }
197
GetContext(napi_env env,napi_callback_info info)198 napi_value JsFeatureAbility::GetContext(napi_env env, napi_callback_info info)
199 {
200 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(env, info);
201 if (me != nullptr) {
202 std::shared_ptr<NativeReference> contextObj = me->GetFAContext();
203 if (contextObj != nullptr) {
204 return contextObj->GetNapiValue();
205 }
206 napi_value contextValue = me->JsGetContext(env, info, AbilityType::PAGE);
207 if (contextValue != nullptr) {
208 napi_ref contextRef = nullptr;
209 napi_create_reference(env, contextValue, 1, &contextRef);
210 me->SetFAContext(std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(contextRef)));
211 return contextValue;
212 }
213 }
214 return nullptr;
215 }
216
FinishWithResult(napi_env env,napi_callback_info info)217 napi_value JsFeatureAbility::FinishWithResult(napi_env env, napi_callback_info info)
218 {
219 GET_NAPI_INFO_AND_CALL(env, info, JsFeatureAbility, OnFinishWithResult);
220 }
221
TerminateAbility(napi_env env,napi_callback_info info)222 napi_value JsFeatureAbility::TerminateAbility(napi_env env, napi_callback_info info)
223 {
224 GET_NAPI_INFO_AND_CALL(env, info, JsFeatureAbility, JsTerminateAbility);
225 }
226
227 #ifdef SUPPORT_GRAPHICS
OnHasWindowFocus(napi_env env,const NapiCallbackInfo & info)228 napi_value JsFeatureAbility::OnHasWindowFocus(napi_env env, const NapiCallbackInfo& info)
229 {
230 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
231 if (info.argc > ARGS_ONE || info.argc < ARGS_ZERO) {
232 HILOG_ERROR(" wrong number of arguments.");
233 return CreateJsUndefined(env);
234 }
235 NapiAsyncTask::CompleteCallback complete =
236 [obj = this](napi_env env, NapiAsyncTask &task, int32_t status) {
237 if (obj->ability_ == nullptr) {
238 HILOG_ERROR("HasWindowFocus execute error, the ability is nullptr");
239 task.Reject(env, CreateJsError(env, NAPI_ERR_ACE_ABILITY, "HasWindowFocus failed"));
240 return;
241 }
242 auto ret = obj->ability_->HasWindowFocus();
243 task.Resolve(env, CreateJsValue(env, ret));
244 };
245 napi_value result = nullptr;
246 napi_value lastParam = (info.argc == ARGS_ZERO) ? nullptr : info.argv[PARAM0];
247 NapiAsyncTask::ScheduleHighQos("JSFeatureAbility::OnHasWindowFocus",
248 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
249 HILOG_DEBUG("OnHasWindowFocus is called end");
250 return result;
251 }
252 #endif
253
GetAbility(napi_env env)254 Ability* JsFeatureAbility::GetAbility(napi_env env)
255 {
256 napi_status ret;
257 napi_value global = nullptr;
258 const napi_extended_error_info *errorInfo = nullptr;
259 ret = napi_get_global(env, &global);
260 if (ret != napi_ok) {
261 napi_get_last_error_info(env, &errorInfo);
262 HILOG_ERROR("get_global=%{public}d err:%{public}s", ret, errorInfo->error_message);
263 return nullptr;
264 }
265
266 napi_value abilityObj = nullptr;
267 ret = napi_get_named_property(env, global, "ability", &abilityObj);
268 if (ret != napi_ok) {
269 napi_get_last_error_info(env, &errorInfo);
270 HILOG_ERROR("get_named_property=%{public}d err:%{public}s", ret, errorInfo->error_message);
271 return nullptr;
272 }
273
274 Ability *ability = nullptr;
275 ret = napi_get_value_external(env, abilityObj, reinterpret_cast<void **>(&ability));
276 if (ret != napi_ok) {
277 napi_get_last_error_info(env, &errorInfo);
278 HILOG_ERROR("get_value_external=%{public}d err:%{public}s", ret, errorInfo->error_message);
279 return nullptr;
280 }
281
282 return ability;
283 }
284
OnStartAbilityForResult(napi_env env,NapiCallbackInfo & info)285 napi_value JsFeatureAbility::OnStartAbilityForResult(napi_env env, NapiCallbackInfo& info)
286 {
287 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
288 if (info.argc < ARGS_ONE || info.argc > ARGS_TWO) {
289 HILOG_ERROR("wrong number of arguments.");
290 return CreateJsUndefined(env);
291 }
292
293 if (ability_ == nullptr) {
294 HILOG_ERROR("ability is nullptr");
295 return CreateJsUndefined(env);
296 }
297
298 std::shared_ptr<CallAbilityParam> abilityParam = std::make_shared<CallAbilityParam>();
299 std::shared_ptr<CallbackInfo> startAbilityCallback = std::make_shared<CallbackInfo>();
300 startAbilityCallback->env = env;
301
302 if (UnwrapForResultParam(*abilityParam, env, info.argv[0]) == nullptr) {
303 HILOG_ERROR("OnStartAbilityForResult UnwrapForResultParam failed.");
304 startAbilityCallback->errCode = NAPI_ERR_PARAM_INVALID;
305 }
306
307 napi_value result = nullptr;
308 napi_value lastParam = (info.argc == ARGS_TWO) ? info.argv[ARGS_ONE] : nullptr;
309 startAbilityCallback->napiAsyncTask =
310 AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result).release();
311
312 AbilityProcess::GetInstance()->AddAbilityResultCallback(ability_,
313 *abilityParam, startAbilityCallback->errCode, *startAbilityCallback);
314
315 if (startAbilityCallback->errCode == NAPI_ERR_NO_ERROR) {
316 startAbilityCallback->errCode = AbilityProcess::GetInstance()->StartAbility(ability_,
317 *abilityParam, *startAbilityCallback);
318 }
319
320 if (startAbilityCallback->errCode != NAPI_ERR_NO_ERROR) {
321 // Callback the errcode when StartAbilityForResult failed.
322 Want resultData;
323 AbilityProcess::GetInstance()->OnAbilityResult(ability_, abilityParam->requestCode, 0, resultData);
324 }
325
326 return result;
327 }
328
OnFinishWithResult(napi_env env,NapiCallbackInfo & info)329 napi_value JsFeatureAbility::OnFinishWithResult(napi_env env, NapiCallbackInfo& info)
330 {
331 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
332 if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
333 HILOG_ERROR("wrong number of arguments.");
334 return CreateJsUndefined(env);
335 }
336
337 if (!AppExecFwk::IsTypeForNapiValue(env, info.argv[0], napi_object)) {
338 HILOG_ERROR("OnFinishWithResult param is not object.");
339 return CreateJsUndefined(env);
340 }
341
342 CallAbilityParam param;
343 napi_value jsRequestCode = nullptr;
344 napi_get_named_property(env, info.argv[0], "resultCode", &jsRequestCode);
345 if (!AppExecFwk::IsTypeForNapiValue(env, jsRequestCode, napi_number)) {
346 HILOG_ERROR("OnFinishWithResult resultCode type failed.");
347 return CreateJsUndefined(env);
348 }
349 if (!ConvertFromJsValue(env, jsRequestCode, param.requestCode)) {
350 HILOG_ERROR("OnFinishWithResult convert resultCode failed.");
351 return CreateJsUndefined(env);
352 }
353 bool hasWant = false;
354 napi_has_named_property(env, info.argv[0], "want", &hasWant);
355 if (hasWant) {
356 napi_value jsWant = nullptr;
357 napi_get_named_property(env, info.argv[0], "want", &jsWant);
358 if (!AppExecFwk::IsTypeForNapiValue(env, jsWant, napi_object)) {
359 HILOG_ERROR("OnFinishWithResult want type failed.");
360 return CreateJsUndefined(env);
361 }
362 if (!UnwrapWant(env, jsWant, param.want)) {
363 HILOG_ERROR("OnFinishWithResult UnwrapWant failed.");
364 return CreateJsUndefined(env);
365 }
366 }
367
368 NapiAsyncTask::CompleteCallback complete = [obj = this, param](napi_env env, NapiAsyncTask &task, int32_t status) {
369 if (obj->ability_ != nullptr) {
370 obj->ability_->SetResult(param.requestCode, param.want);
371 obj->ability_->TerminateAbility();
372 } else {
373 HILOG_ERROR("OnFinishWithResult ability is nullptr");
374 }
375 task.Resolve(env, CreateJsNull(env));
376 };
377 napi_value result = nullptr;
378 napi_value lastParam = (info.argc >= ARGS_TWO) ? info.argv[ARGS_ONE] : nullptr;
379 NapiAsyncTask::ScheduleHighQos("JSFeatureAbility::OnFinishWithResult",
380 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
381 return result;
382 }
383
384 #ifdef SUPPORT_GRAPHICS
GetWindow(napi_env env,napi_callback_info info)385 napi_value JsFeatureAbility::GetWindow(napi_env env, napi_callback_info info)
386 {
387 if (env == nullptr || info == nullptr) {
388 HILOG_ERROR("JsFeatureAbility::%{public}s is called, but input parameters %{public}s is nullptr",
389 __func__, ((env == nullptr) ? "env" : "info"));
390 return nullptr;
391 }
392
393 auto object = CheckParamsAndGetThis<JsFeatureAbility>(env, info);
394 if (object == nullptr) {
395 HILOG_ERROR("CheckParamsAndGetThis return nullptr");
396 return nullptr;
397 }
398
399 return object->OnGetWindow(env, info);
400 }
401
OnGetWindow(napi_env env,napi_callback_info info)402 napi_value JsFeatureAbility::OnGetWindow(napi_env env, napi_callback_info info)
403 {
404 HILOG_DEBUG("%{public}s called", __func__);
405 size_t argc = ARGS_MAX_COUNT;
406 napi_value argv[ARGS_MAX_COUNT] = { nullptr };
407 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
408 if (argc > ARGS_ONE) {
409 HILOG_ERROR("input params count error, argc=%{public}zu", argc);
410 return CreateJsUndefined(env);
411 }
412
413 auto complete = [obj = this] (napi_env env, NapiAsyncTask& task, int32_t status) {
414 if (obj->ability_ == nullptr) {
415 HILOG_ERROR("OnGetWindow task execute error, the ability is nullptr");
416 task.Resolve(env, CreateJsNull(env));
417 return;
418 }
419 auto window = obj->ability_->GetWindow();
420 task.Resolve(env, OHOS::Rosen::CreateJsWindowObject(env, window));
421 };
422
423 auto callback = argc == ARGS_ZERO ? nullptr : argv[PARAM0];
424 napi_value result = nullptr;
425 NapiAsyncTask::ScheduleHighQos("JsFeatureAbility::OnGetWindow",
426 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
427
428 return result;
429 }
430 #else
431
GetWindow(napi_env env,napi_callback_info info)432 napi_value JsFeatureAbility::GetWindow(napi_env env, napi_callback_info info)
433 {
434 return nullptr;
435 }
436
OnGetWindow(napi_env env,napi_callback_info info)437 napi_value JsFeatureAbility::OnGetWindow(napi_env env, napi_callback_info info)
438 {
439 return nullptr;
440 }
441 #endif
442
443 /**
444 * @brief FeatureAbility NAPI method : setResult.
445 *
446 * @param env The environment that the Node-API call is invoked under.
447 * @param info The callback info passed into the callback function.
448 *
449 * @return The return value from NAPI C++ to JS for the module.
450 */
NAPI_SetResult(napi_env env,napi_callback_info info)451 napi_value NAPI_SetResult(napi_env env, napi_callback_info info)
452 {
453 HILOG_INFO("%{public}s,called", __func__);
454 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
455 if (asyncCallbackInfo == nullptr) {
456 HILOG_ERROR("%{public}s,asyncCallbackInfo == nullptr", __func__);
457 return WrapVoidToJS(env);
458 }
459
460 napi_value ret = SetResultWrap(env, info, asyncCallbackInfo);
461 if (ret == nullptr) {
462 HILOG_ERROR("%{public}s,ret == nullptr", __func__);
463 if (asyncCallbackInfo != nullptr) {
464 delete asyncCallbackInfo;
465 asyncCallbackInfo = nullptr;
466 }
467 ret = WrapVoidToJS(env);
468 }
469 HILOG_INFO("%{public}s,end", __func__);
470 return ret;
471 }
472
473 /**
474 * @brief SetResult processing function.
475 *
476 * @param env The environment that the Node-API call is invoked under.
477 * @param asyncCallbackInfo Process data asynchronously.
478 *
479 * @return Return JS data successfully, otherwise return nullptr.
480 */
SetResultWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)481 napi_value SetResultWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
482 {
483 HILOG_INFO("%{public}s,called", __func__);
484 size_t argcAsync = 2;
485 const size_t argcPromise = 1;
486 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
487 napi_value args[ARGS_MAX_COUNT] = {nullptr};
488 napi_value ret = nullptr;
489
490 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
491 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
492 HILOG_ERROR("%{public}s, Fail argument count.", __func__);
493 return nullptr;
494 }
495
496 CallAbilityParam param;
497 if (UnwrapAbilityResult(param, env, args[0]) == nullptr) {
498 HILOG_ERROR("%{public}s, call unwrapWant failed.", __func__);
499 return nullptr;
500 }
501 asyncCallbackInfo->param = param;
502
503 if (argcAsync > argcPromise) {
504 ret = SetResultAsync(env, args, 1, asyncCallbackInfo);
505 } else {
506 ret = SetResultPromise(env, asyncCallbackInfo);
507 }
508 HILOG_INFO("%{public}s,end", __func__);
509 return ret;
510 }
511
SetResultAsync(napi_env env,napi_value * args,const size_t argCallback,AsyncCallbackInfo * asyncCallbackInfo)512 napi_value SetResultAsync(
513 napi_env env, napi_value *args, const size_t argCallback, AsyncCallbackInfo *asyncCallbackInfo)
514 {
515 HILOG_INFO("%{public}s, asyncCallback.", __func__);
516 if (args == nullptr || asyncCallbackInfo == nullptr) {
517 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
518 return nullptr;
519 }
520 napi_value resourceName = nullptr;
521 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
522
523 napi_valuetype valuetype = napi_undefined;
524 NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
525 if (valuetype == napi_function) {
526 napi_create_reference(env, args[argCallback], 1, &asyncCallbackInfo->cbInfo.callback);
527 }
528
529 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
530 [](napi_env env, void *data) {
531 HILOG_INFO("NAPI_SetResult, worker pool thread enter.");
532 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
533 if (asyncCallbackInfo == nullptr) {
534 HILOG_ERROR("NAPI_SetResult, execute asyncCallbackInfo is nullptr");
535 return;
536 }
537
538 if (asyncCallbackInfo->ability != nullptr) {
539 asyncCallbackInfo->ability->SetResult(
540 asyncCallbackInfo->param.requestCode, asyncCallbackInfo->param.want);
541 asyncCallbackInfo->ability->TerminateAbility();
542 } else {
543 HILOG_ERROR("NAPI_SetResult, ability == null");
544 }
545 HILOG_INFO("NAPI_SetResult, worker pool thread execute exit.");
546 },
547 [](napi_env env, napi_status status, void *data) {
548 HILOG_INFO("NAPI_SetResult, main event thread complete.");
549 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
550 if (asyncCallbackInfo == nullptr) {
551 HILOG_ERROR("NAPI_SetResult, complete asyncCallbackInfo is nullptr");
552 return;
553 }
554 napi_value result[ARGS_TWO] = {nullptr};
555 napi_value callback = nullptr;
556 napi_value undefined = nullptr;
557 napi_value callResult = nullptr;
558 napi_get_undefined(env, &undefined);
559 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
560 napi_get_null(env, &result[PARAM1]);
561 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
562 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
563
564 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
565 HILOG_DEBUG("napi_delete_reference");
566 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
567 }
568 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
569 delete asyncCallbackInfo;
570 HILOG_INFO("NAPI_SetResult, main event thread complete end.");
571 },
572 static_cast<void *>(asyncCallbackInfo),
573 &asyncCallbackInfo->asyncWork));
574 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
575 napi_value result = nullptr;
576 NAPI_CALL(env, napi_get_null(env, &result));
577 HILOG_INFO("%{public}s, asyncCallback end", __func__);
578 return result;
579 }
580
SetResultPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)581 napi_value SetResultPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
582 {
583 HILOG_INFO("%{public}s, promise.", __func__);
584 if (asyncCallbackInfo == nullptr) {
585 HILOG_ERROR("SetResultPromise, param == nullptr.");
586 return nullptr;
587 }
588 napi_value resourceName = nullptr;
589 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
590 napi_deferred deferred;
591 napi_value promise = nullptr;
592 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
593 asyncCallbackInfo->deferred = deferred;
594
595 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
596 [](napi_env env, void *data) {
597 HILOG_INFO("NAPI_SetResult, worker pool thread execute.");
598 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
599 if (asyncCallbackInfo == nullptr) {
600 HILOG_ERROR("NAPI_SetResult promise, execute asyncCallbackInfo is nullptr");
601 return;
602 }
603
604 if (asyncCallbackInfo->ability != nullptr) {
605 asyncCallbackInfo->ability->SetResult(
606 asyncCallbackInfo->param.requestCode, asyncCallbackInfo->param.want);
607 asyncCallbackInfo->ability->TerminateAbility();
608 } else {
609 HILOG_ERROR("NAPI_SetResult, ability == nullptr");
610 }
611 HILOG_INFO("NAPI_SetResult, worker pool thread execute end.");
612 },
613 [](napi_env env, napi_status status, void *data) {
614 HILOG_INFO("NAPI_SetResult, main event thread complete.");
615 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
616 if (asyncCallbackInfo == nullptr) {
617 HILOG_ERROR("NAPI_SetResult promise, execute asyncCallbackInfo is nullptr");
618 return;
619 }
620 napi_value result = nullptr;
621 napi_get_null(env, &result);
622 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
623 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
624 delete asyncCallbackInfo;
625 HILOG_INFO("NAPI_SetResult, main event thread complete end.");
626 },
627 static_cast<void *>(asyncCallbackInfo),
628 &asyncCallbackInfo->asyncWork));
629 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
630 HILOG_INFO("%{public}s, promise end", __func__);
631 return promise;
632 }
633
634 EXTERN_C_START
635 /**
636 * @brief The interface of onAbilityResult provided for ACE to call back to JS.
637 *
638 * @param requestCode Indicates the request code returned after the ability is started.
639 * @param resultCode Indicates the result code returned after the ability is started.
640 * @param resultData Indicates the data returned after the ability is started.
641 * @param cb The environment and call back info that the Node-API call is invoked under.
642 *
643 * @return The return value from NAPI C++ to JS for the module.
644 */
CallOnAbilityResult(int requestCode,int resultCode,const Want & resultData,CallbackInfo callbackInfo)645 void CallOnAbilityResult(int requestCode, int resultCode, const Want &resultData, CallbackInfo callbackInfo)
646 {
647 HILOG_INFO("%{public}s,called", __func__);
648 if (callbackInfo.env == nullptr) {
649 HILOG_ERROR("CallOnAbilityResult cb.env is nullptr.");
650 return;
651 }
652
653 if (callbackInfo.napiAsyncTask == nullptr) {
654 HILOG_ERROR("CallOnAbilityResult cb.asyncTask is nullptr.");
655 return;
656 }
657
658 uv_loop_t *loop = nullptr;
659 napi_get_uv_event_loop(callbackInfo.env, &loop);
660 if (loop == nullptr) {
661 HILOG_ERROR("loop instance is nullptr");
662 return;
663 }
664
665 auto work = new uv_work_t;
666 auto onAbilityCB = new (std::nothrow) OnAbilityCallback;
667 onAbilityCB->requestCode = requestCode;
668 onAbilityCB->resultCode = resultCode;
669 onAbilityCB->resultData = resultData;
670 onAbilityCB->cb = callbackInfo;
671
672 work->data = static_cast<void *>(onAbilityCB);
673
674 int rev = uv_queue_work(
675 loop,
676 work,
677 [](uv_work_t *work) {},
678 [](uv_work_t *work, int status) {
679 HILOG_INFO("CallOnAbilityResult, uv_queue_work");
680 // JS Thread
681 if (work == nullptr) {
682 HILOG_ERROR("%{public}s, uv_queue_work work == nullptr.", __func__);
683 return;
684 }
685 auto onAbilityCB = static_cast<OnAbilityCallback *>(work->data);
686 if (onAbilityCB == nullptr) {
687 HILOG_ERROR("%{public}s, uv_queue_work onAbilityCB == nullptr.", __func__);
688 delete work;
689 work = nullptr;
690 return;
691 }
692
693 if (onAbilityCB->cb.errCode != ERR_OK) {
694 int32_t errCode = GetStartAbilityErrorCode(onAbilityCB->cb.errCode);
695 onAbilityCB->cb.napiAsyncTask->Reject(onAbilityCB->cb.env,
696 CreateJsError(onAbilityCB->cb.env, errCode, "StartAbilityForResult Error"));
697 delete onAbilityCB->cb.napiAsyncTask;
698 onAbilityCB->cb.napiAsyncTask = nullptr;
699 delete onAbilityCB;
700 onAbilityCB = nullptr;
701 delete work;
702 work = nullptr;
703 return;
704 }
705
706 napi_value objValue = nullptr;
707 napi_create_object(onAbilityCB->cb.env, &objValue);
708
709 napi_set_named_property(onAbilityCB->cb.env,
710 objValue, "resultCode", CreateJsValue(onAbilityCB->cb.env, onAbilityCB->resultCode));
711 napi_set_named_property(onAbilityCB->cb.env,
712 objValue, "want", CreateJsWant(onAbilityCB->cb.env, onAbilityCB->resultData));
713
714 onAbilityCB->cb.napiAsyncTask->Resolve(onAbilityCB->cb.env, objValue);
715 delete onAbilityCB->cb.napiAsyncTask;
716 onAbilityCB->cb.napiAsyncTask = nullptr;
717 delete onAbilityCB;
718 onAbilityCB = nullptr;
719 delete work;
720 work = nullptr;
721 HILOG_INFO("CallOnAbilityResult, uv_queue_work end");
722 });
723 if (rev != 0) {
724 if (onAbilityCB != nullptr) {
725 delete onAbilityCB;
726 onAbilityCB = nullptr;
727 }
728 if (work != nullptr) {
729 delete work;
730 work = nullptr;
731 }
732 }
733 HILOG_INFO("%{public}s,end", __func__);
734 }
735 EXTERN_C_END
736
InnerUnwrapWant(napi_env env,napi_value args,Want & want)737 bool InnerUnwrapWant(napi_env env, napi_value args, Want &want)
738 {
739 HILOG_INFO("%{public}s called", __func__);
740 napi_valuetype valueType = napi_undefined;
741 NAPI_CALL_BASE(env, napi_typeof(env, args, &valueType), false);
742 if (valueType != napi_object) {
743 HILOG_ERROR("%{public}s wrong argument type", __func__);
744 return false;
745 }
746
747 napi_value jsWant = GetPropertyValueByPropertyName(env, args, "want", napi_object);
748 if (jsWant == nullptr) {
749 HILOG_ERROR("%{public}s jsWant == nullptr", __func__);
750 return false;
751 }
752
753 return UnwrapWant(env, jsWant, want);
754 }
755
756 /**
757 * @brief Parse the parameters.
758 *
759 * @param param Indicates the parameters saved the parse result.
760 * @param env The environment that the Node-API call is invoked under.
761 * @param args Indicates the arguments passed into the callback.
762 *
763 * @return The return value from NAPI C++ to JS for the module.
764 */
UnwrapForResultParam(CallAbilityParam & param,napi_env env,napi_value args)765 napi_value UnwrapForResultParam(CallAbilityParam ¶m, napi_env env, napi_value args)
766 {
767 HILOG_INFO("%{public}s,called", __func__);
768 // dummy requestCode for NativeC++ interface and onabilityresult callback
769 param.requestCode = dummyRequestCode_;
770 param.forResultOption = true;
771 dummyRequestCode_ = (dummyRequestCode_ < INT32_MAX) ? (dummyRequestCode_ + 1) : 0;
772 HILOG_INFO("%{public}s, reqCode=%{public}d forResultOption=%{public}d.",
773 __func__,
774 param.requestCode,
775 param.forResultOption);
776
777 // unwrap the param : want object
778 if (!InnerUnwrapWant(env, args, param.want)) {
779 HILOG_ERROR("Failed to InnerUnwrapWant");
780 return nullptr;
781 }
782
783 // unwrap the param : abilityStartSetting (optional)
784 napi_value jsSettingObj = GetPropertyValueByPropertyName(env, args, "abilityStartSettings", napi_object);
785 if (jsSettingObj == nullptr) {
786 jsSettingObj = GetPropertyValueByPropertyName(env, args, "abilityStartSetting", napi_object);
787 }
788 if (jsSettingObj != nullptr) {
789 param.setting = AbilityStartSetting::GetEmptySetting();
790 if (!UnwrapAbilityStartSetting(env, jsSettingObj, *(param.setting))) {
791 HILOG_ERROR("%{public}s, unwrap abilityStartSetting failed.", __func__);
792 }
793 HILOG_INFO("%{public}s abilityStartSetting", __func__);
794 }
795
796 napi_value result;
797 NAPI_CALL(env, napi_create_int32(env, 1, &result));
798 HILOG_INFO("%{public}s,end", __func__);
799 return result;
800 }
801
802 /**
803 * @brief Parse the abilityResult parameters.
804 *
805 * @param param Indicates the want parameters saved the parse result.
806 * @param env The environment that the Node-API call is invoked under.
807 * @param args Indicates the arguments passed into the callback.
808 *
809 * @return The return value from NAPI C++ to JS for the module.
810 */
UnwrapAbilityResult(CallAbilityParam & param,napi_env env,napi_value args)811 napi_value UnwrapAbilityResult(CallAbilityParam ¶m, napi_env env, napi_value args)
812 {
813 HILOG_INFO("%{public}s,called", __func__);
814 // unwrap the param
815 napi_valuetype valueType = napi_undefined;
816 NAPI_CALL(env, napi_typeof(env, args, &valueType));
817 NAPI_ASSERT(env, valueType == napi_object, "param type mismatch!");
818 // get resultCode property
819 napi_value property = nullptr;
820 NAPI_CALL(env, napi_get_named_property(env, args, "resultCode", &property));
821 NAPI_CALL(env, napi_typeof(env, property, &valueType));
822 NAPI_ASSERT(env, valueType == napi_number, "property type mismatch!");
823 NAPI_CALL(env, napi_get_value_int32(env, property, ¶m.requestCode));
824 HILOG_INFO("%{public}s, requestCode=%{public}d.", __func__, param.requestCode);
825
826 // unwrap the param : want object
827 InnerUnwrapWant(env, args, param.want);
828
829 napi_value result;
830 NAPI_CALL(env, napi_create_int32(env, 1, &result));
831 HILOG_INFO("%{public}s,end", __func__);
832 return result;
833 }
834
835 /**
836 * @brief GetWantSyncWrap processing function.
837 *
838 * @param env The environment that the Node-API call is invoked under.
839 * @param CallingBundleCB Process data asynchronously.
840 *
841 * @return Return JS data successfully, otherwise return nullptr.
842 */
GetWantSyncWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)843 napi_value GetWantSyncWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
844 {
845 HILOG_INFO("%{public}s, called.", __func__);
846 if (asyncCallbackInfo == nullptr) {
847 HILOG_ERROR("%{public}s, asyncCallbackInfo == nullptr.", __func__);
848 return nullptr;
849 }
850
851 asyncCallbackInfo->errCode = NAPI_ERR_NO_ERROR;
852 if (asyncCallbackInfo->ability == nullptr) {
853 HILOG_ERROR("%{public}s, ability == nullptr", __func__);
854 asyncCallbackInfo->errCode = NAPI_ERR_ACE_ABILITY;
855 return nullptr;
856 }
857
858 std::shared_ptr<AAFwk::Want> ptrWant = asyncCallbackInfo->ability->GetWant();
859 if (ptrWant != nullptr) {
860 asyncCallbackInfo->param.want = *ptrWant;
861 } else {
862 asyncCallbackInfo->errCode = NAPI_ERR_ABILITY_CALL_INVALID;
863 }
864
865 napi_value result = nullptr;
866 if (asyncCallbackInfo->errCode == NAPI_ERR_NO_ERROR) {
867 result = WrapWant(env, asyncCallbackInfo->param.want);
868 } else {
869 result = WrapVoidToJS(env);
870 }
871 HILOG_INFO("%{public}s, end.", __func__);
872 return result;
873 }
874
875 /**
876 * @brief Get want(Sync).
877 *
878 * @param env The environment that the Node-API call is invoked under.
879 * @param info The callback info passed into the callback function.
880 *
881 * @return The return value from NAPI C++ to JS for the module.
882 */
NAPI_GetWantSync(napi_env env,napi_callback_info info)883 napi_value NAPI_GetWantSync(napi_env env, napi_callback_info info)
884 {
885 HILOG_INFO("%{public}s called.", __func__);
886 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
887 if (asyncCallbackInfo == nullptr) {
888 return WrapVoidToJS(env);
889 }
890
891 asyncCallbackInfo->errCode = NAPI_ERR_NO_ERROR;
892 napi_value ret = GetWantSyncWrap(env, info, asyncCallbackInfo);
893
894 delete asyncCallbackInfo;
895 asyncCallbackInfo = nullptr;
896
897 if (ret == nullptr) {
898 ret = WrapVoidToJS(env);
899 HILOG_ERROR("%{public}s ret == null", __func__);
900 } else {
901 HILOG_INFO("%{public}s, exit.", __func__);
902 }
903 return ret;
904 }
905
906 /**
907 * @brief Obtains the type of this application.
908 *
909 * @param env The environment that the Node-API call is invoked under.
910 * @param info The callback info passed into the callback function.
911 *
912 * @return The return value from NAPI C++ to JS for the module.
913 */
NAPI_GetAppType(napi_env env,napi_callback_info info)914 napi_value NAPI_GetAppType(napi_env env, napi_callback_info info)
915 {
916 HILOG_INFO("%{public}s called.", __func__);
917 return NAPI_GetAppTypeCommon(env, info, AbilityType::PAGE);
918 }
919
920 /**
921 * @brief Obtains the class name in this ability name, without the prefixed bundle name.
922 *
923 * @param env The environment that the Node-API call is invoked under.
924 * @param info The callback info passed into the callback function.
925 *
926 * @return The return value from NAPI C++ to JS for the module.
927 */
NAPI_GetAbilityName(napi_env env,napi_callback_info info)928 napi_value NAPI_GetAbilityName(napi_env env, napi_callback_info info)
929 {
930 HILOG_INFO("%{public}s called.", __func__);
931 return NAPI_GetAbilityNameCommon(env, info, AbilityType::PAGE);
932 }
933
934 /**
935 * @brief Obtains information about the current ability.
936 *
937 * @param env The environment that the Node-API call is invoked under.
938 * @param info The callback info passed into the callback function.
939 *
940 * @return The return value from NAPI C++ to JS for the module.
941 */
NAPI_GetAbilityInfo(napi_env env,napi_callback_info info)942 napi_value NAPI_GetAbilityInfo(napi_env env, napi_callback_info info)
943 {
944 HILOG_INFO("%{public}s called.", __func__);
945 return NAPI_GetAbilityInfoCommon(env, info, AbilityType::PAGE);
946 }
947
948 /**
949 * @brief Obtains the HapModuleInfo object of the application.
950 *
951 * @param env The environment that the Node-API call is invoked under.
952 * @param info The callback info passed into the callback function.
953 *
954 * @return The return value from NAPI C++ to JS for the module.
955 */
NAPI_GetHapModuleInfo(napi_env env,napi_callback_info info)956 napi_value NAPI_GetHapModuleInfo(napi_env env, napi_callback_info info)
957 {
958 HILOG_INFO("%{public}s called.", __func__);
959 return NAPI_GetHapModuleInfoCommon(env, info, AbilityType::PAGE);
960 }
961
962 /**
963 * @brief FeatureAbility NAPI method : getDataAbilityHelper.
964 *
965 * @param env The environment that the Node-API call is invoked under.
966 * @param info The callback info passed into the callback function.
967 *
968 * @return The return value from NAPI C++ to JS for the module.
969 */
NAPI_GetDataAbilityHelper(napi_env env,napi_callback_info info)970 napi_value NAPI_GetDataAbilityHelper(napi_env env, napi_callback_info info)
971 {
972 HILOG_INFO("%{public}s,called", __func__);
973 DataAbilityHelperCB *dataAbilityHelperCB = new (std::nothrow) DataAbilityHelperCB;
974 if (dataAbilityHelperCB == nullptr) {
975 HILOG_ERROR("%{public}s, dataAbilityHelperCB == nullptr", __func__);
976 return WrapVoidToJS(env);
977 }
978 dataAbilityHelperCB->cbBase.cbInfo.env = env;
979 napi_value ret = GetDataAbilityHelperWrap(env, info, dataAbilityHelperCB);
980 if (ret == nullptr) {
981 HILOG_ERROR("%{public}s, ret == nullptr", __func__);
982 if (dataAbilityHelperCB != nullptr) {
983 delete dataAbilityHelperCB;
984 dataAbilityHelperCB = nullptr;
985 }
986 ret = WrapVoidToJS(env);
987 }
988 HILOG_INFO("%{public}s,end", __func__);
989 return ret;
990 }
991
992 /**
993 * @brief getDataAbilityHelper processing function.
994 *
995 * @param env The environment that the Node-API call is invoked under.
996 * @param dataAbilityHelperCB Process data asynchronously.
997 *
998 * @return Return JS data successfully, otherwise return nullptr.
999 */
GetDataAbilityHelperWrap(napi_env env,napi_callback_info info,DataAbilityHelperCB * dataAbilityHelperCB)1000 napi_value GetDataAbilityHelperWrap(napi_env env, napi_callback_info info, DataAbilityHelperCB *dataAbilityHelperCB)
1001 {
1002 HILOG_INFO("%{public}s,called", __func__);
1003 if (dataAbilityHelperCB == nullptr) {
1004 HILOG_ERROR("%{public}s,dataAbilityHelperCB == nullptr", __func__);
1005 return nullptr;
1006 }
1007
1008 size_t argcAsync = 2;
1009 const size_t argcPromise = 1;
1010 const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1011 napi_value args[ARGS_MAX_COUNT] = {nullptr};
1012 napi_value ret = nullptr;
1013
1014 NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
1015 if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1016 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1017 return nullptr;
1018 }
1019
1020 napi_valuetype valuetype = napi_undefined;
1021 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1022 if (valuetype == napi_string) {
1023 NAPI_CALL(env, napi_create_reference(env, args[PARAM0], 1, &dataAbilityHelperCB->uri));
1024 }
1025
1026 if (argcAsync > argcPromise) {
1027 ret = GetDataAbilityHelperAsync(env, args, 1, dataAbilityHelperCB);
1028 } else {
1029 ret = GetDataAbilityHelperPromise(env, dataAbilityHelperCB);
1030 }
1031 HILOG_INFO("%{public}s,end", __func__);
1032 return ret;
1033 }
1034
GetDataAbilityHelperAsync(napi_env env,napi_value * args,const size_t argCallback,DataAbilityHelperCB * dataAbilityHelperCB)1035 napi_value GetDataAbilityHelperAsync(
1036 napi_env env, napi_value *args, const size_t argCallback, DataAbilityHelperCB *dataAbilityHelperCB)
1037 {
1038 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1039 if (args == nullptr || dataAbilityHelperCB == nullptr) {
1040 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1041 return nullptr;
1042 }
1043 napi_value resourceName = nullptr;
1044 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1045
1046 napi_valuetype valuetype = napi_undefined;
1047 NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1048 if (valuetype == napi_function) {
1049 NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &dataAbilityHelperCB->cbBase.cbInfo.callback));
1050 }
1051
1052 NAPI_CALL(env,
1053 napi_create_async_work(env, nullptr, resourceName,
1054 [](napi_env env, void *data) { HILOG_INFO("NAPI_GetDataAbilityHelper, worker pool thread execute."); },
1055 GetDataAbilityHelperAsyncCompleteCB,
1056 static_cast<void *>(dataAbilityHelperCB),
1057 &dataAbilityHelperCB->cbBase.asyncWork));
1058 NAPI_CALL(env, napi_queue_async_work_with_qos(env, dataAbilityHelperCB->cbBase.asyncWork,
1059 napi_qos_user_initiated));
1060 napi_value result = nullptr;
1061 NAPI_CALL(env, napi_get_null(env, &result));
1062 HILOG_INFO("%{public}s, asyncCallback end", __func__);
1063 return result;
1064 }
1065
GetDataAbilityHelperPromise(napi_env env,DataAbilityHelperCB * dataAbilityHelperCB)1066 napi_value GetDataAbilityHelperPromise(napi_env env, DataAbilityHelperCB *dataAbilityHelperCB)
1067 {
1068 HILOG_INFO("%{public}s, promise.", __func__);
1069 if (dataAbilityHelperCB == nullptr) {
1070 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1071 return nullptr;
1072 }
1073 napi_value resourceName;
1074 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1075 napi_deferred deferred;
1076 napi_value promise = nullptr;
1077 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1078 dataAbilityHelperCB->cbBase.deferred = deferred;
1079
1080 NAPI_CALL(env,
1081 napi_create_async_work(env, nullptr, resourceName,
1082 [](napi_env env, void *data) { HILOG_INFO("NAPI_GetDataAbilityHelper, worker pool thread execute."); },
1083 GetDataAbilityHelperPromiseCompleteCB,
1084 static_cast<void *>(dataAbilityHelperCB),
1085 &dataAbilityHelperCB->cbBase.asyncWork));
1086 NAPI_CALL(env, napi_queue_async_work_with_qos(env, dataAbilityHelperCB->cbBase.asyncWork,
1087 napi_qos_user_initiated));
1088 HILOG_INFO("%{public}s, promise end.", __func__);
1089 return promise;
1090 }
1091
GetDataAbilityHelperAsyncCompleteCB(napi_env env,napi_status status,void * data)1092 void GetDataAbilityHelperAsyncCompleteCB(napi_env env, napi_status status, void *data)
1093 {
1094 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete.");
1095 DataAbilityHelperCB *dataAbilityHelperCB = static_cast<DataAbilityHelperCB *>(data);
1096 if (dataAbilityHelperCB == nullptr) {
1097 HILOG_ERROR("GetDataAbilityHelperAsyncCompleteCB, dataAbilityHelperCB is nullptr");
1098 return;
1099 }
1100
1101 std::unique_ptr<DataAbilityHelperCB> callbackPtr {dataAbilityHelperCB};
1102 napi_value uri = nullptr;
1103 napi_value callback = nullptr;
1104 napi_value undefined = nullptr;
1105 napi_value result[ARGS_TWO] = {nullptr};
1106 napi_value callResult = nullptr;
1107 napi_get_undefined(env, &undefined);
1108 napi_get_reference_value(env, dataAbilityHelperCB->uri, &uri);
1109 napi_get_reference_value(env, dataAbilityHelperCB->cbBase.cbInfo.callback, &callback);
1110 napi_new_instance(env, GetGlobalDataAbilityHelper(env), 1, &uri, &dataAbilityHelperCB->result);
1111 if (IsTypeForNapiValue(env, dataAbilityHelperCB->result, napi_object)) {
1112 result[PARAM1] = dataAbilityHelperCB->result;
1113 } else {
1114 HILOG_INFO("NAPI_GetDataAbilityHelper, helper is nullptr.");
1115 result[PARAM1] = WrapVoidToJS(env);
1116 }
1117 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
1118 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
1119 if (dataAbilityHelperCB->cbBase.cbInfo.callback != nullptr) {
1120 napi_delete_reference(env, dataAbilityHelperCB->cbBase.cbInfo.callback);
1121 }
1122 if (dataAbilityHelperCB->uri != nullptr) {
1123 napi_delete_reference(env, dataAbilityHelperCB->uri);
1124 }
1125 napi_delete_async_work(env, dataAbilityHelperCB->cbBase.asyncWork);
1126 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete end.");
1127 }
1128
GetDataAbilityHelperPromiseCompleteCB(napi_env env,napi_status status,void * data)1129 void GetDataAbilityHelperPromiseCompleteCB(napi_env env, napi_status status, void *data)
1130 {
1131 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete.");
1132 DataAbilityHelperCB *dataAbilityHelperCB = static_cast<DataAbilityHelperCB *>(data);
1133 if (dataAbilityHelperCB == nullptr) {
1134 HILOG_INFO("GetDataAbilityHelperPromiseCompleteCB, dataAbilityHelperCB is nullptr.");
1135 return;
1136 }
1137
1138 napi_value uri = nullptr;
1139 napi_value result = nullptr;
1140 napi_get_reference_value(env, dataAbilityHelperCB->uri, &uri);
1141 napi_new_instance(env, GetGlobalDataAbilityHelper(env), 1, &uri, &dataAbilityHelperCB->result);
1142 if (IsTypeForNapiValue(env, dataAbilityHelperCB->result, napi_object)) {
1143 result = dataAbilityHelperCB->result;
1144 napi_resolve_deferred(env, dataAbilityHelperCB->cbBase.deferred, result);
1145 } else {
1146 result = GetCallbackErrorValue(env, dataAbilityHelperCB->cbBase.errCode);
1147 napi_reject_deferred(env, dataAbilityHelperCB->cbBase.deferred, result);
1148 HILOG_INFO("NAPI_GetDataAbilityHelper, helper is nullptr.");
1149 }
1150
1151 if (dataAbilityHelperCB->uri != nullptr) {
1152 napi_delete_reference(env, dataAbilityHelperCB->uri);
1153 }
1154 napi_delete_async_work(env, dataAbilityHelperCB->cbBase.asyncWork);
1155 HILOG_INFO("NAPI_GetDataAbilityHelper, main event thread complete end.");
1156 }
1157
1158 /**
1159 * @brief FeatureAbility NAPI method : acquireDataAbilityHelper.
1160 *
1161 * @param env The environment that the Node-API call is invoked under.
1162 * @param info The callback info passed into the callback function.
1163 *
1164 * @return The return value from NAPI C++ to JS for the module.
1165 */
NAPI_AcquireDataAbilityHelper(napi_env env,napi_callback_info info)1166 napi_value NAPI_AcquireDataAbilityHelper(napi_env env, napi_callback_info info)
1167 {
1168 return NAPI_AcquireDataAbilityHelperCommon(env, info, AbilityType::PAGE);
1169 }
1170
1171 /**
1172 * @brief FeatureAbility NAPI method : continueAbility.
1173 *
1174 * @param env The environment that the Node-API call is invoked under.
1175 * @param info The callback info passed into the callback function.
1176 *
1177 * @return The return value from NAPI C++ to JS for the module.
1178 */
NAPI_FAContinueAbility(napi_env env,napi_callback_info info)1179 napi_value NAPI_FAContinueAbility(napi_env env, napi_callback_info info)
1180 {
1181 HILOG_INFO("%{public}s,called", __func__);
1182 AsyncCallbackInfo *asyncCallbackInfo = CreateAsyncCallbackInfo(env);
1183 if (asyncCallbackInfo == nullptr) {
1184 HILOG_ERROR("%{public}s, asyncCallbackInfo == nullptr.", __func__);
1185 return WrapVoidToJS(env);
1186 }
1187
1188 napi_value ret = ContinueAbilityWrap(env, info, asyncCallbackInfo);
1189 if (ret == nullptr) {
1190 if (asyncCallbackInfo != nullptr) {
1191 delete asyncCallbackInfo;
1192 asyncCallbackInfo = nullptr;
1193 }
1194 ret = WrapVoidToJS(env);
1195 }
1196 HILOG_INFO("%{public}s,end.", __func__);
1197 return ret;
1198 }
1199
1200 /**
1201 * @brief ContinueAbilityWrap processing function.
1202 *
1203 * @param env The environment that the Node-API call is invoked under.
1204 * @param asyncCallbackInfo Process data asynchronously.
1205 *
1206 * @return Return JS data successfully, otherwise return nullptr.
1207 */
ContinueAbilityWrap(napi_env env,napi_callback_info info,AsyncCallbackInfo * asyncCallbackInfo)1208 napi_value ContinueAbilityWrap(napi_env env, napi_callback_info info, AsyncCallbackInfo *asyncCallbackInfo)
1209 {
1210 HILOG_INFO("%{public}s, called.", __func__);
1211 size_t argc = 2;
1212 napi_value args[ARGS_MAX_COUNT] = {nullptr};
1213 napi_value ret = nullptr;
1214 napi_valuetype valueType = napi_undefined;
1215
1216 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1217 NAPI_CALL(env, napi_typeof(env, args[0], &valueType));
1218 if (valueType != napi_object && valueType != napi_function) {
1219 HILOG_ERROR("%{public}s, Wrong argument type. Object or function expected.", __func__);
1220 return nullptr;
1221 }
1222 if (argc == 0) {
1223 ret = ContinueAbilityPromise(env, args, asyncCallbackInfo, argc);
1224 } else if (PARA_SIZE_IS_ONE == argc) {
1225 if (valueType == napi_function) {
1226 ret = ContinueAbilityAsync(env, args, asyncCallbackInfo, argc);
1227 } else {
1228 ret = ContinueAbilityPromise(env, args, asyncCallbackInfo, argc);
1229 }
1230 } else if (PARA_SIZE_IS_TWO == argc) {
1231 napi_valuetype value = napi_undefined;
1232 NAPI_CALL(env, napi_typeof(env, args[1], &value));
1233 if (value != napi_function) {
1234 HILOG_ERROR("%{public}s, Wrong argument type. function expected.", __func__);
1235 return nullptr;
1236 }
1237 ret = ContinueAbilityAsync(env, args, asyncCallbackInfo, argc);
1238 } else {
1239 HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1240 }
1241 HILOG_INFO("%{public}s,end.", __func__);
1242 return ret;
1243 }
1244
ContinueAbilityAsync(napi_env env,napi_value * args,AsyncCallbackInfo * asyncCallbackInfo,size_t argc)1245 napi_value ContinueAbilityAsync(napi_env env, napi_value *args, AsyncCallbackInfo *asyncCallbackInfo, size_t argc)
1246 {
1247 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1248 if (args == nullptr || asyncCallbackInfo == nullptr) {
1249 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1250 return nullptr;
1251 }
1252 napi_value resourceName = nullptr;
1253 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1254
1255 if (PARA_SIZE_IS_TWO == argc) {
1256 // args[0] : ContinueAbilityOptions
1257 napi_valuetype valueTypeOptions = napi_undefined;
1258 NAPI_CALL(env, napi_typeof(env, args[0], &valueTypeOptions));
1259 if (valueTypeOptions != napi_object) {
1260 HILOG_ERROR("%{public}s, Wrong argument type. Object expected.", __func__);
1261 return nullptr;
1262 }
1263 if (GetContinueAbilityOptionsInfoCommon(env, args[0], asyncCallbackInfo->optionInfo) == nullptr) {
1264 HILOG_ERROR("%{public}s, GetContinueAbilityOptionsInfoCommonFail", __func__);
1265 return nullptr;
1266 }
1267
1268 // args[1] : callback
1269 napi_valuetype valueTypeCallBack = napi_undefined;
1270 napi_typeof(env, args[1], &valueTypeCallBack);
1271 if (valueTypeCallBack == napi_function) {
1272 napi_create_reference(env, args[1], 1, &asyncCallbackInfo->cbInfo.callback);
1273 }
1274 } else {
1275 // args[0] : callback
1276 napi_valuetype valueTypeCallBack = napi_undefined;
1277 napi_typeof(env, args[1], &valueTypeCallBack);
1278 if (valueTypeCallBack == napi_function) {
1279 napi_create_reference(env, args[0], 1, &asyncCallbackInfo->cbInfo.callback);
1280 }
1281 }
1282
1283 napi_create_async_work(env, nullptr, resourceName,
1284 [](napi_env env, void *data) {
1285 HILOG_INFO("NAPI_ContinueAbility, worker pool thread execute.");
1286 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
1287 if (asyncCallbackInfo == nullptr) {
1288 HILOG_ERROR("NAPI_ContinueAbility, asyncCallbackInfo is nullptr.");
1289 return;
1290 }
1291
1292 if (asyncCallbackInfo->ability != nullptr) {
1293 asyncCallbackInfo->ability->ContinueAbility(asyncCallbackInfo->optionInfo.deviceId);
1294 } else {
1295 HILOG_ERROR("NAPI_ContinueAbilityForResult, asyncCallbackInfo == nullptr.");
1296 }
1297 HILOG_INFO("NAPI_ContinueAbilityForResult, worker pool thread execute exit.");
1298 },
1299 [](napi_env env, napi_status status, void *data) {
1300 HILOG_INFO("NAPI_ContinueAbility, main event thread end.");
1301 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
1302 if (asyncCallbackInfo == nullptr) {
1303 HILOG_ERROR("NAPI_ContinueAbility complete, asyncCallbackInfo is nullptr.");
1304 return;
1305 }
1306 napi_value callback = nullptr;
1307 napi_value undefined = nullptr;
1308 napi_value result[ARGS_TWO] = {nullptr};
1309 napi_value callResult = nullptr;
1310 napi_get_undefined(env, &undefined);
1311 result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
1312 napi_get_null(env, &result[PARAM1]);
1313 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
1314 napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
1315
1316 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
1317 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
1318 }
1319 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1320 delete asyncCallbackInfo;
1321 HILOG_INFO("NAPI_ContinueAbilityForResult, main event thread complete end.");
1322 },
1323 static_cast<void *>(asyncCallbackInfo),
1324 &asyncCallbackInfo->asyncWork);
1325 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1326 napi_value result = nullptr;
1327 napi_get_null(env, &result);
1328 HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1329 return result;
1330 }
1331
ContinueAbilityPromise(napi_env env,napi_value * args,AsyncCallbackInfo * asyncCallbackInfo,size_t argc)1332 napi_value ContinueAbilityPromise(napi_env env, napi_value *args, AsyncCallbackInfo *asyncCallbackInfo, size_t argc)
1333 {
1334 HILOG_INFO("%{public}s, promise.", __func__);
1335 if (asyncCallbackInfo == nullptr) {
1336 HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1337 return nullptr;
1338 }
1339
1340 if (argc == PARA_SIZE_IS_ONE) {
1341 // args[0] : ContinueAbilityOptions
1342 napi_valuetype valueTypeOptions = napi_undefined;
1343 NAPI_CALL(env, napi_typeof(env, args[0], &valueTypeOptions));
1344 if (valueTypeOptions != napi_object) {
1345 HILOG_ERROR("%{public}s, Wrong argument type. Object expected.", __func__);
1346 return nullptr;
1347 }
1348 if (GetContinueAbilityOptionsInfoCommon(env, args[0], asyncCallbackInfo->optionInfo) == nullptr) {
1349 return nullptr;
1350 }
1351 }
1352
1353 napi_value resourceName = nullptr;
1354 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1355 napi_deferred deferred;
1356 napi_value promise = nullptr;
1357 napi_create_promise(env, &deferred, &promise);
1358
1359 asyncCallbackInfo->deferred = deferred;
1360
1361 napi_create_async_work(env, nullptr, resourceName,
1362 [](napi_env env, void *data) {
1363 HILOG_INFO("NAPI_ContinueAbility, worker pool thread execute.");
1364 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
1365 if (asyncCallbackInfo == nullptr) {
1366 HILOG_ERROR("NAPI_ContinueAbility, worker pool thread execute asyncCallbackInfo is nullptr.");
1367 return;
1368 }
1369 if (asyncCallbackInfo->ability != nullptr) {
1370 asyncCallbackInfo->ability->ContinueAbility(asyncCallbackInfo->optionInfo.deviceId);
1371 } else {
1372 HILOG_ERROR("NAPI_ContinueAbilityForResult, asyncCallbackInfo == nullptr");
1373 }
1374 HILOG_INFO("NAPI_ContinueAbilityForResult, worker pool thread execute end.");
1375 },
1376 [](napi_env env, napi_status status, void *data) {
1377 HILOG_INFO("NAPI_ContinueAbility, main event thread complete.");
1378 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
1379 if (asyncCallbackInfo == nullptr) {
1380 HILOG_ERROR("NAPI_ContinueAbility, main event thread complete asyncCallbackInfo is nullptr.");
1381 return;
1382 }
1383 napi_value result = nullptr;
1384 napi_get_null(env, &result);
1385 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
1386 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1387 delete asyncCallbackInfo;
1388 HILOG_INFO("NAPI_ContinueAbilityForResult, main event thread complete end.");
1389 },
1390 static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
1391 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1392 HILOG_INFO("%{public}s, promise end.", __func__);
1393 return promise;
1394 }
1395 } // namespace AppExecFwk
1396 } // namespace OHOS
1397