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