• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bg_continuous_task_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> &notificationLabels,
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 &notificationText,
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