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 "bg_continuous_task_napi_module.h"
17
18 #include "ability.h"
19 #include "iservice_registry.h"
20 #include "napi_base_context.h"
21 #include "system_ability_definition.h"
22 #include "want_agent.h"
23
24 #include "background_mode.h"
25 #include "background_task_mgr_helper.h"
26 #include "bgtaskmgr_inner_errors.h"
27 #include "common.h"
28 #include "continuous_task_log.h"
29 #include "continuous_task_param.h"
30
31 namespace OHOS {
32 namespace BackgroundTaskMgr {
33 namespace {
34 static constexpr uint32_t MAX_START_BG_RUNNING_PARAMS = 4;
35 static constexpr uint32_t MAX_STOP_BG_RUNNING_PARAMS = 2;
36 static constexpr uint32_t CALLBACK_RESULT_PARAMS_NUM = 2;
37 static constexpr uint32_t BG_MODE_ID_BEGIN = 1;
38 static constexpr uint32_t BG_MODE_ID_END = 9;
39 }
40
41 struct AsyncCallbackInfo : public AsyncWorkData {
AsyncCallbackInfoOHOS::BackgroundTaskMgr::AsyncCallbackInfo42 explicit AsyncCallbackInfo(napi_env env) : AsyncWorkData(env) {}
43 std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext {nullptr};
44 uint32_t bgMode {0};
45 std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent {nullptr};
46 };
47
WrapVoidToJS(napi_env env)48 napi_value WrapVoidToJS(napi_env env)
49 {
50 napi_value result = nullptr;
51 NAPI_CALL(env, napi_get_null(env, &result));
52 return result;
53 }
54
WrapUndefinedToJS(napi_env env)55 napi_value WrapUndefinedToJS(napi_env env)
56 {
57 napi_value result = nullptr;
58 NAPI_CALL(env, napi_get_undefined(env, &result));
59 return result;
60 }
61
GetCallbackErrorValue(napi_env env,int32_t errCode)62 napi_value GetCallbackErrorValue(napi_env env, int32_t errCode)
63 {
64 napi_value jsObject = nullptr;
65 napi_value jsValue = nullptr;
66 NAPI_CALL(env, napi_create_int32(env, errCode, &jsValue));
67 NAPI_CALL(env, napi_create_object(env, &jsObject));
68 NAPI_CALL(env, napi_set_named_property(env, jsObject, "code", jsValue));
69 return jsObject;
70 }
71
GetAbilityContext(const napi_env & env,const napi_value & value,std::shared_ptr<AbilityRuntime::AbilityContext> & abilityContext)72 napi_value GetAbilityContext(const napi_env &env, const napi_value &value,
73 std::shared_ptr<AbilityRuntime::AbilityContext> &abilityContext)
74 {
75 bool stageMode = false;
76 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, value, stageMode);
77 BGTASK_LOGI("is stage mode: %{public}s", stageMode ? "true" : "false");
78
79 if (status != napi_ok || !stageMode) {
80 BGTASK_LOGI("Getting context with FA model");
81 auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
82 if (!ability) {
83 BGTASK_LOGE("Failed to get native ability instance");
84 return nullptr;
85 }
86 abilityContext = ability->GetAbilityContext();
87 if (!abilityContext) {
88 BGTASK_LOGE("get FA model ability context failed");
89 return nullptr;
90 }
91 return WrapVoidToJS(env);
92 } else {
93 BGTASK_LOGI("Getting context with stage model");
94 auto context = AbilityRuntime::GetStageModeContext(env, value);
95 if (!context) {
96 BGTASK_LOGE("get context failed");
97 return nullptr;
98 }
99 abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
100 if (!abilityContext) {
101 BGTASK_LOGE("get Stage model ability context failed");
102 return nullptr;
103 }
104 return WrapVoidToJS(env);
105 }
106 }
107
GetMainAbilityLabel(const std::string & bundleName)108 std::string GetMainAbilityLabel(const std::string &bundleName)
109 {
110 sptr<ISystemAbilityManager> systemAbilityManager =
111 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
112 if (systemAbilityManager == nullptr) {
113 BGTASK_LOGE("get SystemAbilityManager failed");
114 return "";
115 }
116
117 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
118 if (remoteObject == nullptr) {
119 BGTASK_LOGE("get Bundle Manager object failed");
120 return "";
121 }
122
123 auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
124 if (bundleMgr == nullptr) {
125 BGTASK_LOGE("get Bundle Manager Proxy failed");
126 return "";
127 }
128
129 AAFwk::Want want;
130 want.SetAction("action.system.home");
131 want.AddEntity("entity.system.home");
132 want.SetElementName("", bundleName, "", "");
133 AppExecFwk::AbilityInfo abilityInfo;
134 bundleMgr->QueryAbilityInfo(want, abilityInfo);
135 return bundleMgr->GetAbilityLabel(bundleName, abilityInfo.name);
136 }
137
StartBackgroundRunningCheckParam(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)138 bool StartBackgroundRunningCheckParam(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
139 {
140 if (asyncCallbackInfo == nullptr) {
141 BGTASK_LOGE("asyncCallbackInfo is nullptr");
142 return false;
143 }
144 if (asyncCallbackInfo->errCode != ERR_OK) {
145 BGTASK_LOGE("input params parse failed");
146 return false;
147 }
148 if (asyncCallbackInfo->abilityContext == nullptr) {
149 asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
150 Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
151 BGTASK_LOGE("abilityContext is null");
152 return false;
153 }
154 const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
155 if (info == nullptr) {
156 BGTASK_LOGE("ability info is null");
157 Common::HandleParamErr(env, ERR_ABILITY_INFO_EMPTY, isThrow);
158 asyncCallbackInfo->errCode = ERR_ABILITY_INFO_EMPTY;
159 return false;
160 }
161
162 if (asyncCallbackInfo->wantAgent == nullptr) {
163 BGTASK_LOGE("wantAgent param is nullptr");
164 Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, isThrow);
165 asyncCallbackInfo->errCode = ERR_WANTAGENT_NULL_OR_TYPE_ERR;
166 return false;
167 }
168
169 sptr<IRemoteObject> token = asyncCallbackInfo->abilityContext->GetToken();
170 if (!token) {
171 BGTASK_LOGE("get ability token info failed");
172 Common::HandleParamErr(env, ERR_GET_TOKEN_ERR, isThrow);
173 asyncCallbackInfo->errCode = ERR_GET_TOKEN_ERR;
174 return false;
175 }
176
177 if (asyncCallbackInfo->bgMode < BG_MODE_ID_BEGIN || asyncCallbackInfo->bgMode > BG_MODE_ID_END) {
178 BGTASK_LOGE("request background mode id: %{public}u out of range", asyncCallbackInfo->bgMode);
179 Common::HandleParamErr(env, ERR_BGMODE_RANGE_ERR, isThrow);
180 asyncCallbackInfo->errCode = ERR_BGMODE_RANGE_ERR;
181 return false;
182 }
183
184 return true;
185 }
186
StartBackgroundRunningExecuteCB(napi_env env,void * data)187 void StartBackgroundRunningExecuteCB(napi_env env, void *data)
188 {
189 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
190 if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
191 BGTASK_LOGE("input params error");
192 return;
193 }
194 const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
195
196 ContinuousTaskParam taskParam = ContinuousTaskParam(true, asyncCallbackInfo->bgMode,
197 asyncCallbackInfo->wantAgent, info->name, asyncCallbackInfo->abilityContext->GetToken(),
198 GetMainAbilityLabel(info->bundleName));
199 asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestStartBackgroundRunning(taskParam);
200 }
201
CallbackCompletedCB(napi_env env,napi_status status,void * data)202 void CallbackCompletedCB(napi_env env, napi_status status, void *data)
203 {
204 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
205 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
206 napi_value callback {nullptr};
207 napi_value undefined {nullptr};
208 napi_value result[CALLBACK_RESULT_PARAMS_NUM] = {nullptr};
209 napi_value callResult = {nullptr};
210 NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
211 if (asyncCallbackInfo->errCode == ERR_OK) {
212 result[0] = WrapUndefinedToJS(env);
213 napi_create_int32(env, 0, &result[1]);
214 } else {
215 result[1] = WrapUndefinedToJS(env);
216 std::string errMsg = Common::FindErrMsg(env, asyncCallbackInfo->errCode);
217 int32_t errCodeInfo = Common::FindErrCode(env, asyncCallbackInfo->errCode);
218 result[0] = Common::GetCallbackErrorValue(env, errCodeInfo, errMsg);
219 }
220
221 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
222 NAPI_CALL_RETURN_VOID(env,
223 napi_call_function(env, undefined, callback, CALLBACK_RESULT_PARAMS_NUM, result, &callResult));
224 }
225
PromiseCompletedCB(napi_env env,napi_status status,void * data)226 void PromiseCompletedCB(napi_env env, napi_status status, void *data)
227 {
228 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
229 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
230 napi_value result {nullptr};
231 if (asyncCallbackInfo->errCode == ERR_OK) {
232 napi_create_int32(env, 0, &result);
233 NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result));
234 } else {
235 std::string errMsg = Common::FindErrMsg(env, asyncCallbackInfo->errCode);
236 int32_t errCodeInfo = Common::FindErrCode(env, asyncCallbackInfo->errCode);
237 result = Common::GetCallbackErrorValue(env, errCodeInfo, errMsg);
238 NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result));
239 }
240 }
241
StartBackgroundRunningAsync(napi_env env,napi_value * argv,const uint32_t argCallback,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)242 napi_value StartBackgroundRunningAsync(napi_env env, napi_value *argv,
243 const uint32_t argCallback, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
244 {
245 if (argv == nullptr || asyncCallbackInfo == nullptr) {
246 BGTASK_LOGE("param is nullptr");
247 return nullptr;
248 }
249 if (isThrow && asyncCallbackInfo->errCode != ERR_OK) {
250 return nullptr;
251 }
252 napi_value resourceName {nullptr};
253 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
254
255 napi_valuetype valuetype = napi_undefined;
256 NAPI_CALL(env, napi_typeof(env, argv[argCallback], &valuetype));
257 if (valuetype != napi_function) {
258 Common::HandleParamErr(env, ERR_CALLBACK_NULL_OR_TYPE_ERR, isThrow);
259 return nullptr;
260 }
261 NAPI_CALL(env, napi_create_reference(env, argv[argCallback], 1, &asyncCallbackInfo->callback));
262 if (!StartBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
263 return nullptr;
264 }
265
266 NAPI_CALL(env, napi_create_async_work(env,
267 nullptr,
268 resourceName,
269 StartBackgroundRunningExecuteCB,
270 CallbackCompletedCB,
271 static_cast<void *>(asyncCallbackInfo),
272 &asyncCallbackInfo->asyncWork));
273 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
274
275 return WrapVoidToJS(env);
276 }
277
StartBackgroundRunningPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)278 napi_value StartBackgroundRunningPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
279 {
280 if (asyncCallbackInfo == nullptr) {
281 BGTASK_LOGE("param is nullptr");
282 return nullptr;
283 }
284 napi_value resourceName;
285 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
286 napi_deferred deferred;
287 napi_value promise {nullptr};
288 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
289 asyncCallbackInfo->deferred = deferred;
290 if (!StartBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
291 return nullptr;
292 }
293
294 NAPI_CALL(env, napi_create_async_work(env,
295 nullptr,
296 resourceName,
297 StartBackgroundRunningExecuteCB,
298 PromiseCompletedCB,
299 static_cast<void *>(asyncCallbackInfo),
300 &asyncCallbackInfo->asyncWork));
301 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
302 return promise;
303 }
304
GetBackgroundMode(const napi_env & env,const napi_value & value,uint32_t & bgMode)305 napi_value GetBackgroundMode(const napi_env &env, const napi_value &value, uint32_t &bgMode)
306 {
307 napi_valuetype valuetype = napi_undefined;
308 NAPI_CALL(env, napi_typeof(env, value, &valuetype));
309 if (valuetype != napi_number) {
310 Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, true);
311 return nullptr;
312 }
313 napi_get_value_uint32(env, value, &bgMode);
314
315 BGTASK_LOGI("get bgmode info: %{public}u", bgMode);
316 return WrapVoidToJS(env);
317 }
318
GetWantAgent(const napi_env & env,const napi_value & value,std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> & wantAgent)319 napi_value GetWantAgent(const napi_env &env, const napi_value &value,
320 std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> &wantAgent)
321 {
322 napi_valuetype valuetype = napi_undefined;
323 AbilityRuntime::WantAgent::WantAgent *wantAgentPtr = nullptr;
324 NAPI_CALL(env, napi_typeof(env, value, &valuetype));
325 if (valuetype != napi_object) {
326 Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, true);
327 return nullptr;
328 }
329 napi_unwrap(env, value, (void **)&wantAgentPtr);
330 wantAgent = std::make_shared<AbilityRuntime::WantAgent::WantAgent>(*wantAgentPtr);
331
332 return WrapVoidToJS(env);
333 }
334
StartBackgroundRunning(napi_env env,napi_callback_info info,bool isThrow)335 napi_value StartBackgroundRunning(napi_env env, napi_callback_info info, bool isThrow)
336 {
337 AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env);
338 if (asyncCallbackInfo == nullptr) {
339 BGTASK_LOGE("asyncCallbackInfo == nullpter");
340 return WrapVoidToJS(env);
341 }
342 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
343
344 size_t argc = MAX_START_BG_RUNNING_PARAMS;
345 napi_value argv[MAX_START_BG_RUNNING_PARAMS] = {nullptr};
346 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
347 if (argc > MAX_START_BG_RUNNING_PARAMS) {
348 BGTASK_LOGE("wrong param nums");
349 Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
350 return WrapVoidToJS(env);
351 }
352
353 // argv[0] : context : AbilityContext
354 if (GetAbilityContext(env, argv[0], asyncCallbackInfo->abilityContext) == nullptr) {
355 BGTASK_LOGE("Get ability context failed");
356 Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
357 asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
358 }
359
360 // argv[1] : bgMode : BackgroundMode
361 if (GetBackgroundMode(env, argv[1], asyncCallbackInfo->bgMode) == nullptr) {
362 BGTASK_LOGE("input bgmode param not number");
363 Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, isThrow);
364 asyncCallbackInfo->errCode = ERR_BGMODE_NULL_OR_TYPE_ERR;
365 }
366
367 // argv[2] : wantAgent: WantAgent
368 if (GetWantAgent(env, argv[2], asyncCallbackInfo->wantAgent) == nullptr) {
369 BGTASK_LOGE("input wantAgent param is not object");
370 Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, isThrow);
371 asyncCallbackInfo->errCode = ERR_WANTAGENT_NULL_OR_TYPE_ERR;
372 }
373
374 napi_value ret {nullptr};
375
376 if (argc == MAX_START_BG_RUNNING_PARAMS) {
377 ret = StartBackgroundRunningAsync(env, argv, MAX_START_BG_RUNNING_PARAMS - 1, asyncCallbackInfo, isThrow);
378 } else {
379 ret = StartBackgroundRunningPromise(env, asyncCallbackInfo, isThrow);
380 }
381
382 if (ret == nullptr) {
383 BGTASK_LOGE("ret is nullpter");
384 if (asyncCallbackInfo != nullptr) {
385 delete asyncCallbackInfo;
386 asyncCallbackInfo = nullptr;
387 }
388 ret = WrapVoidToJS(env);
389 }
390 callbackPtr.release();
391 return ret;
392 }
393
StopBackgroundRunningCheckParam(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)394 bool StopBackgroundRunningCheckParam(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
395 {
396 if (asyncCallbackInfo == nullptr) {
397 BGTASK_LOGE("asyncCallbackInfo is nullptr");
398 return false;
399 }
400 if (asyncCallbackInfo->abilityContext == nullptr) {
401 BGTASK_LOGE("ability context is null");
402 Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
403 asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
404 return false;
405 }
406 const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
407 if (info == nullptr) {
408 BGTASK_LOGE("abilityInfo is null");
409 Common::HandleParamErr(env, ERR_ABILITY_INFO_EMPTY, isThrow);
410 asyncCallbackInfo->errCode = ERR_ABILITY_INFO_EMPTY;
411 return false;
412 }
413
414 sptr<IRemoteObject> token = asyncCallbackInfo->abilityContext->GetToken();
415 if (!token) {
416 BGTASK_LOGE("get ability token info failed");
417 Common::HandleParamErr(env, ERR_GET_TOKEN_ERR, isThrow);
418 asyncCallbackInfo->errCode = ERR_GET_TOKEN_ERR;
419 return false;
420 }
421 return true;
422 }
423
StopBackgroundRunningExecuteCB(napi_env env,void * data)424 void StopBackgroundRunningExecuteCB(napi_env env, void *data)
425 {
426 AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
427 if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
428 BGTASK_LOGE("input param error");
429 return;
430 }
431 const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
432 sptr<IRemoteObject> token = asyncCallbackInfo->abilityContext->GetToken();
433 asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestStopBackgroundRunning(info->name, token);
434 }
435
StopBackgroundRunningAsync(napi_env env,napi_value * argv,const uint32_t argCallback,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)436 napi_value StopBackgroundRunningAsync(napi_env env, napi_value *argv,
437 const uint32_t argCallback, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
438 {
439 if (argv == nullptr || asyncCallbackInfo == nullptr) {
440 BGTASK_LOGE("param is nullptr");
441 return nullptr;
442 }
443 if (isThrow && asyncCallbackInfo->errCode != ERR_OK) {
444 return nullptr;
445 }
446 napi_value resourceName {nullptr};
447 NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
448
449 napi_valuetype valuetype = napi_undefined;
450 NAPI_CALL(env, napi_typeof(env, argv[argCallback], &valuetype));
451 if (valuetype == napi_function) {
452 NAPI_CALL(env, napi_create_reference(env, argv[argCallback], 1, &asyncCallbackInfo->callback));
453 }
454 if (!StopBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
455 return nullptr;
456 }
457
458 NAPI_CALL(env, napi_create_async_work(env,
459 nullptr,
460 resourceName,
461 StopBackgroundRunningExecuteCB,
462 CallbackCompletedCB,
463 static_cast<void *>(asyncCallbackInfo),
464 &asyncCallbackInfo->asyncWork));
465 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
466 return WrapVoidToJS(env);
467 }
468
StopBackgroundRunningPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)469 napi_value StopBackgroundRunningPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
470 {
471 if (asyncCallbackInfo == nullptr) {
472 BGTASK_LOGE("param is nullptr");
473 return nullptr;
474 }
475 napi_value resourceName {nullptr};
476 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
477 napi_deferred deferred;
478 napi_value promise {nullptr};
479 napi_create_promise(env, &deferred, &promise);
480
481 asyncCallbackInfo->deferred = deferred;
482 if (!StopBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
483 return nullptr;
484 }
485
486 napi_create_async_work(
487 env,
488 nullptr,
489 resourceName,
490 StopBackgroundRunningExecuteCB,
491 PromiseCompletedCB,
492 static_cast<void *>(asyncCallbackInfo),
493 &asyncCallbackInfo->asyncWork);
494 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
495 return promise;
496 }
497
StopBackgroundRunning(napi_env env,napi_callback_info info,bool isThrow)498 napi_value StopBackgroundRunning(napi_env env, napi_callback_info info, bool isThrow)
499 {
500 AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env);
501 if (asyncCallbackInfo == nullptr) {
502 BGTASK_LOGE("asyncCallbackInfo is nullpter");
503 return WrapVoidToJS(env);
504 }
505 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
506
507 size_t argc = MAX_STOP_BG_RUNNING_PARAMS;
508 napi_value argv[MAX_STOP_BG_RUNNING_PARAMS] = {nullptr};
509
510 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
511 if (argc > MAX_STOP_BG_RUNNING_PARAMS) {
512 BGTASK_LOGE("wrong param nums");
513 Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
514 return nullptr;
515 }
516
517 // argv[0] : context : AbilityContext
518 if (GetAbilityContext(env, argv[0], asyncCallbackInfo->abilityContext) == nullptr) {
519 BGTASK_LOGE("Get ability context failed");
520 Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
521 asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
522 }
523
524 napi_value ret {nullptr};
525 if (argc == MAX_STOP_BG_RUNNING_PARAMS) {
526 ret = StopBackgroundRunningAsync(env, argv, MAX_STOP_BG_RUNNING_PARAMS - 1, asyncCallbackInfo, isThrow);
527 } else {
528 ret = StopBackgroundRunningPromise(env, asyncCallbackInfo, isThrow);
529 }
530
531 if (ret == nullptr) {
532 BGTASK_LOGE("ret is nullpter");
533 if (asyncCallbackInfo != nullptr) {
534 delete asyncCallbackInfo;
535 asyncCallbackInfo = nullptr;
536 }
537 ret = WrapVoidToJS(env);
538 }
539 callbackPtr.release();
540 return ret;
541 }
542
StartBackgroundRunning(napi_env env,napi_callback_info info)543 napi_value StartBackgroundRunning(napi_env env, napi_callback_info info)
544 {
545 return StartBackgroundRunning(env, info, false);
546 }
547
StopBackgroundRunning(napi_env env,napi_callback_info info)548 napi_value StopBackgroundRunning(napi_env env, napi_callback_info info)
549 {
550 return StopBackgroundRunning(env, info, false);
551 }
552
StartBackgroundRunningThrow(napi_env env,napi_callback_info info)553 napi_value StartBackgroundRunningThrow(napi_env env, napi_callback_info info)
554 {
555 return StartBackgroundRunning(env, info, true);
556 }
557
StopBackgroundRunningThrow(napi_env env,napi_callback_info info)558 napi_value StopBackgroundRunningThrow(napi_env env, napi_callback_info info)
559 {
560 return StopBackgroundRunning(env, info, true);
561 }
562 } // namespace BackgroundTaskMgr
563 } // namespace OHOS