1 /*
2 * Copyright (c) 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
16 #include "js_feature_ability.h"
17
18 #include "distribute_constants.h"
19 #include "distribute_req_param.h"
20 #include "js_runtime_utils.h"
21 #include "hilog_wrapper.h"
22 #include "napi_common_util.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 using namespace OHOS::AppExecFwk;
27 const std::string RESULT_DATA_TAG = "resultData";
28
Finalizer(NativeEngine * engine,void * data,void * hint)29 void JsFeatureAbility::Finalizer(NativeEngine* engine, void* data, void* hint)
30 {
31 HILOG_INFO("JsFeatureAbility::Finalizer is called");
32 std::unique_ptr<JsFeatureAbility>(static_cast<JsFeatureAbility*>(data));
33 }
34
StartAbility(NativeEngine * engine,NativeCallbackInfo * info)35 NativeValue* JsFeatureAbility::StartAbility(NativeEngine* engine, NativeCallbackInfo* info)
36 {
37 JsFeatureAbility* me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
38 return (me != nullptr) ? me->OnStartAbility(*engine, *info) : nullptr;
39 }
40
StartAbilityForResult(NativeEngine * engine,NativeCallbackInfo * info)41 NativeValue* JsFeatureAbility::StartAbilityForResult(NativeEngine* engine, NativeCallbackInfo* info)
42 {
43 JsFeatureAbility* me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
44 return (me != nullptr) ? me->OnStartAbilityForResult(*engine, *info) : nullptr;
45 }
46
FinishWithResult(NativeEngine * engine,NativeCallbackInfo * info)47 NativeValue *JsFeatureAbility::FinishWithResult(NativeEngine *engine, NativeCallbackInfo *info)
48 {
49 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
50 return (me != nullptr) ? me->OnFinishWithResult(*engine, *info) : nullptr;
51 }
52
GetDeviceList(NativeEngine * engine,NativeCallbackInfo * info)53 NativeValue *JsFeatureAbility::GetDeviceList(NativeEngine *engine, NativeCallbackInfo *info)
54 {
55 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
56 return (me != nullptr) ? me->OnGetDeviceList(*engine, *info) : nullptr;
57 }
58
CallAbility(NativeEngine * engine,NativeCallbackInfo * info)59 NativeValue *JsFeatureAbility::CallAbility(NativeEngine *engine, NativeCallbackInfo *info)
60 {
61 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
62 return (me != nullptr) ? me->OnCallAbility(*engine, *info) : nullptr;
63 }
64
ContinueAbility(NativeEngine * engine,NativeCallbackInfo * info)65 NativeValue *JsFeatureAbility::ContinueAbility(NativeEngine *engine, NativeCallbackInfo *info)
66 {
67 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
68 return (me != nullptr) ? me->OnContinueAbility(*engine, *info) : nullptr;
69 }
70
SubscribeAbilityEvent(NativeEngine * engine,NativeCallbackInfo * info)71 NativeValue *JsFeatureAbility::SubscribeAbilityEvent(NativeEngine *engine, NativeCallbackInfo *info)
72 {
73 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
74 return (me != nullptr) ? me->OnSubscribeAbilityEvent(*engine, *info) : nullptr;
75 }
76
UnsubscribeAbilityEvent(NativeEngine * engine,NativeCallbackInfo * info)77 NativeValue *JsFeatureAbility::UnsubscribeAbilityEvent(NativeEngine *engine, NativeCallbackInfo *info)
78 {
79 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
80 return (me != nullptr) ? me->OnUnsubscribeAbilityEvent(*engine, *info) : nullptr;
81 }
82
SendMsg(NativeEngine * engine,NativeCallbackInfo * info)83 NativeValue *JsFeatureAbility::SendMsg(NativeEngine *engine, NativeCallbackInfo *info)
84 {
85 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
86 return (me != nullptr) ? me->OnSendMsg(*engine, *info) : nullptr;
87 }
88
SubscribeMsg(NativeEngine * engine,NativeCallbackInfo * info)89 NativeValue *JsFeatureAbility::SubscribeMsg(NativeEngine *engine, NativeCallbackInfo *info)
90 {
91 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
92 return (me != nullptr) ? me->OnSubscribeMsg(*engine, *info) : nullptr;
93 }
94
UnsubscribeMsg(NativeEngine * engine,NativeCallbackInfo * info)95 NativeValue *JsFeatureAbility::UnsubscribeMsg(NativeEngine *engine, NativeCallbackInfo *info)
96 {
97 JsFeatureAbility *me = CheckParamsAndGetThis<JsFeatureAbility>(engine, info);
98 return (me != nullptr) ? me->OnUnsubscribeMsg(*engine, *info) : nullptr;
99 }
100
OnStartAbility(NativeEngine & engine,NativeCallbackInfo & info)101 NativeValue* JsFeatureAbility::OnStartAbility(NativeEngine &engine, NativeCallbackInfo &info)
102 {
103 HILOG_INFO("%{public}s is called", __FUNCTION__);
104 if (info.argc != 1) {
105 HILOG_ERROR("Params not match");
106 return engine.CreateUndefined();
107 }
108
109 Ability* ability = GetAbility(reinterpret_cast<napi_env>(&engine));
110 if (ability == nullptr) {
111 HILOG_ERROR("ability is nullptr");
112 return engine.CreateUndefined();
113 }
114
115 DistributeReqParam requestParam;
116 if (!UnWrapRequestParams(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]),
117 requestParam)) {
118 HILOG_ERROR("unwrap request params failed");
119 return engine.CreateUndefined();
120 }
121
122 Want want = GetWant(requestParam);
123 AsyncTask::CompleteCallback complete =
124 [want, ability](NativeEngine &engine, AsyncTask &task, int32_t status) {
125 auto errcode = ability->StartAbility(want);
126 task.Resolve(engine, JsFeatureAbility::CreateJsResult(engine, errcode, "Start Ability failed."));
127 };
128
129 NativeValue* result = nullptr;
130 AsyncTask::Schedule("JSFeatureAbility::OnStartAbility",
131 engine, CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, std::move(complete), &result));
132 return result;
133 }
134
OnStartAbilityForResult(NativeEngine & engine,NativeCallbackInfo & info)135 NativeValue* JsFeatureAbility::OnStartAbilityForResult(NativeEngine &engine, NativeCallbackInfo &info)
136 {
137 HILOG_INFO("%{public}s is called", __FUNCTION__);
138 if (info.argc != 1) {
139 HILOG_ERROR("Params not match");
140 return engine.CreateUndefined();
141 }
142 Ability* ability = GetAbility(reinterpret_cast<napi_env>(&engine));
143 if (ability == nullptr) {
144 HILOG_ERROR("ability is nullptr");
145 return engine.CreateUndefined();
146 }
147
148 DistributeReqParam requestParam;
149 if (!UnWrapRequestParams(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]),
150 requestParam)) {
151 HILOG_ERROR("unwrap request params failed");
152 return engine.CreateUndefined();
153 }
154
155 Want want = GetWant(requestParam);
156 NativeValue* result = nullptr;
157 std::unique_ptr<AsyncTask> uasyncTask =
158 CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, nullptr, &result);
159
160 std::shared_ptr<AsyncTask> asyncTask = std::move(uasyncTask);
161 FeatureAbilityTask task = [&engine, asyncTask](int resultCode, const AAFwk::Want& want) {
162 HILOG_INFO("OnStartAbilityForResult async callback is called");
163 std::string data = want.GetStringParam(RESULT_DATA_TAG);
164 NativeValue* abilityResult = JsFeatureAbility::CreateJsResult(engine, resultCode, data);
165 if (abilityResult == nullptr) {
166 HILOG_WARN("wrap abilityResult failed");
167 asyncTask->Reject(engine, CreateJsError(engine, 1, "failed to get result data!"));
168 } else {
169 asyncTask->Resolve(engine, abilityResult);
170 }
171 HILOG_INFO("OnStartAbilityForResult async callback is called end");
172 };
173
174 want.SetParam(Want::PARAM_RESV_FOR_RESULT, true);
175 requestCode_ = (requestCode_ == INT_MAX) ? 0 : (requestCode_ + 1);
176 ability->StartFeatureAbilityForResult(want, requestCode_, std::move(task));
177
178 HILOG_INFO("OnStartAbilityForResult is called end");
179 return result;
180 }
181
OnFinishWithResult(NativeEngine & engine,NativeCallbackInfo & info)182 NativeValue *JsFeatureAbility::OnFinishWithResult(NativeEngine &engine, NativeCallbackInfo &info)
183 {
184 HILOG_INFO("%{public}s is called", __FUNCTION__);
185 if (info.argc != 1) {
186 HILOG_ERROR("Params not match");
187 return engine.CreateUndefined();
188 }
189
190 Ability *ability = GetAbility(reinterpret_cast<napi_env>(&engine));
191 if (ability == nullptr) {
192 HILOG_ERROR("ability is nullptr");
193 return engine.CreateUndefined();
194 }
195
196 auto env = reinterpret_cast<napi_env>(&engine);
197 auto arg0 = reinterpret_cast<napi_value>(info.argv[0]);
198 if (!IsTypeForNapiValue(env, arg0, napi_object)) {
199 HILOG_ERROR("Params is invalid.");
200 return engine.CreateUndefined();
201 }
202
203 int32_t code = ERR_OK;
204 if (!UnwrapInt32ByPropertyName(env, arg0, "code", code)) {
205 HILOG_ERROR("Failed to get code.");
206 return engine.CreateUndefined();
207 }
208
209 napi_value jsResultObj = GetPropertyValueByPropertyName(env, arg0, "result", napi_object);
210 if (jsResultObj == nullptr) {
211 HILOG_ERROR("Failed to get result.");
212 return engine.CreateUndefined();
213 }
214
215 napi_value globalValue = nullptr;
216 napi_get_global(env, &globalValue);
217 napi_value jsonValue;
218 napi_get_named_property(env, globalValue, "JSON", &jsonValue);
219 napi_value stringifyValue = nullptr;
220 napi_get_named_property(env, jsonValue, "stringify", &stringifyValue);
221 napi_value transValue = nullptr;
222 napi_call_function(env, jsonValue, stringifyValue, 1, &jsResultObj, &transValue);
223 std::string resultStr {};
224 resultStr = UnwrapStringFromJS(env, transValue, "");
225
226 HILOG_DEBUG("code: %{public}d, result:%{public}s", code, resultStr.c_str());
227 Want want;
228 want.SetParam(RESULT_DATA_TAG, resultStr);
229 ability->SetResult(code, want);
230
231 AsyncTask::CompleteCallback complete =
232 [ability](NativeEngine &engine, AsyncTask &task, int32_t status) {
233 auto errCode = ability->TerminateAbility();
234 task.Resolve(engine, JsFeatureAbility::CreateJsResult(engine, errCode, "FinishWithResult failed."));
235 };
236
237 NativeValue *result = nullptr;
238 AsyncTask::Schedule("JSFeatureAbility::OnFinishWithResult",
239 engine, CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, std::move(complete), &result));
240 return result;
241 }
242
OnGetDeviceList(NativeEngine & engine,NativeCallbackInfo & info)243 NativeValue *JsFeatureAbility::OnGetDeviceList(NativeEngine &engine, NativeCallbackInfo &info)
244 {
245 HILOG_INFO("%{public}s is called", __FUNCTION__);
246 return engine.CreateUndefined();
247 }
248
OnCallAbility(NativeEngine & engine,NativeCallbackInfo & info)249 NativeValue *JsFeatureAbility::OnCallAbility(NativeEngine &engine, NativeCallbackInfo &info)
250 {
251 HILOG_INFO("%{public}s is called", __FUNCTION__);
252 return engine.CreateUndefined();
253 }
254
OnContinueAbility(NativeEngine & engine,NativeCallbackInfo & info)255 NativeValue *JsFeatureAbility::OnContinueAbility(NativeEngine &engine, NativeCallbackInfo &info)
256 {
257 HILOG_INFO("%{public}s is called", __FUNCTION__);
258 return engine.CreateUndefined();
259 }
260
OnSubscribeAbilityEvent(NativeEngine & engine,NativeCallbackInfo & info)261 NativeValue *JsFeatureAbility::OnSubscribeAbilityEvent(NativeEngine &engine, NativeCallbackInfo &info)
262 {
263 HILOG_INFO("%{public}s is called", __FUNCTION__);
264 return engine.CreateUndefined();
265 }
266
OnUnsubscribeAbilityEvent(NativeEngine & engine,NativeCallbackInfo & info)267 NativeValue *JsFeatureAbility::OnUnsubscribeAbilityEvent(NativeEngine &engine, NativeCallbackInfo &info)
268 {
269 HILOG_INFO("%{public}s is called", __FUNCTION__);
270 return engine.CreateUndefined();
271 }
272
OnSendMsg(NativeEngine & engine,NativeCallbackInfo & info)273 NativeValue *JsFeatureAbility::OnSendMsg(NativeEngine &engine, NativeCallbackInfo &info)
274 {
275 HILOG_INFO("%{public}s is called", __FUNCTION__);
276 return engine.CreateUndefined();
277 }
278
OnSubscribeMsg(NativeEngine & engine,NativeCallbackInfo & info)279 NativeValue *JsFeatureAbility::OnSubscribeMsg(NativeEngine &engine, NativeCallbackInfo &info)
280 {
281 HILOG_INFO("%{public}s is called", __FUNCTION__);
282 return engine.CreateUndefined();
283 }
284
OnUnsubscribeMsg(NativeEngine & engine,NativeCallbackInfo & info)285 NativeValue *JsFeatureAbility::OnUnsubscribeMsg(NativeEngine &engine, NativeCallbackInfo &info)
286 {
287 HILOG_INFO("%{public}s is called", __FUNCTION__);
288 return engine.CreateUndefined();
289 }
290
GetAbility(napi_env env)291 Ability* JsFeatureAbility::GetAbility(napi_env env)
292 {
293 napi_status ret;
294 napi_value global = nullptr;
295 const napi_extended_error_info *errorInfo = nullptr;
296 ret = napi_get_global(env, &global);
297 if (ret != napi_ok) {
298 napi_get_last_error_info(env, &errorInfo);
299 HILOG_ERROR("JsFeatureAbility::GetAbility, get_global=%{public}d err:%{public}s",
300 ret, errorInfo->error_message);
301 return nullptr;
302 }
303
304 napi_value abilityObj = nullptr;
305 ret = napi_get_named_property(env, global, "ability", &abilityObj);
306 if (ret != napi_ok) {
307 napi_get_last_error_info(env, &errorInfo);
308 HILOG_ERROR("JsFeatureAbility::GetAbility, get_named_property=%{public}d err:%{public}s",
309 ret, errorInfo->error_message);
310 return nullptr;
311 }
312
313 Ability* ability = nullptr;
314 ret = napi_get_value_external(env, abilityObj, reinterpret_cast<void **>(&ability));
315 if (ret != napi_ok) {
316 napi_get_last_error_info(env, &errorInfo);
317 HILOG_ERROR("JsFeatureAbility::GetAbility, get_value_external=%{public}d err:%{public}s",
318 ret, errorInfo->error_message);
319 return nullptr;
320 }
321
322 return ability;
323 }
324
GetWant(DistributeReqParam & requestParam)325 Want JsFeatureAbility::GetWant(DistributeReqParam &requestParam)
326 {
327 Want want;
328 Uri parseUri("");
329 if (CheckThenGetDeepLinkUri(requestParam, parseUri)) {
330 want.SetUri(parseUri);
331 want.SetAction(requestParam.GetAction());
332 for (auto entity : requestParam.GetEntities()) {
333 want.AddEntity(entity);
334 }
335 if (!requestParam.GetType().empty()) {
336 want.SetType(requestParam.GetType());
337 }
338 return want;
339 }
340
341 if (requestParam.GetDeviceType() == DistributeConstants::DEVICE_TYPE_DEFAULT) {
342 want.AddFlags(want.FLAG_ABILITYSLICE_MULTI_DEVICE);
343 want.AddFlags(want.FLAG_NOT_OHOS_COMPONENT);
344 want.SetDeviceId(requestParam.GetNetworkId());
345 }
346
347 if (requestParam.GetDeviceType() == DistributeConstants::DEVICE_TYPE_LOCAL) {
348 want.AddFlags(want.FLAG_NOT_OHOS_COMPONENT);
349 }
350 want.AddFlags(requestParam.GetFlag());
351
352 if (!requestParam.GetData().empty()) {
353 want.SetParam(DistributeConstants::START_ABILITY_PARAMS_KEY, requestParam.GetData());
354 }
355
356 if (!requestParam.GetUrl().empty()) {
357 want.SetParam(DistributeConstants::START_ABILITY_URL_KEY, requestParam.GetUrl());
358 want.SetUri(Uri(requestParam.GetUrl()));
359 }
360
361 if (!requestParam.GetType().empty()) {
362 want.SetType(requestParam.GetType());
363 }
364
365 GetExtraParams(requestParam, want);
366
367 if (!requestParam.GetBundleName().empty() && !requestParam.GetAbilityName().empty()) {
368 want.SetElementName(requestParam.GetNetworkId(), requestParam.GetBundleName(),
369 requestParam.GetAbilityName(), requestParam.GetModuleName());
370 } else {
371 want.SetAction(requestParam.GetAction());
372 for (auto entity : requestParam.GetEntities()) {
373 want.AddEntity(entity);
374 }
375 }
376
377 return want;
378 }
379
GetExtraParams(DistributeReqParam & requestParam,Want & want)380 void JsFeatureAbility::GetExtraParams(DistributeReqParam &requestParam, Want &want)
381 {
382 return;
383 }
384
CheckThenGetDeepLinkUri(const DistributeReqParam & requestParam,Uri & uri)385 bool JsFeatureAbility::CheckThenGetDeepLinkUri(const DistributeReqParam &requestParam, Uri &uri)
386 {
387 std::string url = requestParam.GetUrl();
388 std::string action = requestParam.GetAction();
389 if (url.empty() || action.empty()) {
390 return false;
391 }
392
393 if (action != DistributeConstants::DEEP_LINK_ACTION_NAME) {
394 return false;
395 }
396
397 uri = Uri(url);
398 if (uri.GetScheme().empty() || uri.GetHost().empty()) {
399 return false;
400 }
401
402 return true;
403 }
404
UnWrapRequestParams(napi_env env,napi_value param,DistributeReqParam & requestParam)405 bool JsFeatureAbility::UnWrapRequestParams(napi_env env, napi_value param, DistributeReqParam &requestParam)
406 {
407 HILOG_INFO("%{public}s called.", __func__);
408
409 if (!IsTypeForNapiValue(env, param, napi_object)) {
410 HILOG_INFO("%{public}s called. Params is invalid.", __func__);
411 return false;
412 }
413
414 std::string bundleName;
415 if (UnwrapStringByPropertyName(env, param, "bundleName", bundleName)) {
416 requestParam.SetBundleName(bundleName);
417 }
418
419 std::string abilityName;
420 if (UnwrapStringByPropertyName(env, param, "abilityName", abilityName)) {
421 requestParam.SetAbilityName(abilityName);
422 }
423
424 std::vector<std::string> entities;
425 if (UnwrapStringArrayByPropertyName(env, param, "entities", entities)) {
426 requestParam.SetEntities(entities);
427 }
428
429 std::string action;
430 if (UnwrapStringByPropertyName(env, param, "action", action)) {
431 requestParam.SetAction(action);
432 }
433
434 std::string networkId;
435 if (UnwrapStringByPropertyName(env, param, "networkId", networkId)) {
436 requestParam.SetNetWorkId(networkId);
437 }
438
439 int32_t deviceType = 0;
440 if (UnwrapInt32ByPropertyName(env, param, "deviceType", deviceType)) {
441 requestParam.SetDeviceType(deviceType);
442 }
443
444 std::string data;
445 if (UnwrapStringByPropertyName(env, param, "data", data)) {
446 requestParam.SetData(data);
447 }
448
449 int32_t flag = 0;
450 if (UnwrapInt32ByPropertyName(env, param, "flag", flag)) {
451 requestParam.SetFlag(flag);
452 }
453
454 std::string url;
455 if (UnwrapStringByPropertyName(env, param, "url", url)) {
456 requestParam.SetUrl(url);
457 }
458
459 return true;
460 }
461
CreateJsResult(NativeEngine & engine,int32_t errCode,const std::string & message)462 NativeValue* JsFeatureAbility::CreateJsResult(NativeEngine &engine, int32_t errCode, const std::string &message)
463 {
464 NativeValue* jsResult = engine.CreateObject();
465 NativeObject* result = ConvertNativeValueTo<NativeObject>(jsResult);
466 result->SetProperty("code", engine.CreateNumber(errCode));
467 if (errCode == 0) {
468 result->SetProperty("data", engine.CreateUndefined());
469 } else {
470 result->SetProperty("data", engine.CreateString(message.c_str(), message.length()));
471 }
472
473 return jsResult;
474 }
475
CreateJsFeatureAbility(NativeEngine & engine)476 NativeValue* JsFeatureAbility::CreateJsFeatureAbility(NativeEngine &engine)
477 {
478 NativeValue* objValue = engine.CreateObject();
479 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
480
481 std::unique_ptr<JsFeatureAbility> jsFeatureAbility = std::make_unique<JsFeatureAbility>();
482 object->SetNativePointer(jsFeatureAbility.release(), JsFeatureAbility::Finalizer, nullptr);
483
484 const char *moduleName = "JsFeatureAbility";
485 BindNativeFunction(engine, *object, "startAbility", moduleName, JsFeatureAbility::StartAbility);
486 BindNativeFunction(engine, *object, "startAbilityForResult", moduleName, JsFeatureAbility::StartAbilityForResult);
487 BindNativeFunction(engine, *object, "finishWithResult", moduleName, JsFeatureAbility::FinishWithResult);
488 BindNativeFunction(engine, *object, "getDeviceList", moduleName, JsFeatureAbility::GetDeviceList);
489 BindNativeFunction(engine, *object, "callAbility", moduleName, JsFeatureAbility::CallAbility);
490 BindNativeFunction(engine, *object, "continueAbility", moduleName, JsFeatureAbility::ContinueAbility);
491 BindNativeFunction(engine, *object, "subscribeAbilityEvent", moduleName, JsFeatureAbility::SubscribeAbilityEvent);
492 BindNativeFunction(engine, *object, "unsubscribeAbilityEvent", moduleName,
493 JsFeatureAbility::UnsubscribeAbilityEvent);
494 BindNativeFunction(engine, *object, "sendMsg", moduleName, JsFeatureAbility::SendMsg);
495 BindNativeFunction(engine, *object, "subscribeMsg", moduleName, JsFeatureAbility::SubscribeMsg);
496 BindNativeFunction(engine, *object, "unsubscribeMsg", moduleName, JsFeatureAbility::UnsubscribeMsg);
497
498 return objValue;
499 }
500
JsFeatureAbilityInit(NativeEngine * engine,NativeValue * exports)501 NativeValue* JsFeatureAbilityInit(NativeEngine* engine, NativeValue* exports)
502 {
503 HILOG_INFO("%{public}s called.", __func__);
504 if (engine == nullptr) {
505 HILOG_ERROR("%{public}s engine nullptr.", __func__);
506 return nullptr;
507 }
508
509 NativeValue* global = engine->GetGlobal();
510 if (global->TypeOf() != NATIVE_OBJECT) {
511 HILOG_ERROR("global is not NativeObject");
512 return nullptr;
513 }
514
515 NativeObject* object = ConvertNativeValueTo<NativeObject>(global);
516 if (object == nullptr) {
517 HILOG_ERROR("%{public}s convertNativeValueTo result is nullptr.", __func__);
518 return nullptr;
519 }
520
521 object->SetProperty("FeatureAbility", JsFeatureAbility::CreateJsFeatureAbility(*engine));
522
523 HILOG_INFO("%{public}s called end.", __func__);
524 return global;
525 }
526 } // namespace AbilityRuntime
527 } // namespace OHOS
528