1 /*
2  * Copyright (c) 2021-2024 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 "particle_ability.h"
16 
17 #include <cstring>
18 #include <uv.h>
19 #include <vector>
20 
21 #include "hilog_tag_wrapper.h"
22 #include "js_runtime_utils.h"
23 #include "napi_common_ability.h"
24 #include "napi/native_api.h"
25 #include "securec.h"
26 
27 using namespace OHOS::AbilityRuntime;
28 using namespace OHOS::AAFwk;
29 using namespace OHOS::AppExecFwk;
30 
31 namespace OHOS {
32 namespace AppExecFwk {
33 /**
34  * @brief Obtains the type of this application.
35  *
36  * @param env The environment that the Node-API call is invoked under.
37  * @param info The callback info passed into the callback function.
38  *
39  * @return The return value from NAPI C++ to JS for the module.
40  */
NAPI_PAGetAppType(napi_env env,napi_callback_info info)41 napi_value NAPI_PAGetAppType(napi_env env, napi_callback_info info)
42 {
43     TAG_LOGI(AAFwkTag::FA, "called");
44     return NAPI_GetAppTypeCommon(env, info, AbilityType::UNKNOWN);
45 }
46 
47 /**
48  * @brief Obtains information about the current ability.
49  *
50  * @param env The environment that the Node-API call is invoked under.
51  * @param info The callback info passed into the callback function.
52  *
53  * @return The return value from NAPI C++ to JS for the module.
54  */
NAPI_PAGetAbilityInfo(napi_env env,napi_callback_info info)55 napi_value NAPI_PAGetAbilityInfo(napi_env env, napi_callback_info info)
56 {
57     TAG_LOGI(AAFwkTag::FA, "called");
58     return NAPI_GetAbilityInfoCommon(env, info, AbilityType::UNKNOWN);
59 }
60 
61 /**
62  * @brief Obtains the HapModuleInfo object of the application.
63  *
64  * @param env The environment that the Node-API call is invoked under.
65  * @param info The callback info passed into the callback function.
66  *
67  * @return The return value from NAPI C++ to JS for the module.
68  */
NAPI_PAGetHapModuleInfo(napi_env env,napi_callback_info info)69 napi_value NAPI_PAGetHapModuleInfo(napi_env env, napi_callback_info info)
70 {
71     TAG_LOGI(AAFwkTag::FA, "called");
72     return NAPI_GetHapModuleInfoCommon(env, info, AbilityType::UNKNOWN);
73 }
74 
75 /**
76  * @brief Get context.
77  *
78  * @param env The environment that the Node-API call is invoked under.
79  * @param info The callback info passed into the callback function.
80  *
81  * @return The return value from NAPI C++ to JS for the module.
82  */
NAPI_PAGetContext(napi_env env,napi_callback_info info)83 napi_value NAPI_PAGetContext(napi_env env, napi_callback_info info)
84 {
85     TAG_LOGI(AAFwkTag::FA, "called");
86     return NAPI_GetContextCommon(env, info, AbilityType::UNKNOWN);
87 }
88 
89 /**
90  * @brief Get want.
91  *
92  * @param env The environment that the Node-API call is invoked under.
93  * @param info The callback info passed into the callback function.
94  *
95  * @return The return value from NAPI C++ to JS for the module.
96  */
NAPI_PAGetWant(napi_env env,napi_callback_info info)97 napi_value NAPI_PAGetWant(napi_env env, napi_callback_info info)
98 {
99     TAG_LOGI(AAFwkTag::FA, "called");
100     return NAPI_GetWantCommon(env, info, AbilityType::UNKNOWN);
101 }
102 
103 /**
104  * @brief Obtains the class name in this ability name, without the prefixed bundle name.
105  *
106  * @param env The environment that the Node-API call is invoked under.
107  * @param info The callback info passed into the callback function.
108  *
109  * @return The return value from NAPI C++ to JS for the module.
110  */
NAPI_PAGetAbilityName(napi_env env,napi_callback_info info)111 napi_value NAPI_PAGetAbilityName(napi_env env, napi_callback_info info)
112 {
113     TAG_LOGI(AAFwkTag::FA, "called");
114     return NAPI_GetAbilityNameCommon(env, info, AbilityType::UNKNOWN);
115 }
116 
117 /**
118  * @brief ParticleAbility NAPI method : stopAbility.
119  *
120  * @param env The environment that the Node-API call is invoked under.
121  * @param info The callback info passed into the callback function.
122  *
123  * @return The return value from NAPI C++ to JS for the module.
124  */
NAPI_PAStopAbility(napi_env env,napi_callback_info info)125 napi_value NAPI_PAStopAbility(napi_env env, napi_callback_info info)
126 {
127     TAG_LOGI(AAFwkTag::FA, "called");
128     return NAPI_StopAbilityCommon(env, info, AbilityType::UNKNOWN);
129 }
130 
131 /**
132  * @brief FeatureAbility NAPI method : acquireDataAbilityHelper.
133  *
134  * @param env The environment that the Node-API call is invoked under.
135  * @param info The callback info passed into the callback function.
136  *
137  * @return The return value from NAPI C++ to JS for the module.
138  */
NAPI_PAAcquireDataAbilityHelper(napi_env env,napi_callback_info info)139 napi_value NAPI_PAAcquireDataAbilityHelper(napi_env env, napi_callback_info info)
140 {
141     TAG_LOGI(AAFwkTag::FA, "called");
142     return NAPI_AcquireDataAbilityHelperCommon(env, info, AbilityType::UNKNOWN);
143 }
144 
145 /**
146  * @brief ParticleAbility NAPI method : startBackgroundRunning.
147  *
148  * @param env The environment that the Node-API call is invoked under.
149  * @param info The callback info passed into the callback function.
150  *
151  * @return The return value from NAPI C++ to JS for the module.
152  */
NAPI_PAStartBackgroundRunning(napi_env env,napi_callback_info info)153 napi_value NAPI_PAStartBackgroundRunning(napi_env env, napi_callback_info info)
154 {
155     TAG_LOGI(AAFwkTag::FA, "called");
156     return NAPI_StartBackgroundRunningCommon(env, info);
157 }
158 
159 /**
160  * @brief ParticleAbility NAPI method : cancelBackgroundRunning.
161  *
162  * @param env The environment that the Node-API call is invoked under.
163  * @param info The callback info passed into the callback function.
164  *
165  * @return The return value from NAPI C++ to JS for the module.
166  */
NAPI_PACancelBackgroundRunning(napi_env env,napi_callback_info info)167 napi_value NAPI_PACancelBackgroundRunning(napi_env env, napi_callback_info info)
168 {
169     TAG_LOGI(AAFwkTag::FA, "called");
170     return NAPI_CancelBackgroundRunningCommon(env, info);
171 }
172 
173 /**
174  * @brief ParticleAbility NAPI module registration.
175  *
176  * @param env The environment that the Node-API call is invoked under.
177  * @param exports An empty object via the exports parameter as a convenience.
178  *
179  * @return The return value from Init is treated as the exports object for the module.
180  */
ParticleAbilityInit(napi_env env,napi_value exports)181 napi_value ParticleAbilityInit(napi_env env, napi_value exports)
182 {
183     TAG_LOGI(AAFwkTag::FA, "called");
184     napi_property_descriptor properties[] = {
185         DECLARE_NAPI_FUNCTION("getAppType", NAPI_PAGetAppType),
186         DECLARE_NAPI_FUNCTION("getAbilityInfo", NAPI_PAGetAbilityInfo),
187         DECLARE_NAPI_FUNCTION("getHapModuleInfo", NAPI_PAGetHapModuleInfo),
188         DECLARE_NAPI_FUNCTION("getContext", NAPI_PAGetContext),
189         DECLARE_NAPI_FUNCTION("getWant", NAPI_PAGetWant),
190         DECLARE_NAPI_FUNCTION("getAbilityName", NAPI_PAGetAbilityName),
191         DECLARE_NAPI_FUNCTION("stopAbility", NAPI_PAStopAbility),
192         DECLARE_NAPI_FUNCTION("acquireDataAbilityHelper", NAPI_PAAcquireDataAbilityHelper),
193         DECLARE_NAPI_FUNCTION("startBackgroundRunning", NAPI_PAStartBackgroundRunning),
194         DECLARE_NAPI_FUNCTION("cancelBackgroundRunning", NAPI_PACancelBackgroundRunning),
195     };
196     napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties);
197 
198     return JsParticleAbilityInit(env, exports);
199 }
200 
Finalizer(napi_env env,void * data,void * hint)201 void JsParticleAbility::Finalizer(napi_env env, void *data, void *hint)
202 {
203     TAG_LOGI(AAFwkTag::FA, "finalizer called");
204     std::unique_ptr<JsParticleAbility>(static_cast<JsParticleAbility*>(data));
205 }
206 
PAConnectAbility(napi_env env,napi_callback_info info)207 napi_value JsParticleAbility::PAConnectAbility(napi_env env, napi_callback_info info)
208 {
209     JsParticleAbility *me = CheckParamsAndGetThis<JsParticleAbility>(env, info);
210     return (me != nullptr) ? me->JsConnectAbility(env, info, AbilityType::UNKNOWN) : nullptr;
211 }
212 
PADisConnectAbility(napi_env env,napi_callback_info info)213 napi_value JsParticleAbility::PADisConnectAbility(napi_env env, napi_callback_info info)
214 {
215     JsParticleAbility *me = CheckParamsAndGetThis<JsParticleAbility>(env, info);
216     return (me != nullptr) ? me->JsDisConnectAbility(env, info, AbilityType::UNKNOWN) : nullptr;
217 }
218 
PAStartAbility(napi_env env,napi_callback_info info)219 napi_value JsParticleAbility::PAStartAbility(napi_env env, napi_callback_info info)
220 {
221     JsParticleAbility *me = CheckParamsAndGetThis<JsParticleAbility>(env, info);
222     return (me != nullptr) ? me->JsStartAbility(env, info, AbilityType::UNKNOWN) : nullptr;
223 }
224 
PATerminateAbility(napi_env env,napi_callback_info info)225 napi_value JsParticleAbility::PATerminateAbility(napi_env env, napi_callback_info info)
226 {
227     GET_NAPI_INFO_AND_CALL(env, info, JsParticleAbility, JsTerminateAbility);
228 }
229 
GetAbility(napi_env env)230 Ability* JsParticleAbility::GetAbility(napi_env env)
231 {
232     napi_status ret;
233     napi_value global = nullptr;
234     const napi_extended_error_info *errorInfo = nullptr;
235     ret = napi_get_global(env, &global);
236     if (ret != napi_ok) {
237         napi_get_last_error_info(env, &errorInfo);
238         TAG_LOGE(AAFwkTag::FA, "get_global=%{public}d err:%{public}s",
239             ret, errorInfo->error_message);
240         return nullptr;
241     }
242     napi_value abilityObj = nullptr;
243     ret = napi_get_named_property(env, global, "ability", &abilityObj);
244     if (ret != napi_ok) {
245         napi_get_last_error_info(env, &errorInfo);
246         TAG_LOGE(AAFwkTag::FA, "get_named_property=%{public}d err:%{public}s",
247             ret, errorInfo->error_message);
248         return nullptr;
249     }
250     Ability* ability = nullptr;
251     ret = napi_get_value_external(env, abilityObj, reinterpret_cast<void **>(&ability));
252     if (ret != napi_ok) {
253         napi_get_last_error_info(env, &errorInfo);
254         TAG_LOGE(AAFwkTag::FA, "get_value_external=%{public}d err:%{public}s",
255             ret, errorInfo->error_message);
256         return nullptr;
257     }
258     return ability;
259 }
260 
JsParticleAbilityInit(napi_env env,napi_value exportObj)261 napi_value JsParticleAbilityInit(napi_env env, napi_value exportObj)
262 {
263     TAG_LOGD(AAFwkTag::FA, "called");
264 
265     if (env == nullptr || exportObj == nullptr) {
266         TAG_LOGE(AAFwkTag::FA, "env or exportObj null");
267         return nullptr;
268     }
269     if (!CheckTypeForNapiValue(env, exportObj, napi_object)) {
270         TAG_LOGE(AAFwkTag::FA, "object null");
271         return nullptr;
272     }
273 
274     std::unique_ptr<JsParticleAbility> jsParticleAbility = std::make_unique<JsParticleAbility>();
275     jsParticleAbility->ability_ = jsParticleAbility->GetAbility(env);
276     napi_wrap(env, exportObj, jsParticleAbility.release(), JsParticleAbility::Finalizer, nullptr, nullptr);
277 
278     TAG_LOGD(AAFwkTag::FA, "BindNativeFunction called");
279     const char *moduleName = "JsParticleAbility";
280     BindNativeFunction(env, exportObj, "connectAbility", moduleName, JsParticleAbility::PAConnectAbility);
281     BindNativeFunction(env, exportObj, "disconnectAbility", moduleName, JsParticleAbility::PADisConnectAbility);
282     BindNativeFunction(env, exportObj, "startAbility", moduleName, JsParticleAbility::PAStartAbility);
283     BindNativeFunction(env, exportObj, "terminateSelf", moduleName, JsParticleAbility::PATerminateAbility);
284 
285     TAG_LOGD(AAFwkTag::FA, "end");
286     return exportObj;
287 }
288 }  // namespace AppExecFwk
289 }  // namespace OHOS
290