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