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