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, ¬ificationId);
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