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_mgr.h"
17 #include "background_task_mgr_service.h"
18
19 #include <sstream>
20 #include <unistd.h>
21 #include <fcntl.h>
22
23 #include "app_mgr_client.h"
24 #include "bundle_constants.h"
25 #include "bundle_manager_helper.h"
26 #include "common_event_support.h"
27 #include "common_event_manager.h"
28 #include "common_utils.h"
29 #include "errors.h"
30 #include "hitrace_meter.h"
31 #include "if_system_ability_manager.h"
32 #include "hisysevent.h"
33 #include "iremote_object.h"
34 #include "iservice_registry.h"
35 #ifdef HAS_OS_ACCOUNT_PART
36 #include "os_account_manager.h"
37 #endif // HAS_OS_ACCOUNT_PART
38 #include "notification_tools.h"
39 #include "running_process_info.h"
40 #include "string_wrapper.h"
41 #include "system_ability_definition.h"
42
43 #include "bgtask_common.h"
44 #include "bgtask_config.h"
45 #include "bgtask_hitrace_chain.h"
46 #include "bgtaskmgr_inner_errors.h"
47 #include "continuous_task_record.h"
48 #include "continuous_task_log.h"
49 #include "system_event_observer.h"
50 #include "data_storage_helper.h"
51 #ifdef SUPPORT_GRAPHICS
52 #include "locale_config.h"
53 #endif // SUPPORT_GRAPHICS
54 #include "background_mode.h"
55 #include "background_sub_mode.h"
56 #include "continuous_task_suspend_reason.h"
57
58 namespace OHOS {
59 namespace BackgroundTaskMgr {
60 namespace {
61 static const char *g_taskPromptResNames[] = {
62 "ohos_bgmode_prompt_data_transfer",
63 "ohos_bgmode_prompt_audio_playback",
64 "ohos_bgmode_prompt_audio_recording",
65 "ohos_bgmode_prompt_location",
66 "ohos_bgmode_prompt_bluetooth_interaction",
67 "ohos_bgmode_prompt_multidevice_connection",
68 "ohos_bgmode_prompt_wifi_interaction",
69 "ohos_bgmode_prompt_voip",
70 "ohos_bgmode_prompt_task_keeping",
71 "ohos_bgmode_prompt_default_value",
72 };
73
74 static const char *g_taskPromptResNamesSubMode[] = {
75 "ohos_bgsubmode_prompt_car_key",
76 };
77
78 static constexpr char SEPARATOR[] = "_";
79 static constexpr char DUMP_PARAM_LIST_ALL[] = "--all";
80 static constexpr char DUMP_PARAM_CANCEL_ALL[] = "--cancel_all";
81 static constexpr char DUMP_PARAM_CANCEL[] = "--cancel";
82 static constexpr char DUMP_PARAM_GET[] = "--get";
83 static constexpr char DUMP_INNER_TASK[] = "--inner_task";
84 static constexpr char BGMODE_PERMISSION[] = "ohos.permission.KEEP_BACKGROUND_RUNNING";
85 static constexpr char BG_TASK_RES_BUNDLE_NAME[] = "com.ohos.backgroundtaskmgr.resources";
86 static constexpr char BG_TASK_SUB_MODE_TYPE[] = "subMode";
87 static constexpr uint32_t SYSTEM_APP_BGMODE_WIFI_INTERACTION = 64;
88 static constexpr uint32_t PC_BGMODE_TASK_KEEPING = 256;
89 static constexpr int32_t DELAY_TIME = 2000;
90 static constexpr int32_t RECLAIM_MEMORY_DELAY_TIME = 20 * 60 * 1000;
91 static constexpr int32_t MAX_DUMP_PARAM_NUMS = 3;
92 static constexpr int32_t MAX_DUMP_INNER_PARAM_NUMS = 4;
93 static constexpr uint32_t INVALID_BGMODE = 0;
94 static constexpr uint32_t BG_MODE_INDEX_HEAD = 1;
95 static constexpr uint32_t BGMODE_NUMS = 10;
96 static constexpr uint32_t VOIP_SA_UID = 7022;
97 static constexpr uint32_t AVSESSION_SA_UID = 6700;
98 static constexpr uint32_t CONTINUOUS_TASK_SUSPEND = 2;
99 #ifdef FEATURE_PRODUCT_WATCH
100 static constexpr uint32_t HEALTHSPORT_SA_UID = 7500;
101 #else
102 static constexpr uint32_t HEALTHSPORT_SA_UID = 7259;
103 #endif
104 static constexpr uint32_t ALL_MODES = 0xFF;
105
106 #ifndef HAS_OS_ACCOUNT_PART
107 constexpr int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part
108 constexpr int32_t UID_TRANSFORM_DIVISOR = 200000;
GetOsAccountIdFromUid(int32_t uid,int32_t & osAccountId)109 static void GetOsAccountIdFromUid(int32_t uid, int32_t &osAccountId)
110 {
111 osAccountId = uid / UID_TRANSFORM_DIVISOR;
112 }
113 #endif // HAS_OS_ACCOUNT_PART
114 }
115
BgContinuousTaskMgr()116 BgContinuousTaskMgr::BgContinuousTaskMgr() {}
117
~BgContinuousTaskMgr()118 BgContinuousTaskMgr::~BgContinuousTaskMgr() {}
119
Init(const std::shared_ptr<AppExecFwk::EventRunner> & runner)120 bool BgContinuousTaskMgr::Init(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
121 {
122 BGTASK_LOGI("BgContinuousTaskMgr service init start");
123 if (runner == nullptr) {
124 BGTASK_LOGE("BgContinuousTaskMgr runner create failed!");
125 return false;
126 }
127 handler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
128 if (handler_ == nullptr) {
129 BGTASK_LOGE("BgContinuousTaskMgr handler create failed!");
130 return false;
131 }
132 std::string identity = IPCSkeleton::ResetCallingIdentity();
133 bgTaskUid_ = IPCSkeleton::GetCallingUid();
134 BGTASK_LOGI("BgContinuousTaskMgr service uid is: %{public}d", bgTaskUid_);
135 IPCSkeleton::SetCallingIdentity(identity);
136 auto registerTask = [this]() { this->InitNecessaryState(); };
137 handler_->PostSyncTask(registerTask);
138 auto self = shared_from_this();
139 auto reclaimTask = [self]() {
140 if (self) {
141 self->ReclaimProcessMemory(getpid());
142 }
143 };
144 handler_->PostTask(reclaimTask, RECLAIM_MEMORY_DELAY_TIME);
145 return true;
146 }
147
ReclaimProcessMemory(int32_t pid)148 void BgContinuousTaskMgr::ReclaimProcessMemory(int32_t pid)
149 {
150 BGTASK_LOGI("BgContinuousTaskMgr reclaimProcessMemory pid: %{public}d start.", pid);
151 std::string path = "/proc/" + std::to_string(pid) + "/reclaim";
152 std::string contentStr = "1";
153 FILE *file = fopen(path.c_str(), "w");
154 if (file == nullptr) {
155 BGTASK_LOGE("Fail to open file: %{private}s, errno: %{public}s", path.c_str(), strerror(errno));
156 return;
157 }
158 size_t res = fwrite(contentStr.c_str(), 1, contentStr.length(), file);
159 if (res != contentStr.length()) {
160 BGTASK_LOGE("Fail to write file: %{private}s, errno: %{public}s", path.c_str(), strerror(errno));
161 }
162 int closeResult = fclose(file);
163 if (closeResult < 0) {
164 BGTASK_LOGE("Fail to close file: %{private}s, errno: %{public}s", path.c_str(), strerror(errno));
165 }
166 BGTASK_LOGI("BgContinuousTaskMgr reclaimProcessMemory pid: %{public}d end.", pid);
167 }
168
Clear()169 void BgContinuousTaskMgr::Clear()
170 {
171 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
172 Notification::NotificationHelper::UnSubscribeNotification(*subscriber_);
173 #endif
174 if (systemEventListener_ != nullptr) {
175 systemEventListener_->Unsubscribe();
176 }
177 UnregisterAppStateObserver();
178 }
179
InitNecessaryState()180 void BgContinuousTaskMgr::InitNecessaryState()
181 {
182 sptr<ISystemAbilityManager> systemAbilityManager
183 = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
184 if (systemAbilityManager == nullptr
185 || systemAbilityManager->CheckSystemAbility(APP_MGR_SERVICE_ID) == nullptr
186 || systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) == nullptr
187 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
188 || systemAbilityManager->CheckSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID) == nullptr
189 #endif
190 || systemAbilityManager->CheckSystemAbility(COMMON_EVENT_SERVICE_ID) == nullptr) {
191 BGTASK_LOGW("request system service is not ready yet!");
192 auto task = [this]() { this->InitNecessaryState(); };
193 handler_->PostTask(task, DELAY_TIME);
194 return;
195 }
196
197 if (!RegisterNotificationSubscriber()) {
198 return;
199 }
200 if (!RegisterAppStateObserver()) {
201 return;
202 }
203 if (!RegisterSysCommEventListener()) {
204 return;
205 }
206 if (!RegisterConfigurationObserver()) {
207 return;
208 }
209 InitRequiredResourceInfo();
210 }
211
HandlePersistenceData()212 void BgContinuousTaskMgr::HandlePersistenceData()
213 {
214 BGTASK_LOGI("service restart, restore data");
215 DelayedSingleton<DataStorageHelper>::GetInstance()->RestoreTaskRecord(continuousTaskInfosMap_);
216 auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
217 std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos;
218 if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
219 BGTASK_LOGW("connect to app mgr service failed");
220 return;
221 }
222 appMgrClient->GetAllRunningProcesses(allAppProcessInfos);
223 CheckPersistenceData(allAppProcessInfos);
224 DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
225 }
226
CheckProcessUidInfo(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t uid)227 bool BgContinuousTaskMgr::CheckProcessUidInfo(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
228 int32_t uid)
229 {
230 for (const auto &runningProcessInfo : allProcesses) {
231 if (runningProcessInfo.uid_ == uid) {
232 return true;
233 }
234 }
235 return false;
236 }
237
CheckPersistenceData(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses)238 void BgContinuousTaskMgr::CheckPersistenceData(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses)
239 {
240 auto iter = continuousTaskInfosMap_.begin();
241 int32_t maxNotificationId = -1;
242 int32_t maxContinuousTaskId = -1;
243
244 while (iter != continuousTaskInfosMap_.end()) {
245 bool pidIsAlive = checkPidCondition(allProcesses, iter->second->GetPid());
246 int32_t notificationId = iter->second->GetNotificationId();
247 if (notificationId > maxNotificationId) {
248 maxNotificationId = notificationId;
249 }
250 if (iter->second->continuousTaskId_ > maxContinuousTaskId) {
251 maxContinuousTaskId = iter->second->continuousTaskId_;
252 }
253
254 if (pidIsAlive) {
255 if (iter->second->GetNotificationId() == -1) {
256 BGTASK_LOGI("notification id is -1, continue");
257 iter++;
258 continue;
259 }
260 if (cachedBundleInfos_.find(iter->second->GetUid()) == cachedBundleInfos_.end()) {
261 std::string mainAbilityLabel = GetMainAbilityLabel(iter->second->GetBundleName(),
262 iter->second->GetUserId());
263 SetCachedBundleInfo(iter->second->GetUid(), iter->second->GetUserId(),
264 iter->second->GetBundleName(), mainAbilityLabel);
265 }
266 SendContinuousTaskNotification(iter->second);
267 BGTASK_LOGI("restore notification id %{public}d", iter->second->GetNotificationId());
268 iter++;
269 } else {
270 BGTASK_LOGI("process %{public}d die, not restore notification id %{public}d", iter->second->GetPid(),
271 iter->second->GetNotificationId());
272 iter = continuousTaskInfosMap_.erase(iter);
273 }
274 }
275 if (maxNotificationId != -1) {
276 BGTASK_LOGI("set maxNotificationId %{public}d", maxNotificationId);
277 NotificationTools::SetNotificationIdIndex(maxNotificationId);
278 }
279 if (maxContinuousTaskId != -1) {
280 BGTASK_LOGI("set maxContinuousTaskId %{public}d", maxContinuousTaskId);
281 continuousTaskIdIndex_ = maxContinuousTaskId;
282 }
283 }
284
checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t pid)285 bool BgContinuousTaskMgr::checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
286 int32_t pid)
287 {
288 auto findPid = [pid](const auto &target) {
289 return pid == target.pid_;
290 };
291 auto findPidIter = find_if(allProcesses.begin(), allProcesses.end(), findPid);
292 return findPidIter != allProcesses.end();
293 }
294
checkNotificationCondition(const std::set<std::string> & notificationLabels,const std::string & label)295 bool BgContinuousTaskMgr::checkNotificationCondition(const std::set<std::string> ¬ificationLabels,
296 const std::string &label)
297 {
298 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
299 auto findLabel = [label](const auto &target) {
300 return label == target;
301 };
302 auto findLabelIter = find_if(notificationLabels.begin(), notificationLabels.end(), findLabel);
303 return findLabelIter != notificationLabels.end();
304 #else
305 return true;
306 #endif
307 }
308
InitRequiredResourceInfo()309 void BgContinuousTaskMgr::InitRequiredResourceInfo()
310 {
311 if (!GetNotificationPrompt()) {
312 BGTASK_LOGW("init required resource info failed");
313 }
314 HandlePersistenceData();
315 isSysReady_.store(true);
316 DelayedSingleton<BackgroundTaskMgrService>::GetInstance()->SetReady(ServiceReadyState::CONTINUOUS_SERVICE_READY);
317 BGTASK_LOGI("SetReady CONTINUOUS_SERVICE_READY");
318 }
319
RegisterNotificationSubscriber()320 bool BgContinuousTaskMgr::RegisterNotificationSubscriber()
321 {
322 bool res = true;
323 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
324 subscriber_ = std::make_shared<TaskNotificationSubscriber>();
325 if (Notification::NotificationHelper::SubscribeNotificationSelf(*subscriber_) != ERR_OK) {
326 BGTASK_LOGE("SubscribeNotificationSelf failed!");
327 res = false;
328 }
329 #endif
330 return res;
331 }
332
RegisterAppStateObserver()333 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterAppStateObserver()
334 {
335 appStateObserver_ = new (std::nothrow) AppStateObserver(); // must be sprt
336 if (!appStateObserver_) {
337 BGTASK_LOGE("appStateObserver_ null");
338 return false;
339 }
340 auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
341 RegisterApplicationStateObserver(appStateObserver_);
342 if (res != ERR_OK) {
343 BGTASK_LOGE("RegisterApplicationStateObserver error");
344 return false;
345 }
346 appStateObserver_->SetEventHandler(handler_);
347 return true;
348 }
349
UnregisterAppStateObserver()350 void BgContinuousTaskMgr::UnregisterAppStateObserver()
351 {
352 if (!appStateObserver_) {
353 return;
354 }
355 auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
356 UnregisterApplicationStateObserver(appStateObserver_);
357 if (res != ERR_OK) {
358 BGTASK_LOGE("UnregisterApplicationStateObserver error");
359 return;
360 }
361 appStateObserver_ = nullptr;
362 BGTASK_LOGI("UnregisterApplicationStateObserver ok");
363 }
364
RegisterConfigurationObserver()365 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterConfigurationObserver()
366 {
367 auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
368 if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
369 BGTASK_LOGW("connect to app mgr service failed");
370 return false;
371 }
372 configChangeObserver_ = sptr<AppExecFwk::IConfigurationObserver>(
373 new (std::nothrow) ConfigChangeObserver(handler_, shared_from_this()));
374 if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) {
375 return false;
376 }
377 return true;
378 }
379
GetBundleResMgr(const AppExecFwk::BundleInfo & bundleInfo)380 std::shared_ptr<Global::Resource::ResourceManager> BgContinuousTaskMgr::GetBundleResMgr(
381 const AppExecFwk::BundleInfo &bundleInfo)
382 {
383 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
384 if (!resourceManager) {
385 BGTASK_LOGE("create resourceManager failed");
386 return nullptr;
387 }
388 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
389 std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
390 if (moduleResPath.empty()) {
391 continue;
392 }
393 BGTASK_LOGD("GetBundleResMgr, moduleResPath: %{private}s", moduleResPath.c_str());
394 if (!resourceManager->AddResource(moduleResPath.c_str())) {
395 BGTASK_LOGW("GetBundleResMgr AddResource failed");
396 }
397 }
398 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
399 #ifdef SUPPORT_GRAPHICS
400 UErrorCode status = U_ZERO_ERROR;
401 icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
402 if (resConfig != nullptr) {
403 resConfig->SetLocaleInfo(locale);
404 }
405 #endif // SUPPORT_GRAPHICS
406 resourceManager->UpdateResConfig(*resConfig);
407 return resourceManager;
408 }
409
GetNotificationPrompt()410 bool BgContinuousTaskMgr::GetNotificationPrompt()
411 {
412 BgTaskHiTraceChain traceChain(__func__);
413 continuousTaskText_.clear();
414 continuousTaskSubText_.clear();
415 AppExecFwk::BundleInfo bundleInfo;
416 if (!BundleManagerHelper::GetInstance()->GetBundleInfo(BG_TASK_RES_BUNDLE_NAME,
417 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo)) {
418 BGTASK_LOGE("get background task res: %{public}s bundle info failed", BG_TASK_RES_BUNDLE_NAME);
419 return false;
420 }
421 auto resourceManager = GetBundleResMgr(bundleInfo);
422 if (resourceManager == nullptr) {
423 BGTASK_LOGE("Get bgtask resource hap manager failed");
424 return false;
425 }
426 std::string taskText {""};
427 for (std::string name : g_taskPromptResNames) {
428 resourceManager->GetStringByName(name.c_str(), taskText);
429 if (taskText.empty()) {
430 BGTASK_LOGE("get continuous task notification text failed!");
431 return false;
432 }
433 BGTASK_LOGI("get taskText: %{public}s", taskText.c_str());
434 continuousTaskText_.push_back(taskText);
435 }
436 std::string taskSubText {""};
437 for (std::string name : g_taskPromptResNamesSubMode) {
438 resourceManager->GetStringByName(name.c_str(), taskSubText);
439 if (taskSubText.empty()) {
440 BGTASK_LOGE("get continuous task notification sub text failed!");
441 return false;
442 }
443 BGTASK_LOGI("get sub taskSubText: %{public}s", taskSubText.c_str());
444 continuousTaskSubText_.push_back(taskSubText);
445 }
446 return true;
447 }
448
RegisterSysCommEventListener()449 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterSysCommEventListener()
450 {
451 bool res = true;
452 EventFwk::MatchingSkills matchingSkills;
453 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
454 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
455 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
456 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED);
457 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED);
458 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED);
459 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED);
460 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
461 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
462 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
463 EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills);
464 systemEventListener_ = std::make_shared<SystemEventObserver>(commonEventSubscribeInfo);
465 if (systemEventListener_ != nullptr) {
466 systemEventListener_->SetEventHandler(handler_);
467 systemEventListener_->SetBgContinuousTaskMgr(shared_from_this());
468 res = systemEventListener_->Subscribe();
469 }
470 return res;
471 }
472
GetBgTaskUid()473 int32_t BgContinuousTaskMgr::GetBgTaskUid()
474 {
475 return bgTaskUid_;
476 }
477
SetCachedBundleInfo(int32_t uid,int32_t userId,const std::string & bundleName,const std::string & appName)478 bool BgContinuousTaskMgr::SetCachedBundleInfo(int32_t uid, int32_t userId,
479 const std::string &bundleName, const std::string &appName)
480 {
481 BgTaskHiTraceChain traceChain(__func__);
482 AppExecFwk::BundleInfo bundleInfo;
483 if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
484 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
485 BGTASK_LOGE("get bundle info: %{public}s failure!", bundleName.c_str());
486 return false;
487 }
488
489 CachedBundleInfo cachedBundleInfo = CachedBundleInfo();
490 cachedBundleInfo.appName_ = appName;
491 if (AddAbilityBgModeInfos(bundleInfo, cachedBundleInfo)) {
492 cachedBundleInfos_.emplace(uid, cachedBundleInfo);
493 return true;
494 }
495 return false;
496 }
497
AddAbilityBgModeInfos(const AppExecFwk::BundleInfo & bundleInfo,CachedBundleInfo & cachedBundleInfo)498 bool BgContinuousTaskMgr::AddAbilityBgModeInfos(const AppExecFwk::BundleInfo &bundleInfo,
499 CachedBundleInfo &cachedBundleInfo)
500 {
501 for (auto abilityInfo : bundleInfo.abilityInfos) {
502 if (abilityInfo.backgroundModes != INVALID_BGMODE) {
503 cachedBundleInfo.abilityBgMode_.emplace(abilityInfo.name, abilityInfo.backgroundModes);
504 BGTASK_LOGI("abilityName: %{public}s, abilityNameHash: %{public}s, Background Mode: %{public}u.",
505 abilityInfo.name.c_str(), std::to_string(std::hash<std::string>()(abilityInfo.name)).c_str(),
506 abilityInfo.backgroundModes);
507 }
508 }
509 if (cachedBundleInfo.abilityBgMode_.empty()) {
510 return false;
511 }
512 return true;
513 }
514
CheckBgmodeType(uint32_t configuredBgMode,uint32_t requestedBgModeId,bool isNewApi,const std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord)515 ErrCode BgContinuousTaskMgr::CheckBgmodeType(uint32_t configuredBgMode, uint32_t requestedBgModeId,
516 bool isNewApi, const std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord)
517 {
518 BgTaskHiTraceChain traceChain(__func__);
519 if (!isNewApi) {
520 if (configuredBgMode == INVALID_BGMODE) {
521 BGTASK_LOGE("ability without background mode config");
522 return ERR_BGMODE_NULL_OR_TYPE_ERR;
523 } else {
524 return ERR_OK;
525 }
526 } else {
527 uint32_t recordedBgMode = BG_MODE_INDEX_HEAD << (requestedBgModeId - 1);
528 if (recordedBgMode == SYSTEM_APP_BGMODE_WIFI_INTERACTION && !continuousTaskRecord->IsSystem()) {
529 BGTASK_LOGE("wifiInteraction background mode only support for system app");
530 return ERR_BGTASK_NOT_SYSTEM_APP;
531 }
532 if (recordedBgMode == PC_BGMODE_TASK_KEEPING && !AllowUseTaskKeeping(continuousTaskRecord)) {
533 BGTASK_LOGE("task keeping is not supported, please set param persist.sys.bgtask_support_task_keeping.");
534 return ERR_BGTASK_KEEPING_TASK_VERIFY_ERR;
535 }
536 if (requestedBgModeId == INVALID_BGMODE || (configuredBgMode &
537 (BG_MODE_INDEX_HEAD << (requestedBgModeId - 1))) == 0) {
538 BGTASK_LOGE("requested background mode is not declared in config file, configuredBgMode: %{public}d",
539 configuredBgMode);
540 return ERR_BGTASK_INVALID_BGMODE;
541 }
542 }
543 return ERR_OK;
544 }
545
AllowUseTaskKeeping(const std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord)546 bool BgContinuousTaskMgr::AllowUseTaskKeeping(const std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord)
547 {
548 if (SUPPORT_TASK_KEEPING) {
549 return true;
550 }
551 std::string bundleName = continuousTaskRecord->GetBundleName();
552 if (DelayedSingleton<BgtaskConfig>::GetInstance()->IsTaskKeepingExemptedQuatoApp(bundleName)) {
553 return true;
554 }
555 return false;
556 }
557
GetBackgroundModeInfo(int32_t uid,const std::string & abilityName)558 uint32_t BgContinuousTaskMgr::GetBackgroundModeInfo(int32_t uid, const std::string &abilityName)
559 {
560 if (cachedBundleInfos_.find(uid) != cachedBundleInfos_.end()) {
561 auto cachedBundleInfo = cachedBundleInfos_.at(uid);
562 if (cachedBundleInfo.abilityBgMode_.find(abilityName) !=
563 cachedBundleInfo.abilityBgMode_.end()) {
564 return cachedBundleInfo.abilityBgMode_.at(abilityName);
565 }
566 }
567 BGTASK_LOGI("get background mode info, uid: %{public}d, abilityName: %{public}s", uid, abilityName.c_str());
568 return INVALID_BGMODE;
569 }
570
CheckTaskParam(const sptr<ContinuousTaskParam> & taskParam)571 bool CheckTaskParam(const sptr<ContinuousTaskParam> &taskParam)
572 {
573 if (!taskParam) {
574 BGTASK_LOGE("continuous task params is null!");
575 return false;
576 }
577
578 if (taskParam->isNewApi_) {
579 if (taskParam->wantAgent_ == nullptr || taskParam->abilityName_.empty()) {
580 BGTASK_LOGE("continuous task params invalid!");
581 return false;
582 }
583 if (taskParam->isBatchApi_ && taskParam->bgModeIds_.empty()) {
584 BGTASK_LOGE("bgModeIds_ is empty");
585 return false;
586 }
587 } else {
588 if (taskParam->abilityName_.empty()) {
589 BGTASK_LOGE("continuous task params invalid!");
590 return false;
591 }
592 }
593 return true;
594 }
595
CheckBgmodeTypeForInner(uint32_t requestedBgModeId)596 ErrCode BgContinuousTaskMgr::CheckBgmodeTypeForInner(uint32_t requestedBgModeId)
597 {
598 if (requestedBgModeId == INVALID_BGMODE || requestedBgModeId > BGMODE_NUMS) {
599 BGTASK_LOGE("requested background mode is not declared in config file!");
600 return ERR_BGTASK_INVALID_BGMODE;
601 }
602 return ERR_OK;
603 }
604
RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)605 ErrCode BgContinuousTaskMgr::RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
606 {
607 if (!isSysReady_.load()) {
608 BGTASK_LOGW("manager is not ready");
609 return ERR_BGTASK_SYS_NOT_READY;
610 }
611
612 if (!taskParam) {
613 BGTASK_LOGE("continuous task param is null!");
614 return ERR_BGTASK_CHECK_TASK_PARAM;
615 }
616 int32_t callingUid = IPCSkeleton::GetCallingUid();
617 // webview sdk申请长时任务,上下文在应用。callkit sa 申请长时时,上下文在sa;
618 if (callingUid != VOIP_SA_UID && callingUid != HEALTHSPORT_SA_UID && callingUid != taskParam->uid_) {
619 BGTASK_LOGE("continuous task param uid %{public}d is invalid, real %{public}d", taskParam->uid_, callingUid);
620 return ERR_BGTASK_CHECK_TASK_PARAM;
621 }
622 BGTASK_LOGI("continuous task param uid %{public}d, real %{public}d", taskParam->uid_, callingUid);
623 if (taskParam->isStart_) {
624 return StartBackgroundRunningForInner(taskParam);
625 }
626 return StopBackgroundRunningForInner(taskParam);
627 }
628
RequestGetContinuousTasksByUidForInner(int32_t uid,std::vector<std::shared_ptr<ContinuousTaskInfo>> & list)629 ErrCode BgContinuousTaskMgr::RequestGetContinuousTasksByUidForInner(int32_t uid,
630 std::vector<std::shared_ptr<ContinuousTaskInfo>> &list)
631 {
632 if (!isSysReady_.load()) {
633 BGTASK_LOGW("manager is not ready");
634 return ERR_BGTASK_SYS_NOT_READY;
635 }
636 ErrCode result = ERR_OK;
637 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
638 "BackgroundTaskManager::ContinuousTask::Service::RequestGetContinuousTasksByUidForInner");
639 handler_->PostSyncTask([this, uid, &list, &result]() {
640 result = this->GetAllContinuousTasksInner(uid, list);
641 }, AppExecFwk::EventQueue::Priority::HIGH);
642 return result;
643 }
644
StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)645 ErrCode BgContinuousTaskMgr::StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
646 {
647 BgTaskHiTraceChain traceChain(__func__);
648 ErrCode result = ERR_OK;
649 int32_t uid = taskParam->uid_;
650 pid_t callingPid = IPCSkeleton::GetCallingPid();
651 if (taskParam->GetPid() != 0) {
652 callingPid = taskParam->GetPid();
653 }
654 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
655 std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
656 std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
657 int32_t userId = -1;
658
659 #ifdef HAS_OS_ACCOUNT_PART
660 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId);
661 #else // HAS_OS_ACCOUNT_PART
662 GetOsAccountIdFromUid(uid, userId);
663 #endif // HAS_OS_ACCOUNT_PART
664
665 std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
666 abilityName, uid, callingPid, taskParam->bgModeId_);
667 continuousTaskRecord->isNewApi_ = true;
668 continuousTaskRecord->isFromWebview_ = true;
669 continuousTaskRecord->userId_ = userId;
670 continuousTaskRecord->fullTokenId_ = fullTokenId;
671
672 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
673 "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
674 handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
675 result = this->StartBackgroundRunningInner(continuousTaskRecord);
676 }, AppExecFwk::EventQueue::Priority::HIGH);
677
678 return result;
679 }
680
StartBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)681 ErrCode BgContinuousTaskMgr::StartBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
682 {
683 BgTaskHiTraceChain traceChain(__func__);
684 if (!isSysReady_.load()) {
685 return ERR_BGTASK_SYS_NOT_READY;
686 }
687 if (!CheckTaskParam(taskParam)) {
688 return ERR_BGTASK_CHECK_TASK_PARAM;
689 }
690 ErrCode result = ERR_OK;
691 int32_t callingUid = IPCSkeleton::GetCallingUid();
692 pid_t callingPid = IPCSkeleton::GetCallingPid();
693 std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(callingUid);
694 int32_t userId = -1;
695 #ifdef HAS_OS_ACCOUNT_PART
696 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId);
697 #else // HAS_OS_ACCOUNT_PART
698 GetOsAccountIdFromUid(callingUid, userId);
699 #endif // HAS_OS_ACCOUNT_PART
700 if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
701 BGTASK_LOGE("background mode permission is not passed");
702 return ERR_BGTASK_PERMISSION_DENIED;
703 }
704 std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
705 taskParam->abilityName_, callingUid, callingPid, taskParam->bgModeId_, taskParam->isBatchApi_,
706 taskParam->bgModeIds_, taskParam->abilityId_);
707 InitRecordParam(continuousTaskRecord, taskParam, userId);
708 if (taskParam->wantAgent_ != nullptr && taskParam->wantAgent_->GetPendingWant() != nullptr) {
709 auto target = taskParam->wantAgent_->GetPendingWant()->GetTarget();
710 auto want = taskParam->wantAgent_->GetPendingWant()->GetWant(target);
711 if (want != nullptr) {
712 std::shared_ptr<WantAgentInfo> info = std::make_shared<WantAgentInfo>();
713 info->bundleName_ = want->GetOperation().GetBundleName();
714 info->abilityName_ = want->GetOperation().GetAbilityName();
715 continuousTaskRecord->wantAgentInfo_ = info;
716 result = CheckSubMode(want, continuousTaskRecord);
717 if (result != ERR_OK) {
718 return result;
719 }
720 }
721 }
722 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
723 "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
724 handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
725 result = this->StartBackgroundRunningInner(continuousTaskRecord);
726 }, AppExecFwk::EventQueue::Priority::HIGH);
727 taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
728 taskParam->continuousTaskId_ = continuousTaskRecord->continuousTaskId_;
729 return result;
730 }
731
InitRecordParam(std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord,const sptr<ContinuousTaskParam> & taskParam,int32_t userId)732 void BgContinuousTaskMgr::InitRecordParam(std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord,
733 const sptr<ContinuousTaskParam> &taskParam, int32_t userId)
734 {
735 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
736 continuousTaskRecord->wantAgent_ = taskParam->wantAgent_;
737 continuousTaskRecord->userId_ = userId;
738 continuousTaskRecord->isNewApi_ = taskParam->isNewApi_;
739 continuousTaskRecord->appName_ = taskParam->appName_;
740 continuousTaskRecord->fullTokenId_ = fullTokenId;
741 continuousTaskRecord->isSystem_ = BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId);
742 }
743
CheckSubMode(const std::shared_ptr<AAFwk::Want> want,std::shared_ptr<ContinuousTaskRecord> record)744 ErrCode BgContinuousTaskMgr::CheckSubMode(const std::shared_ptr<AAFwk::Want> want,
745 std::shared_ptr<ContinuousTaskRecord> record)
746 {
747 if (want->HasParameter(BG_TASK_SUB_MODE_TYPE)) {
748 if (CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::BLUETOOTH_INTERACTION) &&
749 want->GetIntParam(BG_TASK_SUB_MODE_TYPE, 0) == BackgroundSubMode::CAR_KEY) {
750 record->bgSubModeIds_.push_back(BackgroundSubMode::CAR_KEY);
751 } else {
752 BGTASK_LOGE("subMode is invaild.");
753 return ERR_BGTASK_CHECK_TASK_PARAM;
754 }
755 }
756 return ERR_OK;
757 }
758
UpdateBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)759 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
760 {
761 BgTaskHiTraceChain traceChain(__func__);
762 int32_t callingUid = IPCSkeleton::GetCallingUid();
763 ErrCode result = CheckIsSysReadyAndPermission(callingUid);
764 if (result != ERR_OK) {
765 return result;
766 }
767
768 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
769 "BackgroundTaskManager::ContinuousTask::Service::UpdateBackgroundRunningInner");
770 std::string taskInfoMapKey = std::to_string(callingUid) + SEPARATOR + taskParam->abilityName_ + SEPARATOR +
771 std::to_string(taskParam->abilityId_);
772 auto self = shared_from_this();
773 handler_->PostSyncTask([self, &taskInfoMapKey, &result, taskParam]() mutable {
774 if (!self) {
775 BGTASK_LOGE("self is null");
776 result = ERR_BGTASK_SERVICE_INNER_ERROR;
777 return;
778 }
779 result = self->UpdateBackgroundRunningInner(taskInfoMapKey, taskParam);
780 }, AppExecFwk::EventQueue::Priority::HIGH);
781 return result;
782 }
783
UpdateBackgroundRunningInner(const std::string & taskInfoMapKey,const sptr<ContinuousTaskParam> & taskParam)784 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunningInner(const std::string &taskInfoMapKey,
785 const sptr<ContinuousTaskParam> &taskParam)
786 {
787 ErrCode ret;
788
789 auto iter = continuousTaskInfosMap_.find(taskInfoMapKey);
790 if (iter == continuousTaskInfosMap_.end()) {
791 BGTASK_LOGW("continuous task is not exist: %{public}s, use start befor update", taskInfoMapKey.c_str());
792 return ERR_BGTASK_OBJECT_NOT_EXIST;
793 }
794
795 auto continuousTaskRecord = iter->second;
796 auto oldModes = continuousTaskRecord->bgModeIds_;
797
798 BGTASK_LOGI("continuous task mode %{public}d, old modes: %{public}s, new modes %{public}s, isBatchApi %{public}d,"
799 " abilityId %{public}d", continuousTaskRecord->bgModeId_,
800 continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
801 continuousTaskRecord->ToString(taskParam->bgModeIds_).c_str(),
802 continuousTaskRecord->isBatchApi_, continuousTaskRecord->abilityId_);
803 // update continuoustask by same modes.
804 if (CommonUtils::CheckModesSame(oldModes, taskParam->bgModeIds_)) {
805 return ERR_OK;
806 }
807 if (!CommonUtils::CheckExistMode(taskParam->bgModeIds_, BackgroundMode::BLUETOOTH_INTERACTION) &&
808 !continuousTaskRecord->bgSubModeIds_.empty()) {
809 continuousTaskRecord->bgSubModeIds_.clear();
810 }
811 uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_, continuousTaskRecord->abilityName_);
812 for (auto it = taskParam->bgModeIds_.begin(); it != taskParam->bgModeIds_.end(); it++) {
813 ret = CheckBgmodeType(configuredBgMode, *it, true, continuousTaskRecord);
814 if (ret != ERR_OK) {
815 BGTASK_LOGE("CheckBgmodeType error, mode: %{public}u, apply mode: %{public}u.", configuredBgMode, *it);
816 return ret;
817 }
818 }
819 continuousTaskRecord->bgModeId_ = taskParam->bgModeId_;
820 continuousTaskRecord->bgModeIds_ = taskParam->bgModeIds_;
821 continuousTaskRecord->isBatchApi_ = taskParam->isBatchApi_;
822
823 // old and new task hava mode: DATA_TRANSFER, not update notification
824 if (CommonUtils::CheckExistMode(oldModes, BackgroundMode::DATA_TRANSFER) &&
825 CommonUtils::CheckExistMode(continuousTaskRecord->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
826 BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same mode: DATA_TRANSFER",
827 continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
828 } else {
829 ret = SendContinuousTaskNotification(continuousTaskRecord);
830 if (ret != ERR_OK) {
831 return ret;
832 }
833 }
834 if (continuousTaskInfosMap_[taskInfoMapKey]->suspendState_) {
835 HandleActiveContinuousTask(continuousTaskRecord->uid_, continuousTaskRecord->pid_, taskInfoMapKey);
836 }
837 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_UPDATE);
838 taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
839 taskParam->continuousTaskId_ = continuousTaskRecord->GetContinuousTaskId();
840 return RefreshTaskRecord();
841 }
842
StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)843 ErrCode BgContinuousTaskMgr::StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
844 {
845 std::string taskInfoMapKey = std::to_string(continuousTaskRecord->uid_) + SEPARATOR
846 + continuousTaskRecord->abilityName_ + SEPARATOR + std::to_string(continuousTaskRecord->abilityId_);
847 if (continuousTaskInfosMap_.find(taskInfoMapKey) != continuousTaskInfosMap_.end()) {
848 if (continuousTaskInfosMap_[taskInfoMapKey]->suspendState_) {
849 HandleActiveContinuousTask(continuousTaskRecord->uid_, continuousTaskRecord->pid_, taskInfoMapKey);
850 return ERR_OK;
851 }
852 BGTASK_LOGD("continuous task is already exist: %{public}s", taskInfoMapKey.c_str());
853 return ERR_BGTASK_OBJECT_EXISTS;
854 }
855 BGTASK_LOGI("continuous task mode: %{public}u, modes %{public}s, isBatchApi %{public}d, uid %{public}d,"
856 " abilityId %{public}d", continuousTaskRecord->bgModeId_,
857 continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
858 continuousTaskRecord->isBatchApi_, continuousTaskRecord->uid_, continuousTaskRecord->abilityId_);
859 if (!continuousTaskRecord->isFromWebview_
860 && cachedBundleInfos_.find(continuousTaskRecord->uid_) == cachedBundleInfos_.end()) {
861 std::string mainAbilityLabel = GetMainAbilityLabel(continuousTaskRecord->bundleName_,
862 continuousTaskRecord->userId_);
863 SetCachedBundleInfo(continuousTaskRecord->uid_, continuousTaskRecord->userId_,
864 continuousTaskRecord->bundleName_, mainAbilityLabel);
865 }
866
867 ErrCode ret;
868 if (continuousTaskRecord->isFromWebview_) {
869 ret = CheckBgmodeTypeForInner(continuousTaskRecord->bgModeId_);
870 } else {
871 uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_,
872 continuousTaskRecord->abilityName_);
873 for (auto it = continuousTaskRecord->bgModeIds_.begin(); it != continuousTaskRecord->bgModeIds_.end(); it++) {
874 ret = CheckBgmodeType(configuredBgMode, *it, continuousTaskRecord->isNewApi_, continuousTaskRecord);
875 if (ret != ERR_OK) {
876 BGTASK_LOGE("CheckBgmodeType invalid!");
877 return ret;
878 }
879 }
880 }
881
882 if (!continuousTaskRecord->isFromWebview_) {
883 ret = SendContinuousTaskNotification(continuousTaskRecord);
884 if (ret != ERR_OK) {
885 BGTASK_LOGE("publish error");
886 return ret;
887 }
888 }
889 continuousTaskRecord->continuousTaskId_ = ++continuousTaskIdIndex_;
890 continuousTaskInfosMap_.emplace(taskInfoMapKey, continuousTaskRecord);
891 OnContinuousTaskChanged(continuousTaskRecord, ContinuousTaskEventTriggerType::TASK_START);
892 return RefreshTaskRecord();
893 }
894
GetBgModeNameIndex(uint32_t bgModeId,bool isNewApi)895 uint32_t GetBgModeNameIndex(uint32_t bgModeId, bool isNewApi)
896 {
897 if (!isNewApi) {
898 return BGMODE_NUMS - 1;
899 } else {
900 return bgModeId - 1;
901 }
902 }
903
SendContinuousTaskNotification(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)904 ErrCode BgContinuousTaskMgr::SendContinuousTaskNotification(
905 std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
906 {
907 BgTaskHiTraceChain traceChain(__func__);
908 if (continuousTaskText_.empty()) {
909 BGTASK_LOGE("get notification prompt info failed, continuousTaskText_ is empty");
910 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
911 }
912 std::string appName {""};
913 if (cachedBundleInfos_.find(continuousTaskRecord->uid_) != cachedBundleInfos_.end()) {
914 appName = cachedBundleInfos_.at(continuousTaskRecord->uid_).appName_;
915 }
916 if (appName.empty()) {
917 BGTASK_LOGE("appName is empty");
918 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
919 }
920
921 std::string notificationText {""};
922 ErrCode ret = CheckNotificationText(notificationText, continuousTaskRecord);
923 if (ret != ERR_OK) {
924 return ret;
925 }
926 if (notificationText.empty()) {
927 if (continuousTaskRecord->GetNotificationId() != -1) {
928 NotificationTools::GetInstance()->CancelNotification(
929 continuousTaskRecord->GetNotificationLabel(), continuousTaskRecord->GetNotificationId());
930 continuousTaskRecord->notificationId_ = -1;
931 }
932 return ERR_OK;
933 }
934 BGTASK_LOGD("notificationText %{public}s", notificationText.c_str());
935 auto iter = avSessionNotification_.find(continuousTaskRecord->uid_);
936 bool isPublish = (iter != avSessionNotification_.end()) ? iter->second : false;
937 if (continuousTaskRecord->bgModeIds_.size() == 1 &&
938 continuousTaskRecord->bgModeIds_[0] == BackgroundMode::AUDIO_PLAYBACK) {
939 if (isPublish) {
940 return ERR_OK;
941 }
942 }
943 return NotificationTools::GetInstance()->PublishNotification(continuousTaskRecord,
944 appName, notificationText, bgTaskUid_);
945 }
946
CheckNotificationText(std::string & notificationText,const std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord)947 ErrCode BgContinuousTaskMgr::CheckNotificationText(std::string ¬ificationText,
948 const std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord)
949 {
950 auto iter = avSessionNotification_.find(continuousTaskRecord->uid_);
951 bool isPublish = (iter != avSessionNotification_.end()) ? iter->second : false;
952 BGTASK_LOGD("AVSession Notification isPublish: %{public}d", isPublish);
953 for (auto mode : continuousTaskRecord->bgModeIds_) {
954 if ((mode == BackgroundMode::AUDIO_PLAYBACK && isPublish) || ((mode == BackgroundMode::VOIP ||
955 mode == BackgroundMode::AUDIO_RECORDING) && continuousTaskRecord->IsSystem())) {
956 continue;
957 }
958 BGTASK_LOGD("mode %{public}d", mode);
959 if (mode == BackgroundMode::BLUETOOTH_INTERACTION &&
960 CommonUtils::CheckExistMode(continuousTaskRecord->bgSubModeIds_, BackgroundSubMode::CAR_KEY)) {
961 if (continuousTaskSubText_.empty()) {
962 BGTASK_LOGE("get subMode notification prompt info failed, continuousTaskSubText_ is empty");
963 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
964 }
965 uint32_t index = BackgroundSubMode::CAR_KEY - 1;
966 if (index < continuousTaskSubText_.size()) {
967 notificationText += continuousTaskSubText_.at(index);
968 notificationText += "\n";
969 } else {
970 BGTASK_LOGI("sub index is invalid");
971 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
972 }
973 continue;
974 }
975 uint32_t index = GetBgModeNameIndex(mode, continuousTaskRecord->isNewApi_);
976 if (index < continuousTaskText_.size()) {
977 notificationText += continuousTaskText_.at(index);
978 notificationText += "\n";
979 } else {
980 BGTASK_LOGI("index is invalid");
981 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
982 }
983 }
984 return ERR_OK;
985 }
986
StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)987 ErrCode BgContinuousTaskMgr::StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
988 {
989 ErrCode result = ERR_OK;
990 int32_t uid = taskParam->uid_;
991 int32_t abilityId = taskParam->abilityId_;
992 std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
993
994 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
995 "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
996 handler_->PostSyncTask([this, uid, abilityName, abilityId, &result]() {
997 result = this->StopBackgroundRunningInner(uid, abilityName, abilityId);
998 }, AppExecFwk::EventQueue::Priority::HIGH);
999
1000 return result;
1001 }
1002
StopBackgroundRunning(const std::string & abilityName,int32_t abilityId)1003 ErrCode BgContinuousTaskMgr::StopBackgroundRunning(const std::string &abilityName, int32_t abilityId)
1004 {
1005 if (!isSysReady_.load()) {
1006 BGTASK_LOGW("manager is not ready");
1007 return ERR_BGTASK_SYS_NOT_READY;
1008 }
1009 if (abilityName.empty()) {
1010 BGTASK_LOGE("abilityName is empty!");
1011 return ERR_BGTASK_INVALID_PARAM;
1012 }
1013 int32_t callingUid = IPCSkeleton::GetCallingUid();
1014
1015 ErrCode result = ERR_OK;
1016
1017 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
1018 "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
1019 handler_->PostSyncTask([this, callingUid, abilityName, abilityId, &result]() {
1020 result = this->StopBackgroundRunningInner(callingUid, abilityName, abilityId);
1021 }, AppExecFwk::EventQueue::Priority::HIGH);
1022
1023 return result;
1024 }
1025
StopBackgroundRunningInner(int32_t uid,const std::string & abilityName,int32_t abilityId)1026 ErrCode BgContinuousTaskMgr::StopBackgroundRunningInner(int32_t uid, const std::string &abilityName,
1027 int32_t abilityId)
1028 {
1029 BgTaskHiTraceChain traceChain(__func__);
1030 std::string mapKey = std::to_string(uid) + SEPARATOR + abilityName + SEPARATOR + std::to_string(abilityId);
1031
1032 auto iter = continuousTaskInfosMap_.find(mapKey);
1033 if (iter == continuousTaskInfosMap_.end()) {
1034 BGTASK_LOGD("%{public}s continuous task not exists", mapKey.c_str());
1035 return ERR_BGTASK_OBJECT_NOT_EXIST;
1036 }
1037 BGTASK_LOGI("TASK STOP: user: %{public}s stop continuous task, continuousTaskId: %{public}d, "
1038 "notificationId: %{public}d", mapKey.c_str(), iter->second->GetContinuousTaskId(),
1039 iter->second->GetNotificationId());
1040 ErrCode result = ERR_OK;
1041 if (iter->second->GetNotificationId() != -1) {
1042 result = NotificationTools::GetInstance()->CancelNotification(
1043 iter->second->GetNotificationLabel(), iter->second->GetNotificationId());
1044 }
1045 RemoveContinuousTaskRecord(mapKey);
1046 return result;
1047 }
1048
GetAllContinuousTasks(std::vector<std::shared_ptr<ContinuousTaskInfo>> & list)1049 ErrCode BgContinuousTaskMgr::GetAllContinuousTasks(std::vector<std::shared_ptr<ContinuousTaskInfo>> &list)
1050 {
1051 int32_t callingUid = IPCSkeleton::GetCallingUid();
1052 ErrCode result = CheckIsSysReadyAndPermission(callingUid);
1053 if (result != ERR_OK) {
1054 return result;
1055 }
1056 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
1057 "BackgroundTaskManager::ContinuousTask::Service::GetAllContinuousTasks");
1058 handler_->PostSyncTask([this, callingUid, &list, &result]() {
1059 result = this->GetAllContinuousTasksInner(callingUid, list);
1060 }, AppExecFwk::EventQueue::Priority::HIGH);
1061 return result;
1062 }
1063
GetAllContinuousTasks(std::vector<std::shared_ptr<ContinuousTaskInfo>> & list,bool includeSuspended)1064 ErrCode BgContinuousTaskMgr::GetAllContinuousTasks(
1065 std::vector<std::shared_ptr<ContinuousTaskInfo>> &list, bool includeSuspended)
1066 {
1067 int32_t callingUid = IPCSkeleton::GetCallingUid();
1068 ErrCode result = CheckIsSysReadyAndPermission(callingUid);
1069 if (result != ERR_OK) {
1070 return result;
1071 }
1072 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
1073 "BackgroundTaskManager::ContinuousTask::Service::GetAllContinuousTasksIncludeSuspended");
1074 handler_->PostSyncTask([this, callingUid, &list, &result, includeSuspended]() {
1075 result = this->GetAllContinuousTasksInner(callingUid, list, includeSuspended);
1076 }, AppExecFwk::EventQueue::Priority::HIGH);
1077 return result;
1078 }
1079
CheckIsSysReadyAndPermission(int32_t callingUid)1080 ErrCode BgContinuousTaskMgr::CheckIsSysReadyAndPermission(int32_t callingUid)
1081 {
1082 if (!isSysReady_.load()) {
1083 BGTASK_LOGW("manager is not ready");
1084 return ERR_BGTASK_SYS_NOT_READY;
1085 }
1086 if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
1087 BGTASK_LOGE("uid: %{public}d no have permission", callingUid);
1088 return ERR_BGTASK_PERMISSION_DENIED;
1089 }
1090 if (callingUid < 0) {
1091 BGTASK_LOGE("param callingUid: %{public}d is invaild", callingUid);
1092 return ERR_BGTASK_INVALID_UID;
1093 }
1094 return ERR_OK;
1095 }
1096
GetAllContinuousTasksInner(int32_t uid,std::vector<std::shared_ptr<ContinuousTaskInfo>> & list,bool includeSuspended)1097 ErrCode BgContinuousTaskMgr::GetAllContinuousTasksInner(int32_t uid,
1098 std::vector<std::shared_ptr<ContinuousTaskInfo>> &list, bool includeSuspended)
1099 {
1100 if (continuousTaskInfosMap_.empty()) {
1101 return ERR_OK;
1102 }
1103 BGTASK_LOGW("GetAllContinuousTasksInner, includeSuspended: %{public}d", includeSuspended);
1104 for (const auto &record : continuousTaskInfosMap_) {
1105 if (!record.second) {
1106 continue;
1107 }
1108 if (record.second->uid_ != uid) {
1109 continue;
1110 }
1111 if (!includeSuspended && record.second->suspendState_) {
1112 continue;
1113 }
1114 std::string wantAgentBundleName {"NULL"};
1115 std::string wantAgentAbilityName {"NULL"};
1116 if (record.second->wantAgentInfo_ != nullptr) {
1117 wantAgentBundleName = record.second->wantAgentInfo_->bundleName_;
1118 wantAgentAbilityName = record.second->wantAgentInfo_->abilityName_;
1119 }
1120 auto info = std::make_shared<ContinuousTaskInfo>(record.second->abilityName_, record.second->uid_,
1121 record.second->pid_, record.second->isFromWebview_, record.second->bgModeIds_, record.second->bgSubModeIds_,
1122 record.second->notificationId_, record.second->continuousTaskId_, record.second->abilityId_,
1123 wantAgentBundleName, wantAgentAbilityName);
1124 list.push_back(info);
1125 }
1126 return ERR_OK;
1127 }
1128
StopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)1129 void BgContinuousTaskMgr::StopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
1130 {
1131 if (!isSysReady_.load()) {
1132 BGTASK_LOGW("manager is not ready");
1133 return;
1134 }
1135 auto self = shared_from_this();
1136 auto task = [self, uid, pid, taskType, key]() {
1137 if (self) {
1138 self->HandleStopContinuousTask(uid, pid, taskType, key);
1139 }
1140 };
1141 handler_->PostTask(task);
1142 }
1143
HandleStopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)1144 void BgContinuousTaskMgr::HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
1145 {
1146 BGTASK_LOGI("StopContinuousTask taskType: %{public}d, key %{public}s", taskType, key.c_str());
1147 if (taskType == BackgroundMode::DATA_TRANSFER) {
1148 RemoveContinuousTaskRecordByUidAndMode(uid, taskType);
1149 return;
1150 }
1151 if (taskType == ALL_MODES) {
1152 RemoveContinuousTaskRecordByUid(uid);
1153 return;
1154 }
1155 if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) {
1156 return;
1157 }
1158 NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(),
1159 continuousTaskInfosMap_[key]->GetNotificationId());
1160 SetReason(key, FREEZE_CANCEL);
1161 RemoveContinuousTaskRecord(key);
1162 }
1163
SuspendContinuousTask(int32_t uid,int32_t pid,int32_t reason,const std::string & key)1164 void BgContinuousTaskMgr::SuspendContinuousTask(int32_t uid, int32_t pid, int32_t reason, const std::string &key)
1165 {
1166 if (!isSysReady_.load()) {
1167 BGTASK_LOGW("manager is not ready");
1168 return;
1169 }
1170 auto self = shared_from_this();
1171 auto task = [self, uid, pid, reason, key]() {
1172 if (self) {
1173 if (self->IsExistCallback(uid, CONTINUOUS_TASK_SUSPEND)) {
1174 self->HandleSuspendContinuousTask(uid, pid, reason, key);
1175 } else {
1176 self->HandleStopContinuousTask(uid, pid, 0, key);
1177 }
1178 }
1179 };
1180 handler_->PostTask(task);
1181 }
1182
IsExistCallback(int32_t uid,uint32_t type)1183 bool BgContinuousTaskMgr::IsExistCallback(int32_t uid, uint32_t type)
1184 {
1185 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1186 if ((*iter)->isHap_ && (*iter)->uid_ == uid && (((*iter)->flag_ & type) > 0)) {
1187 BGTASK_LOGD("falg: %{public}d", (*iter)->flag_);
1188 return true;
1189 }
1190 }
1191 return false;
1192 }
1193
HandleSuspendContinuousTask(int32_t uid,int32_t pid,int32_t mode,const std::string & key)1194 void BgContinuousTaskMgr::HandleSuspendContinuousTask(int32_t uid, int32_t pid, int32_t mode, const std::string &key)
1195 {
1196 if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) {
1197 BGTASK_LOGW("suspend TaskInfo failure, no matched task: %{public}s", key.c_str());
1198 return;
1199 }
1200 auto iter = continuousTaskInfosMap_.begin();
1201 while (iter != continuousTaskInfosMap_.end()) {
1202 if (iter->second->GetUid() != uid) {
1203 ++iter;
1204 continue;
1205 }
1206 BGTASK_LOGW("SuspendContinuousTask mode: %{public}d, key %{public}s", mode, key.c_str());
1207 iter->second->suspendState_ = true;
1208 uint32_t reasonValue = ContinuousTaskSuspendReason::GetSuspendReasonValue(mode);
1209 if (reasonValue == 0) {
1210 iter->second->suspendReason_ = -1;
1211 } else {
1212 iter->second->suspendReason_ = static_cast<int32_t>(reasonValue);
1213 }
1214 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_SUSPEND);
1215 RefreshTaskRecord();
1216 break;
1217 }
1218 // 暂停状态取消长时任务通知
1219 NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(),
1220 continuousTaskInfosMap_[key]->GetNotificationId());
1221 // 对SA来说,暂停状态等同于取消
1222 HandleAppContinuousTaskStop(uid);
1223 }
1224
ActiveContinuousTask(int32_t uid,int32_t pid,const std::string & key)1225 void BgContinuousTaskMgr::ActiveContinuousTask(int32_t uid, int32_t pid, const std::string &key)
1226 {
1227 if (!isSysReady_.load()) {
1228 BGTASK_LOGW("manager is not ready");
1229 return;
1230 }
1231 auto self = shared_from_this();
1232 auto task = [self, uid, pid, key]() {
1233 if (self) {
1234 self->HandleActiveContinuousTask(uid, pid, key);
1235 }
1236 };
1237 handler_->PostTask(task);
1238 }
1239
HandleActiveContinuousTask(int32_t uid,int32_t pid,const std::string & key)1240 void BgContinuousTaskMgr::HandleActiveContinuousTask(int32_t uid, int32_t pid, const std::string &key)
1241 {
1242 auto iter = continuousTaskInfosMap_.begin();
1243 while (iter != continuousTaskInfosMap_.end()) {
1244 if (iter->second->GetUid() != uid || !iter->second->suspendState_) {
1245 ++iter;
1246 continue;
1247 }
1248 BGTASK_LOGI("ActiveContinuousTask uid: %{public}d, pid: %{public}d", uid, pid);
1249 iter->second->suspendState_ = false;
1250 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_ACTIVE);
1251 SendContinuousTaskNotification(iter->second);
1252 RefreshTaskRecord();
1253 break;
1254 }
1255 }
1256
RemoveContinuousTaskRecordByUid(int32_t uid)1257 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUid(int32_t uid)
1258 {
1259 auto iter = continuousTaskInfosMap_.begin();
1260 while (iter != continuousTaskInfosMap_.end()) {
1261 if (iter->second->GetUid() != uid) {
1262 ++iter;
1263 continue;
1264 }
1265 BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
1266 iter->second->reason_ = FREEZE_CANCEL;
1267 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
1268 NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
1269 iter->second->GetNotificationId());
1270 iter = continuousTaskInfosMap_.erase(iter);
1271 RefreshTaskRecord();
1272 }
1273 HandleAppContinuousTaskStop(uid);
1274 }
1275
RemoveContinuousTaskRecordByUidAndMode(int32_t uid,uint32_t mode)1276 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUidAndMode(int32_t uid, uint32_t mode)
1277 {
1278 auto iter = continuousTaskInfosMap_.begin();
1279 while (iter != continuousTaskInfosMap_.end()) {
1280 if (iter->second->GetUid() != uid) {
1281 ++iter;
1282 continue;
1283 }
1284 auto findModeIter = std::find(iter->second->bgModeIds_.begin(), iter->second->bgModeIds_.end(), mode);
1285 if (findModeIter == iter->second->bgModeIds_.end()) {
1286 ++iter;
1287 continue;
1288 }
1289 iter->second->reason_ = FREEZE_CANCEL;
1290 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
1291 NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
1292 iter->second->GetNotificationId());
1293 iter = continuousTaskInfosMap_.erase(iter);
1294 RefreshTaskRecord();
1295 }
1296 HandleAppContinuousTaskStop(uid);
1297 }
1298
AddSubscriber(const std::shared_ptr<SubscriberInfo> subscriberInfo)1299 ErrCode BgContinuousTaskMgr::AddSubscriber(const std::shared_ptr<SubscriberInfo> subscriberInfo)
1300 {
1301 if (subscriberInfo == nullptr || subscriberInfo->subscriber_ == nullptr ||
1302 subscriberInfo->subscriber_->AsObject() == nullptr) {
1303 BGTASK_LOGE("subscriber is null.");
1304 return ERR_BGTASK_INVALID_PARAM;
1305 }
1306
1307 handler_->PostSyncTask([=]() {
1308 AddSubscriberInner(subscriberInfo);
1309 });
1310 return ERR_OK;
1311 }
1312
AddSubscriberInner(const std::shared_ptr<SubscriberInfo> subscriberInfo)1313 ErrCode BgContinuousTaskMgr::AddSubscriberInner(const std::shared_ptr<SubscriberInfo> subscriberInfo)
1314 {
1315 BGTASK_LOGD("BgContinuousTaskMgr enter");
1316 auto remoteObj = subscriberInfo->subscriber_->AsObject();
1317 auto findSuscriber = [&remoteObj](const auto& target) {
1318 return remoteObj == target->subscriber_->AsObject();
1319 };
1320
1321 auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSuscriber);
1322 if (subscriberIter != bgTaskSubscribers_.end()) {
1323 BGTASK_LOGW("target subscriber already exist");
1324 return ERR_BGTASK_OBJECT_EXISTS;
1325 }
1326 bgTaskSubscribers_.emplace_back(subscriberInfo);
1327
1328 if (!susriberDeathRecipient_) {
1329 susriberDeathRecipient_ = new (std::nothrow) RemoteDeathRecipient(
1330 [this](const wptr<IRemoteObject> &remote) { this->OnRemoteSubscriberDied(remote); });
1331 }
1332 if (susriberDeathRecipient_) {
1333 remoteObj->AddDeathRecipient(susriberDeathRecipient_);
1334 }
1335 return ERR_OK;
1336 }
1337
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)1338 ErrCode BgContinuousTaskMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
1339 {
1340 if (subscriber == nullptr) {
1341 BGTASK_LOGE("subscriber is null.");
1342 return ERR_BGTASK_INVALID_PARAM;
1343 }
1344
1345 handler_->PostSyncTask([=]() {
1346 RemoveSubscriberInner(subscriber);
1347 });
1348 return ERR_OK;
1349 }
1350
RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)1351 ErrCode BgContinuousTaskMgr::RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
1352 {
1353 auto remote = subscriber->AsObject();
1354 if (remote == nullptr) {
1355 BGTASK_LOGE("Subscriber' object is null.");
1356 return ERR_BGTASK_INVALID_PARAM;
1357 }
1358 auto findSubscriber = [&remote](const auto &info) {
1359 return remote == info->subscriber_->AsObject();
1360 };
1361
1362 auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSubscriber);
1363 if (subscriberIter == bgTaskSubscribers_.end()) {
1364 BGTASK_LOGE("subscriber to remove is not exists.");
1365 return ERR_BGTASK_INVALID_PARAM;
1366 }
1367 if (susriberDeathRecipient_) {
1368 remote->RemoveDeathRecipient(susriberDeathRecipient_);
1369 }
1370 bgTaskSubscribers_.erase(subscriberIter);
1371 BGTASK_LOGI("Remove continuous task subscriber succeed");
1372 return ERR_OK;
1373 }
1374
GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list,int32_t uid)1375 ErrCode BgContinuousTaskMgr::GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list,
1376 int32_t uid)
1377 {
1378 if (!isSysReady_.load()) {
1379 BGTASK_LOGW("manager is not ready");
1380 return ERR_BGTASK_SYS_NOT_READY;
1381 }
1382
1383 ErrCode result = ERR_OK;
1384
1385 handler_->PostSyncTask([this, &list, uid, &result]() {
1386 result = this->GetContinuousTaskAppsInner(list, uid);
1387 }, AppExecFwk::EventQueue::Priority::HIGH);
1388
1389 return result;
1390 }
1391
GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list,int32_t uid)1392 ErrCode BgContinuousTaskMgr::GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list,
1393 int32_t uid)
1394 {
1395 if (continuousTaskInfosMap_.empty()) {
1396 return ERR_OK;
1397 }
1398
1399 for (auto record : continuousTaskInfosMap_) {
1400 if (uid != -1 && uid != record.second->uid_) {
1401 continue;
1402 }
1403 if (record.second->suspendState_) {
1404 continue;
1405 }
1406 auto appInfo = std::make_shared<ContinuousTaskCallbackInfo>(record.second->bgModeId_, record.second->uid_,
1407 record.second->pid_, record.second->abilityName_, record.second->isFromWebview_, record.second->isBatchApi_,
1408 record.second->bgModeIds_, record.second->abilityId_, record.second->fullTokenId_);
1409 list.push_back(appInfo);
1410 }
1411 return ERR_OK;
1412 }
1413
AVSessionNotifyUpdateNotification(int32_t uid,int32_t pid,bool isPublish)1414 ErrCode BgContinuousTaskMgr::AVSessionNotifyUpdateNotification(int32_t uid, int32_t pid, bool isPublish)
1415 {
1416 if (!isSysReady_.load()) {
1417 BGTASK_LOGW("manager is not ready");
1418 return ERR_BGTASK_SYS_NOT_READY;
1419 }
1420
1421 int32_t callingUid = IPCSkeleton::GetCallingUid();
1422 if (callingUid != AVSESSION_SA_UID) {
1423 BGTASK_LOGE("continuous task param uid %{public}d is invalid", callingUid);
1424 return ERR_BGTASK_CHECK_TASK_PARAM;
1425 }
1426
1427 ErrCode result = ERR_OK;
1428 handler_->PostSyncTask([this, uid, pid, isPublish, &result]() {
1429 result = this->AVSessionNotifyUpdateNotificationInner(uid, pid, isPublish);
1430 }, AppExecFwk::EventQueue::Priority::HIGH);
1431
1432 return result;
1433 }
1434
AVSessionNotifyUpdateNotificationInner(int32_t uid,int32_t pid,bool isPublish)1435 ErrCode BgContinuousTaskMgr::AVSessionNotifyUpdateNotificationInner(int32_t uid, int32_t pid, bool isPublish)
1436 {
1437 BGTASK_LOGD("AVSessionNotifyUpdateNotification start, uid: %{public}d, isPublish: %{public}d", uid, isPublish);
1438 avSessionNotification_[uid] = isPublish;
1439 auto findUid = [uid](const auto &target) {
1440 return uid == target.second->GetUid();
1441 };
1442 auto findUidIter = find_if(continuousTaskInfosMap_.begin(), continuousTaskInfosMap_.end(), findUid);
1443 if (findUidIter == continuousTaskInfosMap_.end()) {
1444 BGTASK_LOGD("continuous task is not exist: %{public}d", uid);
1445 return ERR_BGTASK_OBJECT_NOT_EXIST;
1446 }
1447
1448 ErrCode result = ERR_OK;
1449 auto record = findUidIter->second;
1450 // 只有播音类型长时任务,并且没有AVSession通知
1451 if (!isPublish && record->bgModeIds_.size() == 1 && record->bgModeIds_[0] == BackgroundMode::AUDIO_PLAYBACK) {
1452 result = SendContinuousTaskNotification(record);
1453 return result;
1454 }
1455 std::map<std::string, std::pair<std::string, std::string>> newPromptInfos;
1456 if (!CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
1457 std::string mainAbilityLabel = GetMainAbilityLabel(record->bundleName_, record->userId_);
1458 std::string notificationText = GetNotificationText(record);
1459 if (notificationText.empty()) {
1460 result = NotificationTools::GetInstance()->CancelNotification(
1461 record->GetNotificationLabel(), record->GetNotificationId());
1462 record->notificationId_ = -1;
1463 } else {
1464 newPromptInfos.emplace(record->notificationLabel_, std::make_pair(mainAbilityLabel, notificationText));
1465 NotificationTools::GetInstance()->RefreshContinuousNotifications(newPromptInfos, bgTaskUid_);
1466 }
1467 }
1468 return result;
1469 }
1470
ShellDump(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1471 ErrCode BgContinuousTaskMgr::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo)
1472 {
1473 if (!isSysReady_.load()) {
1474 BGTASK_LOGW("manager is not ready");
1475 return ERR_BGTASK_SYS_NOT_READY;
1476 }
1477 ErrCode result = ERR_OK;
1478 handler_->PostSyncTask([&]() {
1479 result = ShellDumpInner(dumpOption, dumpInfo);
1480 });
1481
1482 return result;
1483 }
1484
ShellDumpInner(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1485 ErrCode BgContinuousTaskMgr::ShellDumpInner(const std::vector<std::string> &dumpOption,
1486 std::vector<std::string> &dumpInfo)
1487 {
1488 if (dumpOption[1] == DUMP_PARAM_LIST_ALL) {
1489 DumpAllTaskInfo(dumpInfo);
1490 } else if (dumpOption[1] == DUMP_PARAM_CANCEL_ALL) {
1491 DumpCancelTask(dumpOption, true);
1492 } else if (dumpOption[1] == DUMP_PARAM_CANCEL) {
1493 DumpCancelTask(dumpOption, false);
1494 } else if (dumpOption[1] == DUMP_PARAM_GET) {
1495 DumpGetTask(dumpOption, dumpInfo);
1496 } else if (dumpOption[1] == DUMP_INNER_TASK) {
1497 DumpInnerTask(dumpOption, dumpInfo);
1498 } else {
1499 BGTASK_LOGW("invalid dump param");
1500 }
1501 return ERR_OK;
1502 }
1503
DumpAllTaskInfo(std::vector<std::string> & dumpInfo)1504 void BgContinuousTaskMgr::DumpAllTaskInfo(std::vector<std::string> &dumpInfo)
1505 {
1506 std::stringstream stream;
1507 if (continuousTaskInfosMap_.empty()) {
1508 dumpInfo.emplace_back("No running continuous task\n");
1509 return;
1510 }
1511 std::unordered_map<std::string, std::shared_ptr<ContinuousTaskRecord>>::iterator iter;
1512 uint32_t index = 1;
1513 for (iter = continuousTaskInfosMap_.begin(); iter != continuousTaskInfosMap_.end(); ++iter) {
1514 stream.str("");
1515 stream.clear();
1516 stream << "No." << index;
1517 stream << "\tcontinuousTaskKey: " << iter->first << "\n";
1518 stream << "\tcontinuousTaskValue:" << "\n";
1519 stream << "\t\tbundleName: " << iter->second->GetBundleName() << "\n";
1520 stream << "\t\tabilityName: " << iter->second->GetAbilityName() << "\n";
1521 stream << "\t\tsuspendState: " << (iter->second->suspendState_ ? "true" : "false") << "\n";
1522 stream << "\t\tisFromWebview: " << (iter->second->IsFromWebview() ? "true" : "false") << "\n";
1523 stream << "\t\tisFromNewApi: " << (iter->second->IsNewApi() ? "true" : "false") << "\n";
1524 stream << "\t\tbackgroundMode: " << g_continuousTaskModeName[GetBgModeNameIndex(
1525 iter->second->GetBgModeId(), iter->second->IsNewApi())] << "\n";
1526 stream << "\t\tisBatchApi: " << (iter->second->isBatchApi_ ? "true" : "false") << "\n";
1527 stream << "\t\tbackgroundModes: " << iter->second->ToString(iter->second->bgModeIds_) << "\n";
1528 stream << "\t\tbackgroundSubModes: " << iter->second->ToString(iter->second->bgSubModeIds_) << "\n";
1529 stream << "\t\tuid: " << iter->second->GetUid() << "\n";
1530 stream << "\t\tuserId: " << iter->second->GetUserId() << "\n";
1531 stream << "\t\tpid: " << iter->second->GetPid() << "\n";
1532 stream << "\t\tnotificationLabel: " << iter->second->GetNotificationLabel() << "\n";
1533 stream << "\t\tnotificationId: " << iter->second->GetNotificationId() << "\n";
1534 stream << "\t\tcontinuousTaskId: " << iter->second->continuousTaskId_ << "\n";
1535 if (iter->second->wantAgentInfo_ != nullptr) {
1536 stream << "\t\twantAgentBundleName: " << iter->second->wantAgentInfo_->bundleName_ << "\n";
1537 stream << "\t\twantAgentAbilityName: " << iter->second->wantAgentInfo_->abilityName_ << "\n";
1538 } else {
1539 stream << "\t\twantAgentBundleName: " << "NULL" << "\n";
1540 stream << "\t\twantAgentAbilityName: " << "NULL" << "\n";
1541 }
1542 stream << "\n";
1543 dumpInfo.emplace_back(stream.str());
1544 index++;
1545 }
1546 }
1547
DumpCancelTask(const std::vector<std::string> & dumpOption,bool cleanAll)1548 void BgContinuousTaskMgr::DumpCancelTask(const std::vector<std::string> &dumpOption, bool cleanAll)
1549 {
1550 if (cleanAll) {
1551 std::set<int32_t> uids;
1552 for (auto item : continuousTaskInfosMap_) {
1553 NotificationTools::GetInstance()->CancelNotification(item.second->GetNotificationLabel(),
1554 item.second->GetNotificationId());
1555 OnContinuousTaskChanged(item.second, ContinuousTaskEventTriggerType::TASK_CANCEL);
1556 uids.insert(item.second->uid_);
1557 }
1558 continuousTaskInfosMap_.clear();
1559 RefreshTaskRecord();
1560 for (int32_t uid : uids) {
1561 HandleAppContinuousTaskStop(uid);
1562 }
1563 } else {
1564 if (dumpOption.size() < MAX_DUMP_PARAM_NUMS) {
1565 return;
1566 }
1567 std::string taskKey = dumpOption[2];
1568 auto iter = continuousTaskInfosMap_.find(taskKey);
1569 if (iter == continuousTaskInfosMap_.end()) {
1570 return;
1571 }
1572 NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
1573 iter->second->GetNotificationId());
1574 RemoveContinuousTaskRecord(taskKey);
1575 }
1576 }
1577
DumpGetTask(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1578 void BgContinuousTaskMgr::DumpGetTask(const std::vector<std::string> &dumpOption,
1579 std::vector<std::string> &dumpInfo)
1580 {
1581 if (dumpOption.size() != MAX_DUMP_PARAM_NUMS) {
1582 dumpInfo.emplace_back("param invaild\n");
1583 return;
1584 }
1585 int32_t uid = std::atoi(dumpOption[MAX_DUMP_PARAM_NUMS - 1].c_str());
1586 if (uid < 0) {
1587 dumpInfo.emplace_back("param invaild\n");
1588 return;
1589 }
1590 std::vector<std::shared_ptr<ContinuousTaskInfo>> list;
1591 ErrCode ret = RequestGetContinuousTasksByUidForInner(uid, list);
1592 if (ret != ERR_OK) {
1593 dumpInfo.emplace_back("param invaild\n");
1594 return;
1595 }
1596 if (list.empty()) {
1597 dumpInfo.emplace_back("No running continuous task\n");
1598 return;
1599 }
1600 std::stringstream stream;
1601 uint32_t index = 1;
1602 for (const auto &info : list) {
1603 stream.str("");
1604 stream.clear();
1605 stream << "No." << index;
1606 stream << "\t\tabilityName: " << info->GetAbilityName() << "\n";
1607 stream << "\t\tisFromWebview: " << (info->IsFromWebView() ? "true" : "false") << "\n";
1608 stream << "\t\tuid: " << info->GetUid() << "\n";
1609 stream << "\t\tpid: " << info->GetPid() << "\n";
1610 stream << "\t\tnotificationId: " << info->GetNotificationId() << "\n";
1611 stream << "\t\tcontinuousTaskId: " << info->GetContinuousTaskId() << "\n";
1612 stream << "\t\tabilityId: " << info->GetAbilityId() << "\n";
1613 stream << "\t\twantAgentBundleName: " << info->GetWantAgentBundleName() << "\n";
1614 stream << "\t\twantAgentAbilityName: " << info->GetWantAgentAbilityName() << "\n";
1615 stream << "\t\tbackgroundModes: " << info->ToString(info->GetBackgroundModes()) << "\n";
1616 stream << "\t\tbackgroundSubModes: " << info->ToString(info->GetBackgroundSubModes()) << "\n";
1617 stream << "\n";
1618 dumpInfo.emplace_back(stream.str());
1619 index++;
1620 }
1621 }
1622
DumpInnerTask(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1623 void BgContinuousTaskMgr::DumpInnerTask(const std::vector<std::string> &dumpOption,
1624 std::vector<std::string> &dumpInfo)
1625 {
1626 if (dumpOption.size() != MAX_DUMP_INNER_PARAM_NUMS) {
1627 dumpInfo.emplace_back("param invaild\n");
1628 return;
1629 }
1630 std::string modeStr = dumpOption[2].c_str();
1631 uint32_t mode = 0;
1632 if (modeStr == "WORKOUT") {
1633 mode = BackgroundMode::WORKOUT;
1634 }
1635 if (mode == 0) {
1636 dumpInfo.emplace_back("param invaild\n");
1637 return;
1638 }
1639 std::string operationType = dumpOption[3].c_str();
1640 if (operationType != "apply" && operationType != "reset") {
1641 dumpInfo.emplace_back("param invaild\n");
1642 return;
1643 }
1644 bool isApply = (operationType == "apply");
1645 sptr<ContinuousTaskParamForInner> taskParam = sptr<ContinuousTaskParamForInner>(
1646 new ContinuousTaskParamForInner(1, mode, isApply));
1647 ErrCode ret = ERR_OK;
1648 if (isApply) {
1649 ret = StartBackgroundRunningForInner(taskParam);
1650 } else {
1651 ret = StopBackgroundRunningForInner(taskParam);
1652 }
1653 if (ret != ERR_OK) {
1654 dumpInfo.emplace_back("dump inner continuous task fail.\n");
1655 } else {
1656 dumpInfo.emplace_back("dump inner continuous task success.\n");
1657 }
1658 }
1659
SetReason(const std::string & mapKey,int32_t reason)1660 void BgContinuousTaskMgr::SetReason(const std::string &mapKey, int32_t reason)
1661 {
1662 auto iter = continuousTaskInfosMap_.find(mapKey);
1663 if (iter == continuousTaskInfosMap_.end()) {
1664 BGTASK_LOGW("SetReason failure, no matched task: %{public}s", mapKey.c_str());
1665 } else {
1666 auto record = iter->second;
1667 record->reason_ = reason;
1668 }
1669 }
1670
RemoveContinuousTaskRecord(const std::string & mapKey)1671 bool BgContinuousTaskMgr::RemoveContinuousTaskRecord(const std::string &mapKey)
1672 {
1673 if (continuousTaskInfosMap_.find(mapKey) == continuousTaskInfosMap_.end()) {
1674 BGTASK_LOGW("remove TaskInfo failure, no matched task: %{public}s", mapKey.c_str());
1675 return false;
1676 }
1677 BGTASK_LOGI("erase task info: %{public}s", mapKey.c_str());
1678 auto record = continuousTaskInfosMap_.at(mapKey);
1679 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1680 continuousTaskInfosMap_.erase(mapKey);
1681 HandleAppContinuousTaskStop(record->uid_);
1682 RefreshTaskRecord();
1683 return true;
1684 }
1685
StopContinuousTaskByUser(const std::string & mapKey)1686 bool BgContinuousTaskMgr::StopContinuousTaskByUser(const std::string &mapKey)
1687 {
1688 if (!isSysReady_.load()) {
1689 BGTASK_LOGW("manager is not ready");
1690 return false;
1691 }
1692 bool result = true;
1693 handler_->PostSyncTask([this, mapKey, &result]() {
1694 SetReason(mapKey, REMOVE_NOTIFICATION_CANCEL);
1695 result = RemoveContinuousTaskRecord(mapKey);
1696 });
1697 return result;
1698 }
1699
OnRemoteSubscriberDied(const wptr<IRemoteObject> & object)1700 void BgContinuousTaskMgr::OnRemoteSubscriberDied(const wptr<IRemoteObject> &object)
1701 {
1702 if (!isSysReady_.load()) {
1703 BGTASK_LOGW("manager is not ready");
1704 return;
1705 }
1706 if (object == nullptr) {
1707 BGTASK_LOGE("remote object is null.");
1708 return;
1709 }
1710 handler_->PostSyncTask([this, &object]() { this->OnRemoteSubscriberDiedInner(object); });
1711 }
1712
OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> & object)1713 void BgContinuousTaskMgr::OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> &object)
1714 {
1715 sptr<IRemoteObject> objectProxy = object.promote();
1716 if (!objectProxy) {
1717 BGTASK_LOGE("get remote object failed");
1718 return;
1719 }
1720 auto iter = bgTaskSubscribers_.begin();
1721 while (iter != bgTaskSubscribers_.end()) {
1722 if ((*iter)->subscriber_->AsObject() == objectProxy) {
1723 BGTASK_LOGI("OnRemoteSubscriberDiedInner erase it");
1724 iter = bgTaskSubscribers_.erase(iter);
1725 } else {
1726 iter++;
1727 }
1728 }
1729 }
1730
OnAbilityStateChanged(int32_t uid,const std::string & abilityName,int32_t abilityId)1731 void BgContinuousTaskMgr::OnAbilityStateChanged(int32_t uid, const std::string &abilityName, int32_t abilityId)
1732 {
1733 if (!isSysReady_.load()) {
1734 BGTASK_LOGW("manager is not ready");
1735 return;
1736 }
1737 auto iter = continuousTaskInfosMap_.begin();
1738 while (iter != continuousTaskInfosMap_.end()) {
1739 if (iter->second->uid_ == uid && iter->second->abilityName_ == abilityName &&
1740 iter->second->abilityId_ == abilityId) {
1741 auto record = iter->second;
1742 BGTASK_LOGI("OnAbilityStateChanged uid: %{public}d, bundleName: %{public}s abilityName: %{public}s"
1743 "bgModeId: %{public}d, abilityId: %{public}d", uid, record->bundleName_.c_str(),
1744 record->abilityName_.c_str(), record->bgModeId_, record->abilityId_);
1745 record->reason_ = SYSTEM_CANCEL;
1746 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1747 if (!iter->second->isFromWebview_) {
1748 NotificationTools::GetInstance()->CancelNotification(
1749 record->GetNotificationLabel(), record->GetNotificationId());
1750 }
1751 iter = continuousTaskInfosMap_.erase(iter);
1752 HandleAppContinuousTaskStop(record->uid_);
1753 RefreshTaskRecord();
1754 } else {
1755 iter++;
1756 }
1757 }
1758 }
1759
OnAppStopped(int32_t uid)1760 void BgContinuousTaskMgr::OnAppStopped(int32_t uid)
1761 {
1762 if (!isSysReady_.load()) {
1763 BGTASK_LOGW("manager is not ready");
1764 return;
1765 }
1766 auto iter = continuousTaskInfosMap_.begin();
1767 while (iter != continuousTaskInfosMap_.end()) {
1768 if (iter->second->uid_ == uid) {
1769 auto record = iter->second;
1770 BGTASK_LOGI("OnAppStopped uid: %{public}d, bundleName: %{public}s abilityName: %{public}s"
1771 "bgModeId: %{public}d, abilityId: %{public}d", uid, record->bundleName_.c_str(),
1772 record->abilityName_.c_str(), record->bgModeId_, record->abilityId_);
1773 record->reason_ = SYSTEM_CANCEL;
1774 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1775 if (record->GetNotificationId() != -1) {
1776 NotificationTools::GetInstance()->CancelNotification(
1777 record->GetNotificationLabel(), record->GetNotificationId());
1778 }
1779 iter = continuousTaskInfosMap_.erase(iter);
1780 HandleAppContinuousTaskStop(record->uid_);
1781 RefreshTaskRecord();
1782 } else {
1783 iter++;
1784 }
1785 }
1786 }
1787
GetModeNumByTypeIds(const std::vector<uint32_t> & typeIds)1788 uint32_t BgContinuousTaskMgr::GetModeNumByTypeIds(const std::vector<uint32_t> &typeIds)
1789 {
1790 uint32_t modeNum = 0;
1791 for (auto mode : typeIds) {
1792 modeNum |= (1 << (mode - 1));
1793 }
1794 return modeNum;
1795 }
1796
CanNotifyHap(const std::shared_ptr<SubscriberInfo> subscriberInfo,const std::shared_ptr<ContinuousTaskCallbackInfo> & callbackInfo)1797 bool BgContinuousTaskMgr::CanNotifyHap(const std::shared_ptr<SubscriberInfo> subscriberInfo,
1798 const std::shared_ptr<ContinuousTaskCallbackInfo> &callbackInfo)
1799 {
1800 if (subscriberInfo->isHap_ && subscriberInfo->uid_ == callbackInfo->GetCreatorUid() &&
1801 (callbackInfo->GetCancelReason() == REMOVE_NOTIFICATION_CANCEL ||
1802 callbackInfo->GetCancelReason() == FREEZE_CANCEL)) {
1803 return true;
1804 }
1805 return false;
1806 }
1807
NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskCallbackInfo> & continuousTaskCallbackInfo)1808 void BgContinuousTaskMgr::NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,
1809 const std::shared_ptr<ContinuousTaskCallbackInfo> &continuousTaskCallbackInfo)
1810 {
1811 if (continuousTaskCallbackInfo == nullptr) {
1812 BGTASK_LOGD("continuousTaskCallbackInfo is null");
1813 return;
1814 }
1815 const ContinuousTaskCallbackInfo& taskCallbackInfoRef = *continuousTaskCallbackInfo;
1816 switch (changeEventType) {
1817 case ContinuousTaskEventTriggerType::TASK_START:
1818 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1819 BGTASK_LOGD("continuous task start callback trigger");
1820 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1821 (*iter)->subscriber_->OnContinuousTaskStart(taskCallbackInfoRef);
1822 }
1823 }
1824 break;
1825 case ContinuousTaskEventTriggerType::TASK_UPDATE:
1826 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1827 BGTASK_LOGD("continuous task update callback trigger");
1828 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1829 (*iter)->subscriber_->OnContinuousTaskUpdate(taskCallbackInfoRef);
1830 }
1831 }
1832 break;
1833 case ContinuousTaskEventTriggerType::TASK_CANCEL:
1834 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1835 BGTASK_LOGD("continuous task stop callback trigger");
1836 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1837 // notify all sa
1838 (*iter)->subscriber_->OnContinuousTaskStop(taskCallbackInfoRef);
1839 } else if (CanNotifyHap(*iter, continuousTaskCallbackInfo) && (*iter)->subscriber_) {
1840 // notify self hap
1841 BGTASK_LOGI("uid %{public}d is hap and uid is same, need notify cancel", (*iter)->uid_);
1842 (*iter)->subscriber_->OnContinuousTaskStop(taskCallbackInfoRef);
1843 }
1844 }
1845 break;
1846 case ContinuousTaskEventTriggerType::TASK_SUSPEND:
1847 NotifySubscribersTaskSuspend(continuousTaskCallbackInfo);
1848 break;
1849 case ContinuousTaskEventTriggerType::TASK_ACTIVE:
1850 NotifySubscribersTaskActive(continuousTaskCallbackInfo);
1851 break;
1852 default:
1853 BGTASK_LOGE("unknow ContinuousTaskEventTriggerType: %{public}d", changeEventType);
1854 break;
1855 }
1856 }
1857
NotifySubscribersTaskSuspend(const std::shared_ptr<ContinuousTaskCallbackInfo> & continuousTaskCallbackInfo)1858 void BgContinuousTaskMgr::NotifySubscribersTaskSuspend(
1859 const std::shared_ptr<ContinuousTaskCallbackInfo> &continuousTaskCallbackInfo)
1860 {
1861 const ContinuousTaskCallbackInfo& taskCallbackInfoRef = *continuousTaskCallbackInfo;
1862 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1863 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1864 // 对SA来说,长时任务暂停状态等同于取消长时任务,保持原有逻辑
1865 BGTASK_LOGD("continuous task suspend callback trigger");
1866 (*iter)->subscriber_->OnContinuousTaskStop(taskCallbackInfoRef);
1867 } else if ((*iter)->isHap_ &&
1868 (*iter)->uid_ == continuousTaskCallbackInfo->GetCreatorUid() && (*iter)->subscriber_) {
1869 // 回调通知应用长时任务暂停
1870 BGTASK_LOGI("uid %{public}d is hap and uid is same, need notify suspend, suspendReason: %{public}d"
1871 "suspendState: %{public}d", (*iter)->uid_, taskCallbackInfoRef.GetSuspendReason(),
1872 taskCallbackInfoRef.GetSuspendState());
1873 (*iter)->subscriber_->OnContinuousTaskSuspend(taskCallbackInfoRef);
1874 }
1875 }
1876 }
1877
NotifySubscribersTaskActive(const std::shared_ptr<ContinuousTaskCallbackInfo> & continuousTaskCallbackInfo)1878 void BgContinuousTaskMgr::NotifySubscribersTaskActive(
1879 const std::shared_ptr<ContinuousTaskCallbackInfo> &continuousTaskCallbackInfo)
1880 {
1881 const ContinuousTaskCallbackInfo& taskCallbackInfoRef = *continuousTaskCallbackInfo;
1882 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1883 BGTASK_LOGD("continuous task active callback trigger");
1884 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1885 // 对SA来说,长时任务激活状态等同于注册长时任务,保持原有逻辑
1886 (*iter)->subscriber_->OnContinuousTaskStart(taskCallbackInfoRef);
1887 } else if ((*iter)->isHap_ &&
1888 (*iter)->uid_ == continuousTaskCallbackInfo->GetCreatorUid() && (*iter)->subscriber_) {
1889 // 回调通知应用长时任务激活
1890 BGTASK_LOGI("uid %{public}d is hap and uid is same, need notify active", (*iter)->uid_);
1891 (*iter)->subscriber_->OnContinuousTaskActive(taskCallbackInfoRef);
1892 }
1893 }
1894 }
1895
ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskRecord> & continuousTaskInfo)1896 void BgContinuousTaskMgr::ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,
1897 const std::shared_ptr<ContinuousTaskRecord> &continuousTaskInfo)
1898 {
1899 switch (changeEventType) {
1900 case ContinuousTaskEventTriggerType::TASK_START:
1901 case ContinuousTaskEventTriggerType::TASK_UPDATE:
1902 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_APPLY",
1903 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1904 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1905 "ABILITY", continuousTaskInfo->GetAbilityName(),
1906 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1907 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId());
1908 break;
1909 case ContinuousTaskEventTriggerType::TASK_CANCEL:
1910 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_CANCEL",
1911 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1912 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1913 "ABILITY", continuousTaskInfo->GetAbilityName(),
1914 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1915 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId(), "STOP_REASON", continuousTaskInfo->reason_);
1916 break;
1917 default:
1918 break;
1919 }
1920 }
1921
OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,ContinuousTaskEventTriggerType changeEventType)1922 void BgContinuousTaskMgr::OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,
1923 ContinuousTaskEventTriggerType changeEventType)
1924 {
1925 if (continuousTaskInfo == nullptr) {
1926 BGTASK_LOGW("ContinuousTaskRecord is null");
1927 return;
1928 }
1929
1930 if (bgTaskSubscribers_.empty()) {
1931 BGTASK_LOGI("Background Task Subscriber List is empty");
1932 return;
1933 }
1934
1935 std::shared_ptr<ContinuousTaskCallbackInfo> continuousTaskCallbackInfo
1936 = std::make_shared<ContinuousTaskCallbackInfo>(continuousTaskInfo->GetBgModeId(),
1937 continuousTaskInfo->GetUid(), continuousTaskInfo->GetPid(), continuousTaskInfo->GetAbilityName(),
1938 continuousTaskInfo->IsFromWebview(), continuousTaskInfo->isBatchApi_, continuousTaskInfo->bgModeIds_,
1939 continuousTaskInfo->abilityId_, continuousTaskInfo->fullTokenId_);
1940 continuousTaskCallbackInfo->SetContinuousTaskId(continuousTaskInfo->continuousTaskId_);
1941 continuousTaskCallbackInfo->SetCancelReason(continuousTaskInfo->reason_);
1942 continuousTaskCallbackInfo->SetSuspendState(continuousTaskInfo->suspendState_);
1943 continuousTaskCallbackInfo->SetSuspendReason(continuousTaskInfo->suspendReason_);
1944 NotifySubscribers(changeEventType, continuousTaskCallbackInfo);
1945 ReportHisysEvent(changeEventType, continuousTaskInfo);
1946 }
1947
OnBundleInfoChanged(const std::string & action,const std::string & bundleName,int32_t uid)1948 void BgContinuousTaskMgr::OnBundleInfoChanged(const std::string &action, const std::string &bundleName, int32_t uid)
1949 {
1950 if (!isSysReady_.load()) {
1951 BGTASK_LOGW("manager is not ready");
1952 return;
1953 }
1954 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED
1955 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED
1956 || action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED
1957 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED
1958 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED
1959 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED) {
1960 cachedBundleInfos_.erase(uid);
1961 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) {
1962 cachedBundleInfos_.erase(uid);
1963 auto iter = continuousTaskInfosMap_.begin();
1964 while (iter != continuousTaskInfosMap_.end()) {
1965 if (iter->second->GetUid() == uid) {
1966 auto record = iter->second;
1967 record->reason_ = SYSTEM_CANCEL;
1968 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1969 NotificationTools::GetInstance()->CancelNotification(
1970 record->GetNotificationLabel(), record->GetNotificationId());
1971 iter = continuousTaskInfosMap_.erase(iter);
1972 HandleAppContinuousTaskStop(uid);
1973 RefreshTaskRecord();
1974 } else {
1975 iter++;
1976 }
1977 }
1978 } else {
1979 BGTASK_LOGW("get unregister common event!");
1980 return;
1981 }
1982 }
1983
OnAccountsStateChanged(int32_t id)1984 void BgContinuousTaskMgr::OnAccountsStateChanged(int32_t id)
1985 {
1986 std::vector<int32_t> activatedOsAccountIds;
1987 #ifdef HAS_OS_ACCOUNT_PART
1988 if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds) != ERR_OK) {
1989 BGTASK_LOGE("query activated account failed");
1990 return;
1991 }
1992 #else // HAS_OS_ACCOUNT_PART
1993 activatedOsAccountIds.push_back(DEFAULT_OS_ACCOUNT_ID);
1994 BGTASK_LOGI("there is no account part, use default id.");
1995 #endif // HAS_OS_ACCOUNT_PART
1996 auto iter = continuousTaskInfosMap_.begin();
1997 while (iter != continuousTaskInfosMap_.end()) {
1998 auto idIter = find(activatedOsAccountIds.begin(), activatedOsAccountIds.end(), iter->second->GetUserId());
1999 if (idIter == activatedOsAccountIds.end()) {
2000 auto record = iter->second;
2001 record->reason_ = SYSTEM_CANCEL;
2002 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
2003 NotificationTools::GetInstance()->CancelNotification(
2004 record->GetNotificationLabel(), record->GetNotificationId());
2005 iter = continuousTaskInfosMap_.erase(iter);
2006 HandleAppContinuousTaskStop(record->uid_);
2007 RefreshTaskRecord();
2008 } else {
2009 iter++;
2010 }
2011 }
2012 }
2013
HandleAppContinuousTaskStop(int32_t uid)2014 void BgContinuousTaskMgr::HandleAppContinuousTaskStop(int32_t uid)
2015 {
2016 auto findUid = [uid](const auto &target) {
2017 return uid == target.second->GetUid();
2018 };
2019 auto findUidIter = find_if(continuousTaskInfosMap_.begin(), continuousTaskInfosMap_.end(), findUid);
2020 if (findUidIter != continuousTaskInfosMap_.end()) {
2021 return;
2022 }
2023 BGTASK_LOGI("All continuous task has stopped of uid: %{public}d, so notify related subsystem", uid);
2024 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); iter++) {
2025 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
2026 (*iter)->subscriber_->OnAppContinuousTaskStop(uid);
2027 }
2028 }
2029 }
2030
RefreshTaskRecord()2031 int32_t BgContinuousTaskMgr::RefreshTaskRecord()
2032 {
2033 int32_t ret = DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
2034 if (ret != ERR_OK) {
2035 BGTASK_LOGE("refresh data failed");
2036 return ret;
2037 }
2038 return ERR_OK;
2039 }
2040
GetMainAbilityLabel(const std::string & bundleName,int32_t userId)2041 std::string BgContinuousTaskMgr::GetMainAbilityLabel(const std::string &bundleName, int32_t userId)
2042 {
2043 BgTaskHiTraceChain traceChain(__func__);
2044 std::string mainAbilityLabel {""};
2045 AppExecFwk::BundleResourceInfo bundleResourceInfo;
2046 if (BundleManagerHelper::GetInstance()->GetBundleResourceInfo(bundleName,
2047 AppExecFwk::ResourceFlag::GET_RESOURCE_INFO_ALL, bundleResourceInfo)) {
2048 mainAbilityLabel = bundleResourceInfo.label;
2049 }
2050 return mainAbilityLabel;
2051 }
2052
OnConfigurationChanged(const AppExecFwk::Configuration & configuration)2053 void BgContinuousTaskMgr::OnConfigurationChanged(const AppExecFwk::Configuration &configuration)
2054 {
2055 BgTaskHiTraceChain traceChain(__func__);
2056 if (!isSysReady_.load()) {
2057 BGTASK_LOGW("manager is not ready");
2058 return;
2059 }
2060 std::string languageChange = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
2061 if (languageChange.empty()) {
2062 return;
2063 }
2064 BGTASK_LOGI("System language config has changed");
2065 GetNotificationPrompt();
2066 cachedBundleInfos_.clear();
2067 std::map<std::string, std::pair<std::string, std::string>> newPromptInfos;
2068 auto iter = continuousTaskInfosMap_.begin();
2069 while (iter != continuousTaskInfosMap_.end()) {
2070 auto record = iter->second;
2071 if (!CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
2072 std::string mainAbilityLabel = GetMainAbilityLabel(record->bundleName_, record->userId_);
2073 std::string notificationText = GetNotificationText(record);
2074 newPromptInfos.emplace(record->notificationLabel_, std::make_pair(mainAbilityLabel, notificationText));
2075 }
2076 iter++;
2077 }
2078 NotificationTools::GetInstance()->RefreshContinuousNotifications(newPromptInfos, bgTaskUid_);
2079 }
2080
GetNotificationText(const std::shared_ptr<ContinuousTaskRecord> record)2081 std::string BgContinuousTaskMgr::GetNotificationText(const std::shared_ptr<ContinuousTaskRecord> record)
2082 {
2083 auto iter = avSessionNotification_.find(record->uid_);
2084 bool isPublish = (iter != avSessionNotification_.end()) ? iter->second : false;
2085 BGTASK_LOGD("AVSession Notification isPublish: %{public}d", isPublish);
2086 std::string notificationText {""};
2087 for (auto mode : record->bgModeIds_) {
2088 if ((mode == BackgroundMode::AUDIO_PLAYBACK && isPublish) || ((mode == BackgroundMode::VOIP ||
2089 mode == BackgroundMode::AUDIO_RECORDING) && record->IsSystem())) {
2090 continue;
2091 }
2092 if (mode == BackgroundMode::BLUETOOTH_INTERACTION &&
2093 CommonUtils::CheckExistMode(record->bgSubModeIds_, BackgroundSubMode::CAR_KEY)) {
2094 uint32_t index = BackgroundSubMode::CAR_KEY - 1;
2095 if (index < continuousTaskSubText_.size()) {
2096 notificationText += continuousTaskSubText_.at(index);
2097 notificationText += "\n";
2098 }
2099 continue;
2100 }
2101 uint32_t index = GetBgModeNameIndex(mode, record->isNewApi_);
2102 if (index < continuousTaskText_.size()) {
2103 notificationText += continuousTaskText_.at(index);
2104 notificationText += "\n";
2105 }
2106 }
2107 return notificationText;
2108 }
2109
HandleRemoveTaskByMode(uint32_t mode)2110 void BgContinuousTaskMgr::HandleRemoveTaskByMode(uint32_t mode)
2111 {
2112 auto iter = continuousTaskInfosMap_.begin();
2113 while (iter != continuousTaskInfosMap_.end()) {
2114 auto record = iter->second;
2115 if (record->isFromWebview_ && CommonUtils::CheckExistMode(record->bgModeIds_, mode)) {
2116 BGTASK_LOGI("HandleVoipTaskRemove uid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
2117 " bgModeId: %{public}d, abilityId: %{public}d", record->uid_, record->bundleName_.c_str(),
2118 record->abilityName_.c_str(), mode, record->abilityId_);
2119 record->reason_ = SYSTEM_CANCEL;
2120 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
2121 iter = continuousTaskInfosMap_.erase(iter);
2122 HandleAppContinuousTaskStop(record->uid_);
2123 RefreshTaskRecord();
2124 } else {
2125 iter++;
2126 }
2127 }
2128 }
2129
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)2130 void BgContinuousTaskMgr::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
2131 {
2132 if (!isSysReady_.load()) {
2133 BGTASK_LOGW("manager is not ready");
2134 return;
2135 }
2136 switch (systemAbilityId) {
2137 case SA_ID_VOIP_CALL_MANAGER:
2138 {
2139 BGTASK_LOGI("remove voip system ability, systemAbilityId: %{public}d", systemAbilityId);
2140 auto task = [this]() { this->HandleRemoveTaskByMode(BackgroundMode::VOIP); };
2141 handler_->PostTask(task);
2142 }
2143 break;
2144 case SA_ID_HEALTH_SPORT:
2145 {
2146 BGTASK_LOGI("remove healthsport system ability, systemAbilityId: %{public}d", systemAbilityId);
2147 auto task = [this]() { this->HandleRemoveTaskByMode(BackgroundMode::WORKOUT); };
2148 handler_->PostTask(task);
2149 }
2150 break;
2151 default:
2152 break;
2153 }
2154 }
2155 } // namespace BackgroundTaskMgr
2156 } // namespace OHOS
2157