• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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