• 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 "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