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