• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 "bundle_mgr_interface.h"
20 #include "hitrace_meter.h"
21 #include "iservice_registry.h"
22 #include "napi_base_context.h"
23 #include "system_ability_definition.h"
24 #include "want_agent.h"
25 #ifdef SUPPORT_JSSTACK
26 #include "xpower_event_js.h"
27 #endif
28 
29 #include "background_mode.h"
30 #include "background_task_mgr_helper.h"
31 #include "bgtaskmgr_inner_errors.h"
32 #include "common.h"
33 #include "continuous_task_info.h"
34 #include "continuous_task_log.h"
35 #include "continuous_task_param.h"
36 #include "js_backgroundtask_subscriber.h"
37 #include "js_runtime_utils.h"
38 
39 namespace OHOS {
40 namespace BackgroundTaskMgr {
41 namespace {
42 static constexpr uint32_t MAX_START_BG_RUNNING_PARAMS = 4;
43 static constexpr uint32_t MAX_STOP_BG_RUNNING_PARAMS = 2;
44 static constexpr uint32_t MAX_UPDATE_BG_RUNNING_PARAMS = 2;
45 static constexpr uint32_t MAX_GET_ALL_CONTINUOUSTASK_PARAMS = 2;
46 static constexpr uint32_t CALLBACK_RESULT_PARAMS_NUM = 2;
47 static constexpr uint32_t BG_MODE_ID_BEGIN = 1;
48 static constexpr uint32_t BG_MODE_ID_END = 9;
49 static constexpr int32_t SYSTEM_LIVE_CONTENT_TYPE = 8;
50 static constexpr int32_t SLOT_TYPE = 4;
51 static constexpr uint32_t ARGC_ONE = 1;
52 static constexpr uint32_t ARGC_TWO = 2;
53 static constexpr uint32_t INDEX_ZERO = 0;
54 static constexpr uint32_t INDEX_ONE = 1;
55 static constexpr uint32_t CONTINUOUS_TASK_CANCEL = 1 << 0;
56 static constexpr uint32_t CONTINUOUS_TASK_SUSPEND = 1 << 1;
57 static constexpr uint32_t CONTINUOUS_TASK_ACTIVE = 1 << 2;
58 static std::shared_ptr<JsBackgroundTaskSubscriber> backgroundTaskSubscriber_ = nullptr;
59 static std::vector<std::string> g_backgroundModes = {
60     "dataTransfer",
61     "audioPlayback",
62     "audioRecording",
63     "location",
64     "bluetoothInteraction",
65     "multiDeviceConnection",
66     "wifiInteraction",
67     "voip",
68     "taskKeeping"
69     };
70 
71 static std::vector<std::string> g_callbackTypes = {
72     "continuousTaskCancel",
73     "continuousTaskSuspend",
74     "continuousTaskActive"
75     };
76 }
77 
78 struct AsyncCallbackInfo : public AsyncWorkData {
AsyncCallbackInfoOHOS::BackgroundTaskMgr::AsyncCallbackInfo79     explicit AsyncCallbackInfo(napi_env env) : AsyncWorkData(env) {}
80     std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext {nullptr};
81     uint32_t bgMode {0};
82     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent {nullptr};
83     std::vector<uint32_t> bgModes {};
84     bool isBatchApi {false};
85     bool includeSuspended {false};
86     int32_t notificationId {-1}; // out
87     int32_t continuousTaskId {-1}; // out
88     std::vector<std::shared_ptr<ContinuousTaskInfo>> list; // out
89 };
90 
WrapVoidToJS(napi_env env)91 napi_value WrapVoidToJS(napi_env env)
92 {
93     napi_value result = nullptr;
94     NAPI_CALL(env, napi_get_null(env, &result));
95     return result;
96 }
97 
WrapUndefinedToJS(napi_env env)98 napi_value WrapUndefinedToJS(napi_env env)
99 {
100     napi_value result = nullptr;
101     NAPI_CALL(env, napi_get_undefined(env, &result));
102     return result;
103 }
104 
GetCallbackErrorValue(napi_env env,int32_t errCode)105 napi_value GetCallbackErrorValue(napi_env env, int32_t errCode)
106 {
107     napi_value jsObject = nullptr;
108     napi_value jsValue = nullptr;
109     NAPI_CALL(env, napi_create_int32(env, errCode, &jsValue));
110     NAPI_CALL(env, napi_create_object(env, &jsObject));
111     NAPI_CALL(env, napi_set_named_property(env, jsObject, "code", jsValue));
112     return jsObject;
113 }
114 
GetAbilityContext(const napi_env & env,const napi_value & value,std::shared_ptr<AbilityRuntime::AbilityContext> & abilityContext)115 napi_value GetAbilityContext(const napi_env &env, const napi_value &value,
116     std::shared_ptr<AbilityRuntime::AbilityContext> &abilityContext)
117 {
118     bool stageMode = false;
119     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, value, stageMode);
120     BGTASK_LOGD("is stage mode: %{public}s", stageMode ? "true" : "false");
121 
122     if (status != napi_ok || !stageMode) {
123         BGTASK_LOGI("Getting context with FA model");
124         auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
125         if (!ability) {
126             BGTASK_LOGE("Failed to get native ability instance");
127             return nullptr;
128         }
129         abilityContext = ability->GetAbilityContext();
130         if (!abilityContext) {
131             BGTASK_LOGE("get FA model ability context failed");
132             return nullptr;
133         }
134         return WrapVoidToJS(env);
135     } else {
136         BGTASK_LOGD("Getting context with stage model");
137         auto context = AbilityRuntime::GetStageModeContext(env, value);
138         if (!context) {
139             BGTASK_LOGE("get context failed");
140             return nullptr;
141         }
142         abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
143         if (!abilityContext) {
144             BGTASK_LOGE("get Stage model ability context failed");
145             return nullptr;
146         }
147         return WrapVoidToJS(env);
148     }
149 }
150 
CheckBackgroundMode(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)151 bool CheckBackgroundMode(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
152 {
153     if (!asyncCallbackInfo->isBatchApi) {
154         if (asyncCallbackInfo->bgMode < BG_MODE_ID_BEGIN || asyncCallbackInfo->bgMode > BG_MODE_ID_END) {
155             BGTASK_LOGE("request background mode id: %{public}u out of range", asyncCallbackInfo->bgMode);
156             Common::HandleParamErr(env, ERR_BGMODE_RANGE_ERR, isThrow);
157             asyncCallbackInfo->errCode = ERR_BGMODE_RANGE_ERR;
158             return false;
159         }
160     } else {
161         for (unsigned int  i = 0; i < asyncCallbackInfo->bgModes.size(); i++) {
162             if (asyncCallbackInfo->bgModes[i] < BG_MODE_ID_BEGIN || asyncCallbackInfo->bgModes[i] > BG_MODE_ID_END) {
163                 BGTASK_LOGE("request background mode id: %{public}u out of range", asyncCallbackInfo->bgModes[i]);
164                 Common::HandleParamErr(env, ERR_BGMODE_RANGE_ERR, isThrow);
165                 asyncCallbackInfo->errCode = ERR_BGMODE_RANGE_ERR;
166                 return false;
167             }
168         }
169     }
170     return true;
171 }
172 
StartBackgroundRunningCheckParam(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)173 bool StartBackgroundRunningCheckParam(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
174 {
175     if (asyncCallbackInfo == nullptr) {
176         BGTASK_LOGE("asyncCallbackInfo is nullptr");
177         return false;
178     }
179     if (asyncCallbackInfo->errCode != ERR_OK) {
180         BGTASK_LOGE("input params parse failed");
181         return false;
182     }
183     if (asyncCallbackInfo->abilityContext == nullptr) {
184         asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
185         Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
186         BGTASK_LOGE("abilityContext is null");
187         return false;
188     }
189     const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
190     if (info == nullptr) {
191         BGTASK_LOGE("ability info is null");
192         Common::HandleParamErr(env, ERR_ABILITY_INFO_EMPTY, isThrow);
193         asyncCallbackInfo->errCode = ERR_ABILITY_INFO_EMPTY;
194         return false;
195     }
196     if (asyncCallbackInfo->wantAgent == nullptr) {
197         BGTASK_LOGE("wantAgent param is nullptr");
198         Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, isThrow);
199         asyncCallbackInfo->errCode = ERR_WANTAGENT_NULL_OR_TYPE_ERR;
200         return false;
201     }
202     sptr<IRemoteObject> token = asyncCallbackInfo->abilityContext->GetToken();
203     if (!token) {
204         BGTASK_LOGE("get ability token info failed");
205         Common::HandleParamErr(env, ERR_GET_TOKEN_ERR, isThrow);
206         asyncCallbackInfo->errCode = ERR_GET_TOKEN_ERR;
207         return false;
208     }
209     if (!CheckBackgroundMode(env, asyncCallbackInfo, isThrow)) {
210         BGTASK_LOGE("check background mode failed.");
211         return false;
212     }
213     return true;
214 }
215 
UpdateBackgroundRunningExecuteCB(napi_env env,void * data)216 void UpdateBackgroundRunningExecuteCB(napi_env env, void *data)
217 {
218     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
219         "BackgroundTaskManager::ContinuousTask::Napi::UpdateBackgroundRunningExecuteCB");
220     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
221     if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
222         BGTASK_LOGE("input params error");
223         return;
224     }
225     const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
226     ContinuousTaskParam taskParam = ContinuousTaskParam(true, asyncCallbackInfo->bgMode, nullptr, info->name,
227         asyncCallbackInfo->abilityContext->GetToken(), "", true, asyncCallbackInfo->bgModes,
228         asyncCallbackInfo->abilityContext->GetAbilityRecordId());
229     BGTASK_LOGI("RequestUpdateBackgroundRunning isBatch: %{public}d, bgModeSize: %{public}u",
230         taskParam.isBatchApi_, static_cast<uint32_t>(taskParam.bgModeIds_.size()));
231     asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestUpdateBackgroundRunning(taskParam);
232     asyncCallbackInfo->notificationId = taskParam.notificationId_;
233     asyncCallbackInfo->continuousTaskId = taskParam.continuousTaskId_;
234     BGTASK_LOGI("notification %{public}d, continuousTaskId %{public}d", taskParam.notificationId_,
235         taskParam.continuousTaskId_);
236 }
237 
StartBackgroundRunningExecuteCB(napi_env env,void * data)238 void StartBackgroundRunningExecuteCB(napi_env env, void *data)
239 {
240     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
241         "BackgroundTaskManager::ContinuousTask::Napi::StartBackgroundRunningExecuteCB");
242     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
243     if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
244         BGTASK_LOGE("input params error");
245         return;
246     }
247     const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
248     ContinuousTaskParam taskParam = ContinuousTaskParam(true, asyncCallbackInfo->bgMode, asyncCallbackInfo->wantAgent,
249         info->name, asyncCallbackInfo->abilityContext->GetToken(), "",
250         asyncCallbackInfo->isBatchApi, asyncCallbackInfo->bgModes,
251         asyncCallbackInfo->abilityContext->GetAbilityRecordId());
252     BGTASK_LOGD("RequestStartBackgroundRunning isBatch: %{public}d, bgModeSize: %{public}u",
253         taskParam.isBatchApi_, static_cast<uint32_t>(taskParam.bgModeIds_.size()));
254     asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestStartBackgroundRunning(taskParam);
255     asyncCallbackInfo->notificationId = taskParam.notificationId_;
256     asyncCallbackInfo->continuousTaskId = taskParam.continuousTaskId_;
257     BGTASK_LOGI("notification %{public}d, continuousTaskId %{public}d", taskParam.notificationId_,
258         taskParam.continuousTaskId_);
259 }
260 
CallbackCompletedCB(napi_env env,napi_status status,void * data)261 void CallbackCompletedCB(napi_env env, napi_status status, void *data)
262 {
263     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
264         "BackgroundTaskManager::ContinuousTask::Napi::CallbackCompletedCB");
265     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
266     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
267     napi_value callback {nullptr};
268     napi_value undefined {nullptr};
269     napi_value result[CALLBACK_RESULT_PARAMS_NUM] = {nullptr};
270     napi_value callResult = {nullptr};
271     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
272     if (asyncCallbackInfo->errCode == ERR_OK) {
273         result[0] = WrapUndefinedToJS(env);
274         napi_create_int32(env, 0, &result[1]);
275     } else {
276         result[1] = WrapUndefinedToJS(env);
277         std::string errMsg = Common::FindErrMsg(env, asyncCallbackInfo->errCode);
278         int32_t errCodeInfo = Common::FindErrCode(env, asyncCallbackInfo->errCode);
279         result[0] = Common::GetCallbackErrorValue(env, errCodeInfo, errMsg);
280     }
281 
282     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
283     NAPI_CALL_RETURN_VOID(env,
284         napi_call_function(env, undefined, callback, CALLBACK_RESULT_PARAMS_NUM, result, &callResult));
285 }
286 
PromiseCompletedCB(napi_env env,napi_status status,void * data)287 void PromiseCompletedCB(napi_env env, napi_status status, void *data)
288 {
289     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
290         "BackgroundTaskManager::ContinuousTask::Napi::PromiseCompletedCB");
291     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
292     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
293     napi_value result {nullptr};
294     if (asyncCallbackInfo->errCode == ERR_OK) {
295         if (asyncCallbackInfo->bgModes.size() > 0) {
296             napi_value slotType = nullptr;
297             napi_value contentType = nullptr;
298             napi_value notificationId = nullptr;
299             napi_value continuousTaskId = nullptr;
300             napi_create_object(env, &result);
301             napi_create_int32(env, SLOT_TYPE, &slotType);
302             napi_create_int32(env, SYSTEM_LIVE_CONTENT_TYPE, &contentType);
303             napi_create_int32(env, asyncCallbackInfo->notificationId, &notificationId);
304             napi_create_int32(env, asyncCallbackInfo->continuousTaskId, &continuousTaskId);
305             napi_set_named_property(env, result, "slotType", slotType);
306             napi_set_named_property(env, result, "contentType", contentType);
307             napi_set_named_property(env, result, "notificationId", notificationId);
308             napi_set_named_property(env, result, "continuousTaskId", continuousTaskId);
309         } else {
310             napi_create_int32(env, 0, &result);
311         }
312         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result));
313     } else {
314         std::string errMsg = Common::FindErrMsg(env, asyncCallbackInfo->errCode);
315         int32_t errCodeInfo = Common::FindErrCode(env, asyncCallbackInfo->errCode);
316         result = Common::GetCallbackErrorValue(env, errCodeInfo, errMsg);
317         NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result));
318     }
319 }
320 
ReportXPowerJsStackSysEventByType(napi_env env,const std::string & taskType)321 void ReportXPowerJsStackSysEventByType(napi_env env, const std::string &taskType)
322 {
323     #ifdef SUPPORT_JSSTACK
324         HiviewDFX::ReportXPowerJsStackSysEvent(env, taskType);
325     #endif
326 }
327 
StartBackgroundRunningAsync(napi_env env,napi_value * argv,const uint32_t argCallback,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)328 napi_value StartBackgroundRunningAsync(napi_env env, napi_value *argv,
329     const uint32_t argCallback, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
330 {
331     if (argv == nullptr || asyncCallbackInfo == nullptr) {
332         BGTASK_LOGE("param is nullptr");
333         return nullptr;
334     }
335     if (isThrow && asyncCallbackInfo->errCode != ERR_OK) {
336         return nullptr;
337     }
338     napi_value resourceName {nullptr};
339     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
340 
341     napi_valuetype valuetype = napi_undefined;
342     NAPI_CALL(env, napi_typeof(env, argv[argCallback], &valuetype));
343     if (valuetype != napi_function) {
344         Common::HandleParamErr(env, ERR_CALLBACK_NULL_OR_TYPE_ERR, isThrow);
345         BGTASK_LOGE("valuetype is no napi_function.");
346         return nullptr;
347     }
348     NAPI_CALL(env, napi_create_reference(env, argv[argCallback], 1, &asyncCallbackInfo->callback));
349     if (!StartBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
350         BGTASK_LOGE("start bgytask check param fail.");
351         return nullptr;
352     }
353 
354     NAPI_CALL(env, napi_create_async_work(env,
355         nullptr,
356         resourceName,
357         StartBackgroundRunningExecuteCB,
358         CallbackCompletedCB,
359         static_cast<void *>(asyncCallbackInfo),
360         &asyncCallbackInfo->asyncWork));
361     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
362 
363     return WrapVoidToJS(env);
364 }
365 
UpdateBackgroundRunningPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)366 napi_value UpdateBackgroundRunningPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
367 {
368     if (asyncCallbackInfo == nullptr) {
369         BGTASK_LOGE("param is nullptr");
370         return nullptr;
371     }
372     if (!CheckBackgroundMode(env, asyncCallbackInfo, isThrow)) {
373         return nullptr;
374     }
375     napi_value resourceName;
376     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
377     napi_deferred deferred;
378     napi_value promise {nullptr};
379     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
380     asyncCallbackInfo->deferred = deferred;
381     NAPI_CALL(env, napi_create_async_work(env,
382         nullptr,
383         resourceName,
384         UpdateBackgroundRunningExecuteCB,
385         PromiseCompletedCB,
386         static_cast<void *>(asyncCallbackInfo),
387         &asyncCallbackInfo->asyncWork));
388     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
389     return promise;
390 }
391 
StartBackgroundRunningPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)392 napi_value StartBackgroundRunningPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
393 {
394     if (asyncCallbackInfo == nullptr) {
395         BGTASK_LOGE("param is nullptr");
396         return nullptr;
397     }
398     napi_value resourceName;
399     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
400     napi_deferred deferred;
401     napi_value promise {nullptr};
402     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
403     asyncCallbackInfo->deferred = deferred;
404     if (!StartBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
405         BGTASK_LOGE("start bgytask check param fail.");
406         return nullptr;
407     }
408     NAPI_CALL(env, napi_create_async_work(env,
409         nullptr,
410         resourceName,
411         StartBackgroundRunningExecuteCB,
412         PromiseCompletedCB,
413         static_cast<void *>(asyncCallbackInfo),
414         &asyncCallbackInfo->asyncWork));
415     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
416     return promise;
417 }
418 
CheckTypeForNapiValue(napi_env env,napi_value param,napi_valuetype expectType)419 bool CheckTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType)
420 {
421     napi_valuetype valueType = napi_undefined;
422     if (napi_typeof(env, param, &valueType) != napi_ok) {
423         return false;
424     }
425     return valueType == expectType;
426 }
427 
GetMode(const napi_env & env,const napi_value & value,AsyncCallbackInfo * asyncCallbackInfo)428 napi_value GetMode(const napi_env &env, const napi_value &value, AsyncCallbackInfo *asyncCallbackInfo)
429 {
430     napi_valuetype valuetype = napi_undefined;
431     NAPI_CALL(env, napi_typeof(env, value, &valuetype));
432     if (valuetype != napi_number) {
433         Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, true);
434         return nullptr;
435     }
436     napi_get_value_uint32(env, value, &asyncCallbackInfo->bgMode);
437     asyncCallbackInfo->isBatchApi = false;
438     BGTASK_LOGD("get bgmode info: %{public}u", asyncCallbackInfo->bgMode);
439     return WrapVoidToJS(env);
440 }
441 
GetModes(const napi_env & env,const napi_value & value,AsyncCallbackInfo * asyncCallbackInfo)442 napi_value GetModes(const napi_env &env, const napi_value &value, AsyncCallbackInfo *asyncCallbackInfo)
443 {
444     uint32_t arrayLen = 0;
445     napi_get_array_length(env, value, &arrayLen);
446     BGTASK_LOGD("get bgModes arraylen: %{public}u", arrayLen);
447     if (arrayLen == 0) {
448         BGTASK_LOGE("get bgModes arraylen is 0");
449         Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, true);
450         return nullptr;
451     }
452     asyncCallbackInfo->isBatchApi = true;
453     for (uint32_t i = 0; i < arrayLen; i++) {
454         napi_value mode = nullptr;
455         napi_get_element(env, value, i, &mode);
456         std::string result;
457         if (Common::GetStringValue(env, mode, result) == nullptr) {
458             BGTASK_LOGE("GetStringValue failed.");
459             Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, true);
460             return nullptr;
461         }
462         BGTASK_LOGI("GetBackgroundMode %{public}s.", result.c_str());
463         auto it = std::find(g_backgroundModes.begin(), g_backgroundModes.end(), result);
464         if (it != g_backgroundModes.end()) {
465             auto index = std::distance(g_backgroundModes.begin(), it);
466             auto modeIter = std::find(asyncCallbackInfo->bgModes.begin(), asyncCallbackInfo->bgModes.end(), index + 1);
467             if (modeIter == asyncCallbackInfo->bgModes.end()) {
468                 asyncCallbackInfo->bgModes.push_back(index + 1);
469             }
470         } else {
471             BGTASK_LOGE("mode string is invalid");
472             Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, true);
473             return nullptr;
474         }
475     }
476     return WrapVoidToJS(env);
477 }
478 
GetBackgroundMode(const napi_env & env,const napi_value & value,AsyncCallbackInfo * asyncCallbackInfo)479 napi_value GetBackgroundMode(const napi_env &env, const napi_value &value, AsyncCallbackInfo *asyncCallbackInfo)
480 {
481     bool isArray = false;
482     if (napi_is_array(env, value, &isArray) != napi_ok || isArray == false) {
483         return GetMode(env, value, asyncCallbackInfo);
484     } else {
485         return GetModes(env, value, asyncCallbackInfo);
486     }
487 }
488 
GetWantAgent(const napi_env & env,const napi_value & value,std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> & wantAgent)489 napi_value GetWantAgent(const napi_env &env, const napi_value &value,
490     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> &wantAgent)
491 {
492     napi_valuetype valuetype = napi_undefined;
493     AbilityRuntime::WantAgent::WantAgent *wantAgentPtr = nullptr;
494     NAPI_CALL(env, napi_typeof(env, value, &valuetype));
495     if (valuetype != napi_object) {
496         Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, true);
497         return nullptr;
498     }
499     napi_unwrap(env, value, (void **)&wantAgentPtr);
500     if (wantAgentPtr == nullptr) {
501         return nullptr;
502     }
503     wantAgent = std::make_shared<AbilityRuntime::WantAgent::WantAgent>(*wantAgentPtr);
504 
505     return WrapVoidToJS(env);
506 }
507 
GetIncludeSuspended(const napi_env & env,const napi_value & value,bool & includeSuspended)508 napi_value GetIncludeSuspended(const napi_env &env, const napi_value &value, bool &includeSuspended)
509 {
510     napi_valuetype valuetype = napi_undefined;
511     NAPI_CALL(env, napi_typeof(env, value, &valuetype));
512     if (valuetype != napi_boolean) {
513         Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, true);
514         return nullptr;
515     }
516     napi_get_value_bool(env, value, &includeSuspended);
517     return WrapVoidToJS(env);
518 }
519 
GetAllContinuousTasksCheckParamBeforeSubmit(napi_env env,size_t argc,napi_value * argv,bool isThrow,AsyncCallbackInfo * asyncCallbackInfo)520 bool GetAllContinuousTasksCheckParamBeforeSubmit(napi_env env, size_t argc, napi_value *argv, bool isThrow,
521     AsyncCallbackInfo *asyncCallbackInfo)
522 {
523     if (argc > MAX_GET_ALL_CONTINUOUSTASK_PARAMS || argc < ARGC_ONE) {
524         BGTASK_LOGE("wrong param nums");
525         Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
526         asyncCallbackInfo->errCode = ERR_PARAM_NUMBER_ERR;
527         return false;
528     }
529     // argv[0] : context : AbilityContext
530     if (GetAbilityContext(env, argv[0], asyncCallbackInfo->abilityContext) == nullptr) {
531         BGTASK_LOGE("GetAllContinuousTasks Get ability context failed");
532         Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
533         asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
534         return false;
535     }
536 
537     // argv[1] : includeSuspended : includeSuspended
538     if (argc == ARGC_TWO && GetIncludeSuspended(env, argv[1], asyncCallbackInfo->includeSuspended) == nullptr) {
539         BGTASK_LOGE("GetAllContinuousTasks Get includeSuspended failed");
540         Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, isThrow);
541         asyncCallbackInfo->errCode = ERR_BGMODE_NULL_OR_TYPE_ERR;
542         return false;
543     }
544     return true;
545 }
546 
StartBackgroundRunningCheckParamBeforeSubmit(napi_env env,napi_value * argv,size_t len,bool isThrow,AsyncCallbackInfo * asyncCallbackInfo)547 bool StartBackgroundRunningCheckParamBeforeSubmit(napi_env env, napi_value *argv, size_t len, bool isThrow,
548     AsyncCallbackInfo *asyncCallbackInfo)
549 {
550     // argv[0] : context : AbilityContext
551     if (GetAbilityContext(env, argv[0], asyncCallbackInfo->abilityContext) == nullptr) {
552         BGTASK_LOGE("Get ability context failed");
553         Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
554         asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
555         return false;
556     }
557 
558     // argv[1] : bgMode : BackgroundMode
559     if (GetBackgroundMode(env, argv[1], asyncCallbackInfo) == nullptr) {
560         BGTASK_LOGE("input bgmode param not number");
561         Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, isThrow);
562         asyncCallbackInfo->errCode = ERR_BGMODE_NULL_OR_TYPE_ERR;
563         return false;
564     }
565 
566     // argv[2] : wantAgent: WantAgent
567     if (GetWantAgent(env, argv[2], asyncCallbackInfo->wantAgent) == nullptr) {
568         BGTASK_LOGE("input wantAgent param is not object");
569         Common::HandleParamErr(env, ERR_WANTAGENT_NULL_OR_TYPE_ERR, isThrow);
570         asyncCallbackInfo->errCode = ERR_WANTAGENT_NULL_OR_TYPE_ERR;
571         return false;
572     }
573     return true;
574 }
575 
576 
UpdateBackgroundRunning(napi_env env,napi_callback_info info,bool isThrow)577 napi_value UpdateBackgroundRunning(napi_env env, napi_callback_info info, bool isThrow)
578 {
579     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
580         "BackgroundTaskManager::ContinuousTask::Napi::UpdateBackgroundRunning");
581     ReportXPowerJsStackSysEventByType(env, "CONTINUOUS_TASK_UPDATE");
582     AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env);
583     if (asyncCallbackInfo == nullptr) {
584         BGTASK_LOGE("asyncCallbackInfo == nullpter");
585         return WrapVoidToJS(env);
586     }
587     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
588 
589     size_t argc = MAX_UPDATE_BG_RUNNING_PARAMS;
590     napi_value argv[MAX_UPDATE_BG_RUNNING_PARAMS] = {nullptr};
591     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
592     if (argc != MAX_UPDATE_BG_RUNNING_PARAMS) {
593         BGTASK_LOGE("wrong param nums");
594         Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
595         return WrapVoidToJS(env);
596     }
597 
598     // argv[0] : context : AbilityContext
599     if (GetAbilityContext(env, argv[0], asyncCallbackInfo->abilityContext) == nullptr) {
600         BGTASK_LOGE("Get ability context failed");
601         Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
602         asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
603         return WrapVoidToJS(env);
604     }
605 
606     // argv[1] : bgMode : BackgroundMode
607     if (GetBackgroundMode(env, argv[1], asyncCallbackInfo) == nullptr) {
608         BGTASK_LOGE("input bgmode param not number");
609         Common::HandleParamErr(env, ERR_BGMODE_NULL_OR_TYPE_ERR, isThrow);
610         asyncCallbackInfo->errCode = ERR_BGMODE_NULL_OR_TYPE_ERR;
611         return WrapVoidToJS(env);
612     }
613 
614     napi_value ret {nullptr};
615     ret = UpdateBackgroundRunningPromise(env, asyncCallbackInfo, isThrow);
616     callbackPtr.release();
617     if (ret == nullptr) {
618         BGTASK_LOGE("ret is nullpter");
619         if (asyncCallbackInfo != nullptr) {
620             delete asyncCallbackInfo;
621             asyncCallbackInfo = nullptr;
622         }
623         ret = WrapVoidToJS(env);
624     }
625     return ret;
626 }
627 
StartBackgroundRunning(napi_env env,napi_callback_info info,bool isThrow)628 napi_value StartBackgroundRunning(napi_env env, napi_callback_info info, bool isThrow)
629 {
630     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
631         "BackgroundTaskManager::ContinuousTask::Napi::StartBackgroundRunning");
632     ReportXPowerJsStackSysEventByType(env, "CONTINUOUS_TASK_APPLY");
633     AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env);
634     if (asyncCallbackInfo == nullptr) {
635         BGTASK_LOGE("asyncCallbackInfo == nullpter");
636         return WrapVoidToJS(env);
637     }
638     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
639 
640     size_t argc = MAX_START_BG_RUNNING_PARAMS;
641     napi_value argv[MAX_START_BG_RUNNING_PARAMS] = {nullptr};
642     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
643     if (argc > MAX_START_BG_RUNNING_PARAMS) {
644         BGTASK_LOGE("wrong param nums");
645         Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
646         return WrapVoidToJS(env);
647     }
648 
649     if (!StartBackgroundRunningCheckParamBeforeSubmit(env, argv, MAX_START_BG_RUNNING_PARAMS, isThrow,
650         asyncCallbackInfo)) {
651         BGTASK_LOGE("failed to check parameters before start bgtask running.");
652         return WrapVoidToJS(env);
653     }
654 
655     napi_value ret {nullptr};
656 
657     if (argc == MAX_START_BG_RUNNING_PARAMS) {
658         ret = StartBackgroundRunningAsync(env, argv, MAX_START_BG_RUNNING_PARAMS - 1, asyncCallbackInfo, isThrow);
659     } else {
660         ret = StartBackgroundRunningPromise(env, asyncCallbackInfo, isThrow);
661     }
662     callbackPtr.release();
663     if (ret == nullptr) {
664         BGTASK_LOGE("ret is nullpter");
665         if (asyncCallbackInfo != nullptr) {
666             delete asyncCallbackInfo;
667             asyncCallbackInfo = nullptr;
668         }
669         ret = WrapVoidToJS(env);
670     }
671     return ret;
672 }
673 
StopBackgroundRunningCheckParam(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)674 bool StopBackgroundRunningCheckParam(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
675 {
676     if (asyncCallbackInfo == nullptr) {
677         BGTASK_LOGE("asyncCallbackInfo is nullptr");
678         return false;
679     }
680     if (asyncCallbackInfo->abilityContext == nullptr) {
681         BGTASK_LOGE("ability context is null");
682         Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
683         asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
684         return false;
685     }
686     const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
687     if (info == nullptr) {
688         BGTASK_LOGE("abilityInfo is null");
689         Common::HandleParamErr(env, ERR_ABILITY_INFO_EMPTY, isThrow);
690         asyncCallbackInfo->errCode = ERR_ABILITY_INFO_EMPTY;
691         return false;
692     }
693 
694     sptr<IRemoteObject> token = asyncCallbackInfo->abilityContext->GetToken();
695     if (!token) {
696         BGTASK_LOGE("get ability token info failed");
697         Common::HandleParamErr(env, ERR_GET_TOKEN_ERR, isThrow);
698         asyncCallbackInfo->errCode = ERR_GET_TOKEN_ERR;
699         return false;
700     }
701     return true;
702 }
703 
StopBackgroundRunningExecuteCB(napi_env env,void * data)704 void StopBackgroundRunningExecuteCB(napi_env env, void *data)
705 {
706     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
707         "BackgroundTaskManager::ContinuousTask::Napi::StopBackgroundRunningExecuteCB");
708     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
709     if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
710         BGTASK_LOGE("input param error");
711         return;
712     }
713     const std::shared_ptr<AppExecFwk::AbilityInfo> info = asyncCallbackInfo->abilityContext->GetAbilityInfo();
714     sptr<IRemoteObject> token = asyncCallbackInfo->abilityContext->GetToken();
715     int32_t abilityId = asyncCallbackInfo->abilityContext->GetAbilityRecordId();
716     asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestStopBackgroundRunning(info->name, token, abilityId);
717 }
718 
StopBackgroundRunningAsync(napi_env env,napi_value * argv,const uint32_t argCallback,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)719 napi_value StopBackgroundRunningAsync(napi_env env, napi_value *argv,
720     const uint32_t argCallback, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
721 {
722     if (argv == nullptr || asyncCallbackInfo == nullptr) {
723         BGTASK_LOGE("param is nullptr");
724         return nullptr;
725     }
726     if (isThrow && asyncCallbackInfo->errCode != ERR_OK) {
727         return nullptr;
728     }
729     napi_value resourceName {nullptr};
730     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
731 
732     napi_valuetype valuetype = napi_undefined;
733     NAPI_CALL(env, napi_typeof(env, argv[argCallback], &valuetype));
734     if (valuetype != napi_function) {
735         Common::HandleParamErr(env, ERR_CALLBACK_NULL_OR_TYPE_ERR, isThrow);
736         return nullptr;
737     }
738     NAPI_CALL(env, napi_create_reference(env, argv[argCallback], 1, &asyncCallbackInfo->callback));
739     if (!StopBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
740         return nullptr;
741     }
742 
743     NAPI_CALL(env, napi_create_async_work(env,
744         nullptr,
745         resourceName,
746         StopBackgroundRunningExecuteCB,
747         CallbackCompletedCB,
748         static_cast<void *>(asyncCallbackInfo),
749         &asyncCallbackInfo->asyncWork));
750     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
751     return WrapVoidToJS(env);
752 }
753 
StopBackgroundRunningPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)754 napi_value StopBackgroundRunningPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
755 {
756     if (asyncCallbackInfo == nullptr) {
757         BGTASK_LOGE("param is nullptr");
758         return nullptr;
759     }
760     napi_value resourceName {nullptr};
761     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
762     napi_deferred deferred;
763     napi_value promise {nullptr};
764     napi_create_promise(env, &deferred, &promise);
765 
766     asyncCallbackInfo->deferred = deferred;
767     if (!StopBackgroundRunningCheckParam(env, asyncCallbackInfo, isThrow) && isThrow) {
768         return nullptr;
769     }
770 
771     napi_create_async_work(
772         env,
773         nullptr,
774         resourceName,
775         StopBackgroundRunningExecuteCB,
776         PromiseCompletedCB,
777         static_cast<void *>(asyncCallbackInfo),
778         &asyncCallbackInfo->asyncWork);
779     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
780     return promise;
781 }
782 
StopBackgroundRunning(napi_env env,napi_callback_info info,bool isThrow)783 napi_value StopBackgroundRunning(napi_env env, napi_callback_info info, bool isThrow)
784 {
785     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
786         "BackgroundTaskManager::ContinuousTask::Napi::StopBackgroundRunning");
787     ReportXPowerJsStackSysEventByType(env, "CONTINUOUS_TASK_CANCEL");
788     AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env);
789     if (asyncCallbackInfo == nullptr) {
790         BGTASK_LOGE("asyncCallbackInfo is nullpter");
791         return WrapVoidToJS(env);
792     }
793     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
794 
795     size_t argc = MAX_STOP_BG_RUNNING_PARAMS;
796     napi_value argv[MAX_STOP_BG_RUNNING_PARAMS] = {nullptr};
797 
798     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
799     if (argc > MAX_STOP_BG_RUNNING_PARAMS) {
800         BGTASK_LOGE("wrong param nums");
801         Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
802         return nullptr;
803     }
804 
805     // argv[0] : context : AbilityContext
806     if (GetAbilityContext(env, argv[0], asyncCallbackInfo->abilityContext) == nullptr) {
807         BGTASK_LOGE("Get ability context failed");
808         Common::HandleParamErr(env, ERR_CONTEXT_NULL_OR_TYPE_ERR, isThrow);
809         asyncCallbackInfo->errCode = ERR_CONTEXT_NULL_OR_TYPE_ERR;
810         return nullptr;
811     }
812 
813     napi_value ret {nullptr};
814     if (argc == MAX_STOP_BG_RUNNING_PARAMS) {
815         ret = StopBackgroundRunningAsync(env, argv, MAX_STOP_BG_RUNNING_PARAMS - 1, asyncCallbackInfo, isThrow);
816     } else {
817         ret = StopBackgroundRunningPromise(env, asyncCallbackInfo, isThrow);
818     }
819     callbackPtr.release();
820     if (ret == nullptr) {
821         BGTASK_LOGE("ret is nullpter");
822         if (asyncCallbackInfo != nullptr) {
823             delete asyncCallbackInfo;
824             asyncCallbackInfo = nullptr;
825         }
826         ret = WrapVoidToJS(env);
827     }
828     return ret;
829 }
830 
CheckOnParam(napi_env env,uint32_t argc,napi_value argv[],std::string & typeString)831 bool CheckOnParam(napi_env env, uint32_t argc, napi_value argv[], std::string& typeString)
832 {
833     if (argc < ARGC_TWO) {
834         BGTASK_LOGE("wrong param nums");
835         return false;
836     }
837     // argv[0] : type
838     if (!AbilityRuntime::ConvertFromJsValue(env, argv[INDEX_ZERO], typeString)) {
839         BGTASK_LOGE("type must be string");
840         return false;
841     }
842     auto it = std::find(g_callbackTypes.begin(), g_callbackTypes.end(), typeString);
843     if (it == g_callbackTypes.end()) {
844         BGTASK_LOGE("continuousTask type error: %{public}s", typeString.c_str());
845         return false;
846     }
847     // arg[1] : callback
848     if (!CheckTypeForNapiValue(env, argv[INDEX_ONE], napi_function)) {
849         return false;
850     }
851     return true;
852 }
853 
CheckOffParam(napi_env env,uint32_t argc,napi_value argv[],std::string & typeString)854 bool CheckOffParam(napi_env env, uint32_t argc, napi_value argv[], std::string& typeString)
855 {
856     if (argc < ARGC_ONE) {
857         BGTASK_LOGE("wrong param nums < 1");
858         return false;
859     }
860 
861     // argv[0] : type
862     if (!AbilityRuntime::ConvertFromJsValue(env, argv[INDEX_ZERO], typeString)) {
863         BGTASK_LOGE("type must be string");
864         return false;
865     }
866     auto it = std::find(g_callbackTypes.begin(), g_callbackTypes.end(), typeString);
867     if (it == g_callbackTypes.end()) {
868         BGTASK_LOGE("continuousTask type error: %{public}s", typeString.c_str());
869         return false;
870     }
871     // arg[1] : callback
872     if (argc == ARGC_TWO) {
873         if (!CheckTypeForNapiValue(env, argv[INDEX_ONE], napi_function)) {
874             return false;
875         }
876     }
877     return true;
878 }
879 
SubscribeBackgroundTask(napi_env env,uint32_t flag=0)880 bool SubscribeBackgroundTask(napi_env env, uint32_t flag = 0)
881 {
882     if (backgroundTaskSubscriber_ == nullptr) {
883         backgroundTaskSubscriber_ = std::make_shared<JsBackgroundTaskSubscriber>(env);
884         if (backgroundTaskSubscriber_ == nullptr) {
885             BGTASK_LOGE("ret is nullptr");
886             Common::HandleErrCode(env, ERR_BGTASK_SERVICE_INNER_ERROR, true);
887             return false;
888         }
889     }
890     backgroundTaskSubscriber_->SetFlag(flag, true);
891     ErrCode errCode = BackgroundTaskMgrHelper::SubscribeBackgroundTask(*backgroundTaskSubscriber_);
892     if (errCode != ERR_OK) {
893         BGTASK_LOGE("SubscribeBackgroundTask failed.");
894         Common::HandleErrCode(env, errCode, true);
895         return false;
896     }
897     return true;
898 }
899 
UnSubscribeBackgroundTask(napi_env env,uint32_t flag=0)900 void UnSubscribeBackgroundTask(napi_env env, uint32_t flag = 0)
901 {
902     if (!backgroundTaskSubscriber_->IsEmpty()) {
903         return;
904     }
905     backgroundTaskSubscriber_->SetFlag(flag, false);
906     ErrCode errCode = BackgroundTaskMgrHelper::UnsubscribeBackgroundTask(*backgroundTaskSubscriber_);
907     if (errCode != ERR_OK) {
908         BGTASK_LOGE("UnsubscribeBackgroundTask failed.");
909         Common::HandleErrCode(env, errCode, true);
910         return;
911     }
912     backgroundTaskSubscriber_->UnSubscriberBgtaskSaStatusChange();
913     backgroundTaskSubscriber_ = nullptr;
914 }
915 
OnOnContinuousTaskCallback(napi_env env,napi_callback_info info)916 napi_value OnOnContinuousTaskCallback(napi_env env, napi_callback_info info)
917 {
918     size_t argc = ARGC_TWO;
919     napi_value argv[ARGC_TWO] = {nullptr};
920     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
921     std::string typeString;
922     if (!CheckOnParam(env, argc, argv, typeString)) {
923         Common::HandleParamErr(env, ERR_BGTASK_INVALID_PARAM, true);
924         return WrapUndefinedToJS(env);
925     }
926     uint32_t type = 0;
927     if (typeString == "continuousTaskCancel") {
928         type = CONTINUOUS_TASK_CANCEL;
929     } else if (typeString == "continuousTaskSuspend") {
930         type = CONTINUOUS_TASK_SUSPEND;
931     } else if (typeString == "continuousTaskActive") {
932         type = CONTINUOUS_TASK_ACTIVE;
933     }
934     BGTASK_LOGD("SubscribeBackgroundTask type: %{public}s, type: %{public}d", typeString.c_str(), type);
935     if (!SubscribeBackgroundTask(env, type)) {
936         return WrapUndefinedToJS(env);
937     }
938     backgroundTaskSubscriber_->AddJsObserverObject(typeString, argv[INDEX_ONE]);
939     backgroundTaskSubscriber_->SubscriberBgtaskSaStatusChange();
940     return WrapUndefinedToJS(env);
941 }
942 
OffOnContinuousTaskCallback(napi_env env,napi_callback_info info)943 napi_value OffOnContinuousTaskCallback(napi_env env, napi_callback_info info)
944 {
945     size_t argc = ARGC_TWO;
946     napi_value argv[ARGC_TWO] = {nullptr};
947     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
948     std::string typeString;
949     if (!CheckOffParam(env, argc, argv, typeString)) {
950         Common::HandleParamErr(env, ERR_BGTASK_INVALID_PARAM, true);
951         return WrapUndefinedToJS(env);
952     }
953     if (!backgroundTaskSubscriber_) {
954         BGTASK_LOGE("backgroundTaskSubscriber_ is null, return");
955         return WrapUndefinedToJS(env);
956     }
957     if (argc == ARGC_ONE) {
958         backgroundTaskSubscriber_->RemoveJsObserverObjects(typeString);
959     } else if (argc == ARGC_TWO) {
960         backgroundTaskSubscriber_->RemoveJsObserverObject(typeString, argv[INDEX_ONE]);
961     }
962 
963     uint32_t type = 0;
964     if (backgroundTaskSubscriber_-> IsTypeEmpty(typeString)) {
965         if (typeString == "continuousTaskCancel") {
966             type = CONTINUOUS_TASK_CANCEL;
967         } else if (typeString == "continuousTaskSuspend") {
968             type = CONTINUOUS_TASK_SUSPEND;
969         } else if (typeString == "continuousTaskActive") {
970             type = CONTINUOUS_TASK_ACTIVE;
971         }
972     }
973     UnSubscribeBackgroundTask(env, type);
974     return WrapUndefinedToJS(env);
975 }
976 
GetAllContinuousTasksExecuteCB(napi_env env,void * data)977 void GetAllContinuousTasksExecuteCB(napi_env env, void *data)
978 {
979     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
980         "BackgroundTaskManager::ContinuousTask::Napi::GetAllContinuousTasksExecuteCB");
981     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
982     if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
983         BGTASK_LOGE("input params error");
984         return;
985     }
986     asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestGetAllContinuousTasks(asyncCallbackInfo->list);
987 }
988 
GetAllContinuousTasksIncludeSuspendedExecuteCB(napi_env env,void * data)989 void GetAllContinuousTasksIncludeSuspendedExecuteCB(napi_env env, void *data)
990 {
991     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
992         "BackgroundTaskManager::ContinuousTask::Napi::GetAllContinuousTasksIncludeSuspendedExecuteCB");
993     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
994     if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
995         BGTASK_LOGE("input params error");
996         return;
997     }
998     asyncCallbackInfo->errCode = BackgroundTaskMgrHelper::RequestGetAllContinuousTasks(
999         asyncCallbackInfo->list, asyncCallbackInfo->includeSuspended);
1000 }
1001 
GetAllContinuousTasksPromiseCompletedCB(napi_env env,napi_status status,void * data)1002 void GetAllContinuousTasksPromiseCompletedCB(napi_env env, napi_status status, void *data)
1003 {
1004     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
1005         "BackgroundTaskManager::ContinuousTask::Napi::GetAllContinuousTasksPromiseCompletedCB");
1006     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
1007     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
1008     napi_value result {nullptr};
1009     if (asyncCallbackInfo->errCode == ERR_OK) {
1010         if (asyncCallbackInfo->list.size() > 0) {
1011             NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &result));
1012             uint32_t count = 0;
1013             for (const auto &continuoustTaskInfo : asyncCallbackInfo->list) {
1014                 napi_value napiWork = Common::GetNapiContinuousTaskInfo(env, continuoustTaskInfo);
1015                 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, count, napiWork));
1016                 count++;
1017             }
1018         } else {
1019             NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &result));
1020         }
1021         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result));
1022     } else {
1023         std::string errMsg = Common::FindErrMsg(env, asyncCallbackInfo->errCode);
1024         int32_t errCodeInfo = Common::FindErrCode(env, asyncCallbackInfo->errCode);
1025         result = Common::GetCallbackErrorValue(env, errCodeInfo, errMsg);
1026         NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result));
1027     }
1028     callbackPtr.release();
1029 }
1030 
GetAllContinuousTasksPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)1031 napi_value GetAllContinuousTasksPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
1032 {
1033     if (asyncCallbackInfo == nullptr) {
1034         BGTASK_LOGE("param is nullptr");
1035         return nullptr;
1036     }
1037     napi_value resourceName;
1038     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1039     napi_deferred deferred;
1040     napi_value promise {nullptr};
1041     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1042     asyncCallbackInfo->deferred = deferred;
1043     NAPI_CALL(env, napi_create_async_work(env,
1044         nullptr,
1045         resourceName,
1046         GetAllContinuousTasksExecuteCB,
1047         GetAllContinuousTasksPromiseCompletedCB,
1048         static_cast<void *>(asyncCallbackInfo),
1049         &asyncCallbackInfo->asyncWork));
1050     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1051     return promise;
1052 }
1053 
GetAllContinuousTasksIncludeSuspendedPromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,bool isThrow)1054 napi_value GetAllContinuousTasksIncludeSuspendedPromise(
1055     napi_env env, AsyncCallbackInfo *asyncCallbackInfo, bool isThrow)
1056 {
1057     if (asyncCallbackInfo == nullptr) {
1058         BGTASK_LOGE("param is nullptr");
1059         return nullptr;
1060     }
1061     napi_value resourceName;
1062     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1063     napi_deferred deferred;
1064     napi_value promise {nullptr};
1065     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1066     asyncCallbackInfo->deferred = deferred;
1067     NAPI_CALL(env, napi_create_async_work(env,
1068         nullptr,
1069         resourceName,
1070         GetAllContinuousTasksIncludeSuspendedExecuteCB,
1071         GetAllContinuousTasksPromiseCompletedCB,
1072         static_cast<void *>(asyncCallbackInfo),
1073         &asyncCallbackInfo->asyncWork));
1074     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1075     return promise;
1076 }
1077 
GetAllContinuousTasks(napi_env env,napi_callback_info info,bool isThrow)1078 napi_value GetAllContinuousTasks(napi_env env, napi_callback_info info, bool isThrow)
1079 {
1080     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
1081         "BackgroundTaskManager::ContinuousTask::Napi::GetAllContinuousTasks");
1082     if (env == nullptr) {
1083         BGTASK_LOGE("env param invaild.");
1084         return WrapVoidToJS(env);
1085     }
1086     ReportXPowerJsStackSysEventByType(env, "GET_ALL_CONTINUOUS_TASK");
1087     AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env);
1088     if (asyncCallbackInfo == nullptr) {
1089         BGTASK_LOGE("asyncCallbackInfo == nullpter");
1090         return WrapVoidToJS(env);
1091     }
1092     std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
1093 
1094     size_t argc = MAX_GET_ALL_CONTINUOUSTASK_PARAMS;
1095     napi_value argv[MAX_GET_ALL_CONTINUOUSTASK_PARAMS] = {nullptr};
1096     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
1097 
1098     if (!GetAllContinuousTasksCheckParamBeforeSubmit(env, argc, argv, isThrow, asyncCallbackInfo)) {
1099         callbackPtr.release();
1100         if (asyncCallbackInfo != nullptr) {
1101             delete asyncCallbackInfo;
1102             asyncCallbackInfo = nullptr;
1103         }
1104         return WrapVoidToJS(env);
1105     }
1106 
1107     napi_value ret {nullptr};
1108     if (argc == ARGC_ONE) {
1109         ret = GetAllContinuousTasksPromise(env, asyncCallbackInfo, isThrow);
1110     } else {
1111         ret = GetAllContinuousTasksIncludeSuspendedPromise(env, asyncCallbackInfo, isThrow);
1112     }
1113     callbackPtr.release();
1114     if (ret == nullptr) {
1115         BGTASK_LOGE("ret is nullpter");
1116         if (asyncCallbackInfo != nullptr) {
1117             delete asyncCallbackInfo;
1118             asyncCallbackInfo = nullptr;
1119         }
1120         ret = WrapVoidToJS(env);
1121     }
1122     return ret;
1123 }
1124 
StartBackgroundRunning(napi_env env,napi_callback_info info)1125 napi_value StartBackgroundRunning(napi_env env, napi_callback_info info)
1126 {
1127     return StartBackgroundRunning(env, info, false);
1128 }
1129 
StopBackgroundRunning(napi_env env,napi_callback_info info)1130 napi_value StopBackgroundRunning(napi_env env, napi_callback_info info)
1131 {
1132     return StopBackgroundRunning(env, info, false);
1133 }
1134 
StartBackgroundRunningThrow(napi_env env,napi_callback_info info)1135 napi_value StartBackgroundRunningThrow(napi_env env, napi_callback_info info)
1136 {
1137     return StartBackgroundRunning(env, info, true);
1138 }
1139 
UpdateBackgroundRunningThrow(napi_env env,napi_callback_info info)1140 napi_value UpdateBackgroundRunningThrow(napi_env env, napi_callback_info info)
1141 {
1142     return UpdateBackgroundRunning(env, info, true);
1143 }
1144 
StopBackgroundRunningThrow(napi_env env,napi_callback_info info)1145 napi_value StopBackgroundRunningThrow(napi_env env, napi_callback_info info)
1146 {
1147     return StopBackgroundRunning(env, info, true);
1148 }
1149 
GetAllContinuousTasksThrow(napi_env env,napi_callback_info info)1150 napi_value GetAllContinuousTasksThrow(napi_env env, napi_callback_info info)
1151 {
1152     return GetAllContinuousTasks(env, info, true);
1153 }
1154 }  // namespace BackgroundTaskMgr
1155 }  // namespace OHOS