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