1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bg_continuous_task_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 "parameters.h"
40 #include "running_process_info.h"
41 #include "string_wrapper.h"
42 #include "system_ability_definition.h"
43 
44 #include "bgtask_common.h"
45 #include "bgtaskmgr_inner_errors.h"
46 #include "continuous_task_record.h"
47 #include "continuous_task_log.h"
48 #include "system_event_observer.h"
49 #include "data_storage_helper.h"
50 #ifdef SUPPORT_GRAPHICS
51 #include "locale_config.h"
52 #endif // SUPPORT_GRAPHICS
53 #include "background_mode.h"
54 
55 namespace OHOS {
56 namespace BackgroundTaskMgr {
57 namespace {
58 static const char *g_taskPromptResNames[] = {
59     "ohos_bgmode_prompt_data_transfer",
60     "ohos_bgmode_prompt_audio_playback",
61     "ohos_bgmode_prompt_audio_recording",
62     "ohos_bgmode_prompt_location",
63     "ohos_bgmode_prompt_bluetooth_interaction",
64     "ohos_bgmode_prompt_multidevice_connection",
65     "ohos_bgmode_prompt_wifi_interaction",
66     "ohos_bgmode_prompt_voip",
67     "ohos_bgmode_prompt_task_keeping",
68     "ohos_bgmode_prompt_default_value",
69 };
70 
71 static constexpr char SEPARATOR[] = "_";
72 static constexpr char DUMP_PARAM_LIST_ALL[] = "--all";
73 static constexpr char DUMP_PARAM_CANCEL_ALL[] = "--cancel_all";
74 static constexpr char DUMP_PARAM_CANCEL[] = "--cancel";
75 static constexpr char BGMODE_PERMISSION[] = "ohos.permission.KEEP_BACKGROUND_RUNNING";
76 static constexpr char BG_TASK_RES_BUNDLE_NAME[] = "com.ohos.backgroundtaskmgr.resources";
77 static constexpr uint32_t SYSTEM_APP_BGMODE_WIFI_INTERACTION = 64;
78 static constexpr uint32_t PC_BGMODE_TASK_KEEPING = 256;
79 static constexpr int32_t DELAY_TIME = 2000;
80 static constexpr int32_t RECLAIM_MEMORY_DELAY_TIME = 20 * 60 * 1000;
81 static constexpr int32_t MAX_DUMP_PARAM_NUMS = 3;
82 static constexpr uint32_t INVALID_BGMODE = 0;
83 static constexpr uint32_t BG_MODE_INDEX_HEAD = 1;
84 static constexpr uint32_t BGMODE_NUMS = 10;
85 static constexpr uint32_t VOIP_SA_UID = 7022;
86 static constexpr uint32_t ALL_MODES = 0xFF;
87 
88 #ifndef HAS_OS_ACCOUNT_PART
89 constexpr int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part
90 constexpr int32_t UID_TRANSFORM_DIVISOR = 200000;
GetOsAccountIdFromUid(int32_t uid,int32_t & osAccountId)91 static void GetOsAccountIdFromUid(int32_t uid, int32_t &osAccountId)
92 {
93     osAccountId = uid / UID_TRANSFORM_DIVISOR;
94 }
95 #endif // HAS_OS_ACCOUNT_PART
96 }
97 
BgContinuousTaskMgr()98 BgContinuousTaskMgr::BgContinuousTaskMgr() {}
99 
~BgContinuousTaskMgr()100 BgContinuousTaskMgr::~BgContinuousTaskMgr() {}
101 
Init(const std::shared_ptr<AppExecFwk::EventRunner> & runner)102 bool BgContinuousTaskMgr::Init(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
103 {
104     if (runner == nullptr) {
105         BGTASK_LOGE("BgContinuousTaskMgr runner create failed!");
106         return false;
107     }
108     handler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
109     if (handler_ == nullptr) {
110         BGTASK_LOGE("BgContinuousTaskMgr handler create failed!");
111         return false;
112     }
113     std::string identity = IPCSkeleton::ResetCallingIdentity();
114     bgTaskUid_ = IPCSkeleton::GetCallingUid();
115     BGTASK_LOGI("BgContinuousTaskMgr service uid is: %{public}d", bgTaskUid_);
116     IPCSkeleton::SetCallingIdentity(identity);
117     auto registerTask = [this]() { this->InitNecessaryState(); };
118     handler_->PostSyncTask(registerTask);
119     auto self = shared_from_this();
120     auto reclaimTask = [self]() {
121         if (self) {
122             self->ReclaimProcessMemory(getpid());
123         }
124     };
125     handler_->PostTask(reclaimTask, RECLAIM_MEMORY_DELAY_TIME);
126     return true;
127 }
128 
ReclaimProcessMemory(int32_t pid)129 void BgContinuousTaskMgr::ReclaimProcessMemory(int32_t pid)
130 {
131     BGTASK_LOGI("BgContinuousTaskMgr reclaimProcessMemory pid: %{public}d start.", pid);
132     std::string path = "/proc/" + std::to_string(pid) + "/reclaim";
133     std::string contentStr = "1";
134     int fd = open(path.c_str(), O_WRONLY);
135     if (fd < 0) {
136         BGTASK_LOGE("BgContinuousTaskMgr ReclaimProcessMemory open file failed!");
137         return;
138     }
139     int res = write(fd, contentStr.c_str(), contentStr.length());
140     if (res == -1) {
141         BGTASK_LOGE("BgContinuousTaskMgr ReclaimProcessMemory write file failed!");
142     }
143     close(fd);
144     BGTASK_LOGI("BgContinuousTaskMgr reclaimProcessMemory pid: %{public}d end.", pid);
145 }
146 
Clear()147 void BgContinuousTaskMgr::Clear()
148 {
149 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
150     Notification::NotificationHelper::UnSubscribeNotification(*subscriber_);
151 #endif
152     if (systemEventListener_ != nullptr) {
153         systemEventListener_->Unsubscribe();
154     }
155     UnregisterAppStateObserver();
156 }
157 
InitNecessaryState()158 void BgContinuousTaskMgr::InitNecessaryState()
159 {
160     sptr<ISystemAbilityManager> systemAbilityManager
161         = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
162     if (systemAbilityManager == nullptr
163         || systemAbilityManager->CheckSystemAbility(APP_MGR_SERVICE_ID) == nullptr
164         || systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) == nullptr
165 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
166         || systemAbilityManager->CheckSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID) == nullptr
167 #endif
168         || systemAbilityManager->CheckSystemAbility(COMMON_EVENT_SERVICE_ID) == nullptr) {
169         BGTASK_LOGW("request system service is not ready yet!");
170         auto task = [this]() { this->InitNecessaryState(); };
171         handler_->PostTask(task, DELAY_TIME);
172         return;
173     }
174 
175     if (!RegisterNotificationSubscriber()) {
176         BGTASK_LOGE("RegisterNotificationSubscriber failed");
177         return;
178     }
179     if (!RegisterAppStateObserver()) {
180         BGTASK_LOGE("RegisterAppStateObserver failed");
181         return;
182     }
183     if (!RegisterSysCommEventListener()) {
184         BGTASK_LOGE("RegisterSysCommEventListener failed");
185         return;
186     }
187     if (!RegisterConfigurationObserver()) {
188         BGTASK_LOGE("RegisterConfigurationObserver failed");
189         return;
190     }
191     deviceType_ = OHOS::system::GetParameter("const.build.characteristics", "");
192     BGTASK_LOGI("current device type is: %{public}s", deviceType_.c_str());
193     InitRequiredResourceInfo();
194 }
195 
HandlePersistenceData()196 void BgContinuousTaskMgr::HandlePersistenceData()
197 {
198     BGTASK_LOGI("service restart, restore data");
199     DelayedSingleton<DataStorageHelper>::GetInstance()->RestoreTaskRecord(continuousTaskInfosMap_);
200     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
201     std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos;
202     if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
203         BGTASK_LOGW("connect to app mgr service failed");
204         return;
205     }
206     appMgrClient->GetAllRunningProcesses(allAppProcessInfos);
207     CheckPersistenceData(allAppProcessInfos);
208     DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
209 }
210 
CheckProcessUidInfo(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t uid)211 bool BgContinuousTaskMgr::CheckProcessUidInfo(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
212     int32_t uid)
213 {
214     for (const auto &runningProcessInfo : allProcesses) {
215         if (runningProcessInfo.uid_ == uid) {
216             return true;
217         }
218     }
219     return false;
220 }
221 
CheckPersistenceData(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses)222 void BgContinuousTaskMgr::CheckPersistenceData(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses)
223 {
224     auto iter = continuousTaskInfosMap_.begin();
225     int32_t maxId = -1;
226 
227     while (iter != continuousTaskInfosMap_.end()) {
228         bool pidIsAlive = checkPidCondition(allProcesses, iter->second->GetPid());
229         int32_t notificationId = iter->second->GetNotificationId();
230         if (notificationId > maxId) {
231             maxId = notificationId;
232         }
233         if (pidIsAlive) {
234             if (iter->second->GetNotificationId() == -1) {
235                 BGTASK_LOGI("notification id is -1, continue");
236                 iter++;
237                 continue;
238             }
239             if (cachedBundleInfos_.find(iter->second->GetUid()) == cachedBundleInfos_.end()) {
240                 std::string mainAbilityLabel = GetMainAbilityLabel(iter->second->GetBundleName(),
241                     iter->second->GetUserId());
242                 SetCachedBundleInfo(iter->second->GetUid(), iter->second->GetUserId(),
243                     iter->second->GetBundleName(), mainAbilityLabel);
244             }
245             SendContinuousTaskNotification(iter->second);
246             BGTASK_LOGI("restore notification id %{public}d", iter->second->GetNotificationId());
247             iter++;
248         } else {
249             BGTASK_LOGI("process %{public}d die, not restore notification id %{public}d", iter->second->GetPid(),
250                 iter->second->GetNotificationId());
251             iter = continuousTaskInfosMap_.erase(iter);
252         }
253     }
254     if (maxId != -1) {
255         BGTASK_LOGI("set maxId %{public}d", maxId);
256         NotificationTools::SetNotificationIdIndex(maxId);
257     }
258 }
259 
checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t pid)260 bool BgContinuousTaskMgr::checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
261     int32_t pid)
262 {
263     auto findPid = [pid](const auto &target) {
264         return pid == target.pid_;
265     };
266     auto findPidIter = find_if(allProcesses.begin(), allProcesses.end(), findPid);
267     return findPidIter != allProcesses.end();
268 }
269 
checkNotificationCondition(const std::set<std::string> & notificationLabels,const std::string & label)270 bool BgContinuousTaskMgr::checkNotificationCondition(const std::set<std::string> &notificationLabels,
271     const std::string &label)
272 {
273 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
274     auto findLabel = [label](const auto &target) {
275         return label == target;
276     };
277     auto findLabelIter = find_if(notificationLabels.begin(), notificationLabels.end(), findLabel);
278     return findLabelIter != notificationLabels.end();
279 #else
280     return true;
281 #endif
282 }
283 
InitRequiredResourceInfo()284 void BgContinuousTaskMgr::InitRequiredResourceInfo()
285 {
286     if (!GetNotificationPrompt()) {
287         BGTASK_LOGW("init required resource info failed");
288     }
289     HandlePersistenceData();
290     isSysReady_.store(true);
291     DelayedSingleton<BackgroundTaskMgrService>::GetInstance()->SetReady(ServiceReadyState::CONTINUOUS_SERVICE_READY);
292     BGTASK_LOGI("SetReady CONTINUOUS_SERVICE_READY");
293 }
294 
RegisterNotificationSubscriber()295 bool BgContinuousTaskMgr::RegisterNotificationSubscriber()
296 {
297     bool res = true;
298 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
299     subscriber_ = std::make_shared<TaskNotificationSubscriber>();
300     if (Notification::NotificationHelper::SubscribeNotificationSelf(*subscriber_) != ERR_OK) {
301         BGTASK_LOGE("SubscribeNotificationSelf failed!");
302         res = false;
303     }
304 #endif
305     return res;
306 }
307 
RegisterAppStateObserver()308 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterAppStateObserver()
309 {
310     appStateObserver_ = new (std::nothrow) AppStateObserver(); // must be sprt
311     if (!appStateObserver_) {
312         BGTASK_LOGE("appStateObserver_ null");
313         return false;
314     }
315     auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
316         RegisterApplicationStateObserver(appStateObserver_);
317     if (res != ERR_OK) {
318         BGTASK_LOGE("RegisterApplicationStateObserver error");
319         return false;
320     }
321     appStateObserver_->SetEventHandler(handler_);
322     return true;
323 }
324 
UnregisterAppStateObserver()325 void BgContinuousTaskMgr::UnregisterAppStateObserver()
326 {
327     if (!appStateObserver_) {
328         return;
329     }
330     auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
331         UnregisterApplicationStateObserver(appStateObserver_);
332     if (res != ERR_OK) {
333         BGTASK_LOGE("UnregisterApplicationStateObserver error");
334         return;
335     }
336     appStateObserver_ = nullptr;
337     BGTASK_LOGI("UnregisterApplicationStateObserver ok");
338 }
339 
RegisterConfigurationObserver()340 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterConfigurationObserver()
341 {
342     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
343     if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
344         BGTASK_LOGW("connect to app mgr service failed");
345         return false;
346     }
347     configChangeObserver_ = sptr<AppExecFwk::IConfigurationObserver>(
348         new (std::nothrow) ConfigChangeObserver(handler_, shared_from_this()));
349     if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) {
350         return false;
351     }
352     return true;
353 }
354 
GetBundleResMgr(const AppExecFwk::BundleInfo & bundleInfo)355 std::shared_ptr<Global::Resource::ResourceManager> BgContinuousTaskMgr::GetBundleResMgr(
356     const AppExecFwk::BundleInfo &bundleInfo)
357 {
358     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
359     if (!resourceManager) {
360         BGTASK_LOGE("create resourceManager failed");
361         return nullptr;
362     }
363     for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
364         std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
365         if (moduleResPath.empty()) {
366             continue;
367         }
368         BGTASK_LOGD("GetBundleResMgr, moduleResPath: %{private}s", moduleResPath.c_str());
369         if (!resourceManager->AddResource(moduleResPath.c_str())) {
370             BGTASK_LOGW("GetBundleResMgr AddResource failed");
371         }
372     }
373     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
374 #ifdef SUPPORT_GRAPHICS
375     UErrorCode status = U_ZERO_ERROR;
376     icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
377     resConfig->SetLocaleInfo(locale);
378 #endif // SUPPORT_GRAPHICS
379     resourceManager->UpdateResConfig(*resConfig);
380     return resourceManager;
381 }
382 
GetNotificationPrompt()383 bool BgContinuousTaskMgr::GetNotificationPrompt()
384 {
385     continuousTaskText_.clear();
386     AppExecFwk::BundleInfo bundleInfo;
387     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(BG_TASK_RES_BUNDLE_NAME,
388         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo)) {
389         BGTASK_LOGE("get background task res: %{public}s bundle info failed", BG_TASK_RES_BUNDLE_NAME);
390         return false;
391     }
392     auto resourceManager = GetBundleResMgr(bundleInfo);
393     if (resourceManager == nullptr) {
394         BGTASK_LOGE("Get bgtask resource hap manager failed");
395         return false;
396     }
397     std::string taskText {""};
398     for (std::string name : g_taskPromptResNames) {
399         resourceManager->GetStringByName(name.c_str(), taskText);
400         if (taskText.empty()) {
401             BGTASK_LOGE("get continuous task notification text failed!");
402             return false;
403         }
404         BGTASK_LOGI("get taskText: %{public}s", taskText.c_str());
405         continuousTaskText_.push_back(taskText);
406     }
407     return true;
408 }
409 
RegisterSysCommEventListener()410 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterSysCommEventListener()
411 {
412     bool res = true;
413     EventFwk::MatchingSkills matchingSkills;
414     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
415     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
416     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
417     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED);
418     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED);
419     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED);
420     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED);
421     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
422     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
423     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
424     EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills);
425     systemEventListener_ = std::make_shared<SystemEventObserver>(commonEventSubscribeInfo);
426     if (systemEventListener_ != nullptr) {
427         systemEventListener_->SetEventHandler(handler_);
428         systemEventListener_->SetBgContinuousTaskMgr(shared_from_this());
429         res = systemEventListener_->Subscribe();
430     }
431     return res;
432 }
433 
GetBgTaskUid()434 int32_t BgContinuousTaskMgr::GetBgTaskUid()
435 {
436     return bgTaskUid_;
437 }
438 
SetCachedBundleInfo(int32_t uid,int32_t userId,const std::string & bundleName,const std::string & appName)439 bool BgContinuousTaskMgr::SetCachedBundleInfo(int32_t uid, int32_t userId,
440     const std::string &bundleName, const std::string &appName)
441 {
442     AppExecFwk::BundleInfo bundleInfo;
443     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
444         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
445         BGTASK_LOGE("get bundle info: %{public}s failure!", bundleName.c_str());
446         return false;
447     }
448 
449     CachedBundleInfo cachedBundleInfo = CachedBundleInfo();
450     cachedBundleInfo.appName_ = appName;
451     if (AddAbilityBgModeInfos(bundleInfo, cachedBundleInfo)) {
452         cachedBundleInfos_.emplace(uid, cachedBundleInfo);
453         return true;
454     }
455     return false;
456 }
457 
AddAbilityBgModeInfos(const AppExecFwk::BundleInfo & bundleInfo,CachedBundleInfo & cachedBundleInfo)458 bool BgContinuousTaskMgr::AddAbilityBgModeInfos(const AppExecFwk::BundleInfo &bundleInfo,
459     CachedBundleInfo &cachedBundleInfo)
460 {
461     for (auto abilityInfo : bundleInfo.abilityInfos) {
462         if (abilityInfo.backgroundModes != INVALID_BGMODE) {
463             cachedBundleInfo.abilityBgMode_.emplace(abilityInfo.name, abilityInfo.backgroundModes);
464             BGTASK_LOGI("abilityName: %{public}s, abilityNameHash: %{public}s, Background Mode: %{public}u.",
465                 abilityInfo.name.c_str(), std::to_string(std::hash<std::string>()(abilityInfo.name)).c_str(),
466                 abilityInfo.backgroundModes);
467         }
468     }
469     if (cachedBundleInfo.abilityBgMode_.empty()) {
470         return false;
471     }
472     return true;
473 }
474 
CheckBgmodeType(uint32_t configuredBgMode,uint32_t requestedBgModeId,bool isNewApi,uint64_t fullTokenId)475 ErrCode BgContinuousTaskMgr::CheckBgmodeType(uint32_t configuredBgMode, uint32_t requestedBgModeId,
476     bool isNewApi, uint64_t fullTokenId)
477 {
478     if (!isNewApi) {
479         if (configuredBgMode == INVALID_BGMODE) {
480             BGTASK_LOGE("ability without background mode config");
481             return ERR_BGMODE_NULL_OR_TYPE_ERR;
482         } else {
483             return ERR_OK;
484         }
485     } else {
486         uint32_t recordedBgMode = BG_MODE_INDEX_HEAD << (requestedBgModeId - 1);
487         if (recordedBgMode == SYSTEM_APP_BGMODE_WIFI_INTERACTION &&
488             !BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId)) {
489             BGTASK_LOGE("wifiInteraction background mode only support for system app");
490             return ERR_BGTASK_NOT_SYSTEM_APP;
491         }
492         if (recordedBgMode == PC_BGMODE_TASK_KEEPING && !SUPPORT_TASK_KEEPING) {
493             BGTASK_LOGE("task keeping is not supported, please set param "
494                 "persist.sys.bgtask_support_task_keeping.");
495             return ERR_BGTASK_KEEPING_TASK_VERIFY_ERR;
496         }
497         if (requestedBgModeId == INVALID_BGMODE || (configuredBgMode &
498             (BG_MODE_INDEX_HEAD << (requestedBgModeId - 1))) == 0) {
499             BGTASK_LOGE("requested background mode is not declared in config file, configuredBgMode: %{public}d",
500                 configuredBgMode);
501             return ERR_BGTASK_INVALID_BGMODE;
502         }
503     }
504     return ERR_OK;
505 }
506 
GetBackgroundModeInfo(int32_t uid,const std::string & abilityName)507 uint32_t BgContinuousTaskMgr::GetBackgroundModeInfo(int32_t uid, const std::string &abilityName)
508 {
509     if (cachedBundleInfos_.find(uid) != cachedBundleInfos_.end()) {
510         auto cachedBundleInfo = cachedBundleInfos_.at(uid);
511         if (cachedBundleInfo.abilityBgMode_.find(abilityName) !=
512             cachedBundleInfo.abilityBgMode_.end()) {
513             return cachedBundleInfo.abilityBgMode_.at(abilityName);
514         }
515     }
516     return INVALID_BGMODE;
517 }
518 
CheckTaskParam(const sptr<ContinuousTaskParam> & taskParam)519 bool CheckTaskParam(const sptr<ContinuousTaskParam> &taskParam)
520 {
521     if (!taskParam) {
522         BGTASK_LOGE("continuous task params is null!");
523         return false;
524     }
525 
526     if (taskParam->isNewApi_) {
527         if (taskParam->wantAgent_ == nullptr || taskParam->abilityName_.empty()) {
528             BGTASK_LOGE("continuous task params invalid!");
529             return false;
530         }
531         if (taskParam->isBatchApi_ && taskParam->bgModeIds_.empty()) {
532             BGTASK_LOGE("bgModeIds_ is empty");
533             return false;
534         }
535         if (taskParam->abilityId_ < 0) {
536             BGTASK_LOGE("abilityId_ is invalid");
537         }
538     } else {
539         if (taskParam->abilityName_.empty()) {
540             BGTASK_LOGE("continuous task params invalid!");
541             return false;
542         }
543     }
544     return true;
545 }
546 
CheckBgmodeTypeForInner(uint32_t requestedBgModeId)547 ErrCode BgContinuousTaskMgr::CheckBgmodeTypeForInner(uint32_t requestedBgModeId)
548 {
549     if (requestedBgModeId == INVALID_BGMODE || requestedBgModeId >= BGMODE_NUMS) {
550         BGTASK_LOGE("requested background mode is not declared in config file!");
551         return ERR_BGTASK_INVALID_BGMODE;
552     }
553     return ERR_OK;
554 }
555 
RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)556 ErrCode BgContinuousTaskMgr::RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
557 {
558     if (!isSysReady_.load()) {
559         BGTASK_LOGW("manager is not ready");
560         return ERR_BGTASK_SYS_NOT_READY;
561     }
562 
563     if (!taskParam) {
564         BGTASK_LOGE("continuous task param is null!");
565         return ERR_BGTASK_CHECK_TASK_PARAM;
566     }
567     int32_t callingUid = IPCSkeleton::GetCallingUid();
568     // webview sdk申请长时任务,上下文在应用。callkit sa 申请长时时,上下文在sa;
569     if (callingUid != VOIP_SA_UID && callingUid != taskParam->uid_) {
570         BGTASK_LOGE("continuous task param uid %{public}d is invalid, real %{public}d", taskParam->uid_, callingUid);
571         return ERR_BGTASK_CHECK_TASK_PARAM;
572     }
573     BGTASK_LOGI("continuous task param uid %{public}d, real %{public}d", taskParam->uid_, callingUid);
574     if (taskParam->isStart_) {
575         return StartBackgroundRunningForInner(taskParam);
576     }
577     return StopBackgroundRunningForInner(taskParam);
578 }
579 
StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)580 ErrCode BgContinuousTaskMgr::StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
581 {
582     ErrCode result = ERR_OK;
583     int32_t uid = taskParam->uid_;
584     pid_t callingPid = IPCSkeleton::GetCallingPid();
585     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
586     if (IPCSkeleton::GetCallingUid() == VOIP_SA_UID) {
587         fullTokenId = taskParam->tokenId_;
588     }
589     std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
590     std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
591     int32_t userId = -1;
592 
593 #ifdef HAS_OS_ACCOUNT_PART
594     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId);
595 #else // HAS_OS_ACCOUNT_PART
596     GetOsAccountIdFromUid(uid, userId);
597 #endif // HAS_OS_ACCOUNT_PART
598 
599     std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
600         abilityName, uid, callingPid, taskParam->bgModeId_);
601     continuousTaskRecord->isNewApi_ = true;
602     continuousTaskRecord->isFromWebview_ = true;
603     continuousTaskRecord->userId_ = userId;
604     continuousTaskRecord->fullTokenId_ = fullTokenId;
605 
606     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
607         "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
608     handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
609         result = this->StartBackgroundRunningInner(continuousTaskRecord);
610         }, AppExecFwk::EventQueue::Priority::HIGH);
611 
612     return result;
613 }
614 
StartBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)615 ErrCode BgContinuousTaskMgr::StartBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
616 {
617     if (!isSysReady_.load()) {
618         BGTASK_LOGW("manager is not ready");
619         return ERR_BGTASK_SYS_NOT_READY;
620     }
621 
622     if (!CheckTaskParam(taskParam)) {
623         return ERR_BGTASK_CHECK_TASK_PARAM;
624     }
625     ErrCode result = ERR_OK;
626 
627     int32_t callingUid = IPCSkeleton::GetCallingUid();
628     pid_t callingPid = IPCSkeleton::GetCallingPid();
629     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
630     std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(callingUid);
631     int32_t userId = -1;
632 #ifdef HAS_OS_ACCOUNT_PART
633     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId);
634 #else // HAS_OS_ACCOUNT_PART
635     GetOsAccountIdFromUid(callingUid, userId);
636 #endif // HAS_OS_ACCOUNT_PART
637 
638     if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
639         BGTASK_LOGE("background mode permission is not passed");
640         return ERR_BGTASK_PERMISSION_DENIED;
641     }
642 
643     std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
644         taskParam->abilityName_, callingUid, callingPid, taskParam->bgModeId_, taskParam->isBatchApi_,
645         taskParam->bgModeIds_, taskParam->abilityId_);
646     continuousTaskRecord->wantAgent_ = taskParam->wantAgent_;
647     continuousTaskRecord->userId_ = userId;
648     continuousTaskRecord->isNewApi_ = taskParam->isNewApi_;
649     continuousTaskRecord->appName_ = taskParam->appName_;
650     continuousTaskRecord->fullTokenId_ = fullTokenId;
651     continuousTaskRecord->isSystem_ = BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId);
652 
653     if (taskParam->wantAgent_ != nullptr && taskParam->wantAgent_->GetPendingWant() != nullptr) {
654         auto target = taskParam->wantAgent_->GetPendingWant()->GetTarget();
655         auto want = taskParam->wantAgent_->GetPendingWant()->GetWant(target);
656         if (want != nullptr) {
657             std::shared_ptr<WantAgentInfo> info = std::make_shared<WantAgentInfo>();
658             info->bundleName_ = want->GetOperation().GetBundleName();
659             info->abilityName_ = want->GetOperation().GetAbilityName();
660             continuousTaskRecord->wantAgentInfo_ = info;
661         }
662     }
663 
664     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
665         "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
666     handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
667         result = this->StartBackgroundRunningInner(continuousTaskRecord);
668         }, AppExecFwk::EventQueue::Priority::HIGH);
669     taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
670     return result;
671 }
672 
UpdateBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)673 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
674 {
675     if (!isSysReady_.load()) {
676         BGTASK_LOGW("manager is not ready");
677         return ERR_BGTASK_SYS_NOT_READY;
678     }
679     if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
680         BGTASK_LOGE("background mode permission is not passed");
681         return ERR_BGTASK_PERMISSION_DENIED;
682     }
683     ErrCode result = ERR_OK;
684     int32_t callingUid = IPCSkeleton::GetCallingUid();
685 
686     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
687         "BackgroundTaskManager::ContinuousTask::Service::UpdateBackgroundRunningInner");
688     std::string taskInfoMapKey = std::to_string(callingUid) + SEPARATOR + taskParam->abilityName_ + SEPARATOR +
689         std::to_string(taskParam->abilityId_);
690     auto self = shared_from_this();
691     handler_->PostSyncTask([self, &taskInfoMapKey, &result, taskParam]() mutable {
692         if (!self) {
693             BGTASK_LOGE("self is null");
694             result = ERR_BGTASK_SERVICE_INNER_ERROR;
695             return;
696         }
697         result = self->UpdateBackgroundRunningInner(taskInfoMapKey, taskParam);
698         }, AppExecFwk::EventQueue::Priority::HIGH);
699 
700     return result;
701 }
702 
UpdateBackgroundRunningInner(const std::string & taskInfoMapKey,const sptr<ContinuousTaskParam> & taskParam)703 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunningInner(const std::string &taskInfoMapKey,
704     const sptr<ContinuousTaskParam> &taskParam)
705 {
706     ErrCode ret;
707 
708     auto iter = continuousTaskInfosMap_.find(taskInfoMapKey);
709     if (iter == continuousTaskInfosMap_.end()) {
710         BGTASK_LOGW("continuous task is not exist: %{public}s, use start befor update", taskInfoMapKey.c_str());
711         return ERR_BGTASK_OBJECT_NOT_EXIST;
712     }
713 
714     auto continuousTaskRecord = iter->second;
715     auto oldModes = continuousTaskRecord->bgModeIds_;
716 
717     BGTASK_LOGI("continuous task mode %{public}d, old modes: %{public}s, new modes %{public}s, isBatchApi %{public}d,"
718         " abilityId %{public}d", continuousTaskRecord->bgModeId_,
719         continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
720         continuousTaskRecord->ToString(taskParam->bgModeIds_).c_str(),
721         continuousTaskRecord->isBatchApi_, continuousTaskRecord->abilityId_);
722     // update continuoustask by same modes.
723     if (CommonUtils::CheckModesSame(oldModes, taskParam->bgModeIds_)) {
724         BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same modes.",
725             continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
726         return ERR_OK;
727     }
728 
729     uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_, continuousTaskRecord->abilityName_);
730     for (auto it =  taskParam->bgModeIds_.begin(); it != taskParam->bgModeIds_.end(); it++) {
731         ret = CheckBgmodeType(configuredBgMode, *it, true, continuousTaskRecord->fullTokenId_);
732         if (ret != ERR_OK) {
733             BGTASK_LOGE("CheckBgmodeType error, config mode: %{public}u, apply mode: %{public}u.", configuredBgMode,
734                 *it);
735             return ret;
736         }
737     }
738     continuousTaskRecord->bgModeIds_ = taskParam->bgModeIds_;
739     continuousTaskRecord->isBatchApi_ = taskParam->isBatchApi_;
740 
741     // old and new task hava mode: DATA_TRANSFER, not update notification
742     if (CommonUtils::CheckExistMode(oldModes, BackgroundMode::DATA_TRANSFER) &&
743         CommonUtils::CheckExistMode(continuousTaskRecord->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
744         BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same mode: DATA_TRANSFER",
745             continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
746     } else {
747         ret = SendContinuousTaskNotification(continuousTaskRecord);
748         if (ret != ERR_OK) {
749             BGTASK_LOGE("publish error");
750             return ret;
751         }
752     }
753     OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_UPDATE);
754     taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
755     return RefreshTaskRecord();
756 }
757 
758 
StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)759 ErrCode BgContinuousTaskMgr::StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
760 {
761     std::string taskInfoMapKey = std::to_string(continuousTaskRecord->uid_) + SEPARATOR
762         + continuousTaskRecord->abilityName_ + SEPARATOR + std::to_string(continuousTaskRecord->abilityId_);
763     if (continuousTaskInfosMap_.find(taskInfoMapKey) != continuousTaskInfosMap_.end()) {
764         BGTASK_LOGW("continuous task is already exist: %{public}s", taskInfoMapKey.c_str());
765         return ERR_BGTASK_OBJECT_EXISTS;
766     }
767     BGTASK_LOGI("continuous task mode: %{public}u, modes %{public}s, isBatchApi %{public}d, uid %{public}d,"
768         " abilityId %{public}d", continuousTaskRecord->bgModeId_,
769         continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
770         continuousTaskRecord->isBatchApi_, continuousTaskRecord->uid_, continuousTaskRecord->abilityId_);
771     if (!continuousTaskRecord->isFromWebview_
772         && cachedBundleInfos_.find(continuousTaskRecord->uid_) == cachedBundleInfos_.end()) {
773         std::string mainAbilityLabel = GetMainAbilityLabel(continuousTaskRecord->bundleName_,
774             continuousTaskRecord->userId_);
775         SetCachedBundleInfo(continuousTaskRecord->uid_, continuousTaskRecord->userId_,
776             continuousTaskRecord->bundleName_, mainAbilityLabel);
777     }
778 
779     ErrCode ret;
780     if (continuousTaskRecord->isFromWebview_) {
781         ret = CheckBgmodeTypeForInner(continuousTaskRecord->bgModeId_);
782     } else {
783         uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_,
784             continuousTaskRecord->abilityName_);
785         for (auto it = continuousTaskRecord->bgModeIds_.begin(); it != continuousTaskRecord->bgModeIds_.end(); it++) {
786             ret = CheckBgmodeType(configuredBgMode, *it, continuousTaskRecord->isNewApi_,
787                 continuousTaskRecord->fullTokenId_);
788             if (ret != ERR_OK) {
789                 BGTASK_LOGE("CheckBgmodeType invalid!");
790                 return ret;
791             }
792         }
793     }
794 
795     if (!continuousTaskRecord->isFromWebview_) {
796         ret = SendContinuousTaskNotification(continuousTaskRecord);
797         if (ret != ERR_OK) {
798             BGTASK_LOGE("publish error");
799             return ret;
800         }
801     }
802     continuousTaskInfosMap_.emplace(taskInfoMapKey, continuousTaskRecord);
803     OnContinuousTaskChanged(continuousTaskRecord, ContinuousTaskEventTriggerType::TASK_START);
804     return RefreshTaskRecord();
805 }
806 
GetBgModeNameIndex(uint32_t bgModeId,bool isNewApi)807 uint32_t GetBgModeNameIndex(uint32_t bgModeId, bool isNewApi)
808 {
809     if (!isNewApi) {
810         return BGMODE_NUMS - 1;
811     } else {
812         return bgModeId - 1;
813     }
814 }
815 
SendContinuousTaskNotification(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)816 ErrCode BgContinuousTaskMgr::SendContinuousTaskNotification(
817     std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
818 {
819     if (continuousTaskText_.empty()) {
820         BGTASK_LOGE("get notification prompt info failed, continuousTaskText_ is empty");
821         return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
822     }
823     std::string appName {""};
824     if (cachedBundleInfos_.find(continuousTaskRecord->uid_) != cachedBundleInfos_.end()) {
825         appName = cachedBundleInfos_.at(continuousTaskRecord->uid_).appName_;
826     }
827     if (appName.empty()) {
828         BGTASK_LOGE("appName is empty");
829         return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
830     }
831 
832     std::string notificationText {""};
833     for (auto mode : continuousTaskRecord->bgModeIds_) {
834         if (mode == BackgroundMode::AUDIO_PLAYBACK || ((mode == BackgroundMode::VOIP ||
835             mode == BackgroundMode::AUDIO_RECORDING) && continuousTaskRecord->IsSystem())) {
836             continue;
837         }
838         BGTASK_LOGD("mode %{public}d", mode);
839         uint32_t index = GetBgModeNameIndex(mode, continuousTaskRecord->isNewApi_);
840         if (index < continuousTaskText_.size()) {
841             notificationText += continuousTaskText_.at(index);
842             notificationText += "\n";
843         } else {
844             BGTASK_LOGI("index is invalid");
845             return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
846         }
847     }
848     if (notificationText.empty()) {
849         if (continuousTaskRecord->GetNotificationId() != -1) {
850             NotificationTools::GetInstance()->CancelNotification(
851                 continuousTaskRecord->GetNotificationLabel(), continuousTaskRecord->GetNotificationId());
852             continuousTaskRecord->notificationId_ = -1;
853         }
854         return ERR_OK;
855     }
856     BGTASK_LOGD("notificationText %{public}s", notificationText.c_str());
857     return NotificationTools::GetInstance()->PublishNotification(continuousTaskRecord,
858         appName, notificationText, bgTaskUid_);
859 }
860 
StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)861 ErrCode BgContinuousTaskMgr::StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
862 {
863     ErrCode result = ERR_OK;
864     int32_t uid = taskParam->uid_;
865     int32_t abilityId = taskParam->abilityId_;
866     std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
867 
868     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
869         "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
870     handler_->PostSyncTask([this, uid, abilityName, abilityId, &result]() {
871         result = this->StopBackgroundRunningInner(uid, abilityName, abilityId);
872         }, AppExecFwk::EventQueue::Priority::HIGH);
873 
874     return result;
875 }
876 
StopBackgroundRunning(const std::string & abilityName,int32_t abilityId)877 ErrCode BgContinuousTaskMgr::StopBackgroundRunning(const std::string &abilityName, int32_t abilityId)
878 {
879     if (!isSysReady_.load()) {
880         BGTASK_LOGW("manager is not ready");
881         return ERR_BGTASK_SYS_NOT_READY;
882     }
883     if (abilityName.empty()) {
884         BGTASK_LOGE("abilityName is empty!");
885         return ERR_BGTASK_INVALID_PARAM;
886     }
887     if (abilityId < 0) {
888         BGTASK_LOGE("abilityId is Invalid!");
889     }
890     int32_t callingUid = IPCSkeleton::GetCallingUid();
891 
892     ErrCode result = ERR_OK;
893 
894     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
895         "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
896     handler_->PostSyncTask([this, callingUid, abilityName, abilityId, &result]() {
897         result = this->StopBackgroundRunningInner(callingUid, abilityName, abilityId);
898         }, AppExecFwk::EventQueue::Priority::HIGH);
899 
900     return result;
901 }
902 
StopBackgroundRunningInner(int32_t uid,const std::string & abilityName,int32_t abilityId)903 ErrCode BgContinuousTaskMgr::StopBackgroundRunningInner(int32_t uid, const std::string &abilityName,
904     int32_t abilityId)
905 {
906     std::string mapKey = std::to_string(uid) + SEPARATOR + abilityName + SEPARATOR + std::to_string(abilityId);
907 
908     auto iter = continuousTaskInfosMap_.find(mapKey);
909     if (iter == continuousTaskInfosMap_.end()) {
910         BGTASK_LOGW("%{public}s continuous task not exists", mapKey.c_str());
911         return ERR_BGTASK_OBJECT_NOT_EXIST;
912     }
913     BGTASK_LOGI("%{public}s stop continuous task", mapKey.c_str());
914     ErrCode result = ERR_OK;
915     if (iter->second->GetNotificationId() != -1) {
916         result = NotificationTools::GetInstance()->CancelNotification(
917             iter->second->GetNotificationLabel(), iter->second->GetNotificationId());
918     }
919 
920     RemoveContinuousTaskRecord(mapKey);
921     return result;
922 }
923 
StopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)924 void BgContinuousTaskMgr::StopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
925 {
926     if (!isSysReady_.load()) {
927         BGTASK_LOGW("manager is not ready");
928         return;
929     }
930     auto self = shared_from_this();
931     auto task = [self, uid, pid, taskType, key]() {
932         if (self) {
933             self->HandleStopContinuousTask(uid, pid, taskType, key);
934         }
935     };
936     handler_->PostTask(task);
937 }
938 
HandleStopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)939 void BgContinuousTaskMgr::HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
940 {
941     BGTASK_LOGI("StopContinuousTask taskType: %{public}d, key %{public}s", taskType, key.c_str());
942     if (taskType == BackgroundMode::DATA_TRANSFER) {
943         RemoveContinuousTaskRecordByUidAndMode(uid, taskType);
944         return;
945     }
946     if (taskType == ALL_MODES) {
947         RemoveContinuousTaskRecordByUid(uid);
948         return;
949     }
950     if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) {
951         BGTASK_LOGW("remove TaskInfo failure, no matched task: %{public}s", key.c_str());
952         return;
953     }
954     NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(),
955         continuousTaskInfosMap_[key]->GetNotificationId());
956     SetReason(key, FREEZE_CANCEL);
957     RemoveContinuousTaskRecord(key);
958 }
959 
RemoveContinuousTaskRecordByUid(int32_t uid)960 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUid(int32_t uid)
961 {
962     auto iter = continuousTaskInfosMap_.begin();
963     while (iter != continuousTaskInfosMap_.end()) {
964         if (iter->second->GetUid() != uid) {
965             ++iter;
966             continue;
967         }
968         BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
969         iter->second->reason_ = FREEZE_CANCEL;
970         OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
971         NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
972             iter->second->GetNotificationId());
973         iter = continuousTaskInfosMap_.erase(iter);
974         RefreshTaskRecord();
975     }
976     HandleAppContinuousTaskStop(uid);
977 }
978 
RemoveContinuousTaskRecordByUidAndMode(int32_t uid,uint32_t mode)979 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUidAndMode(int32_t uid, uint32_t mode)
980 {
981     auto iter = continuousTaskInfosMap_.begin();
982     while (iter != continuousTaskInfosMap_.end()) {
983         if (iter->second->GetUid() != uid) {
984             ++iter;
985             continue;
986         }
987         auto findModeIter = std::find(iter->second->bgModeIds_.begin(), iter->second->bgModeIds_.end(), mode);
988         if (findModeIter == iter->second->bgModeIds_.end()) {
989             ++iter;
990             continue;
991         }
992         BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
993         iter->second->reason_ = FREEZE_CANCEL;
994         OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
995         NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
996             iter->second->GetNotificationId());
997         iter = continuousTaskInfosMap_.erase(iter);
998         RefreshTaskRecord();
999     }
1000     HandleAppContinuousTaskStop(uid);
1001 }
1002 
AddSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)1003 ErrCode BgContinuousTaskMgr::AddSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
1004 {
1005     if (subscriber == nullptr) {
1006         BGTASK_LOGE("subscriber is null.");
1007         return ERR_BGTASK_INVALID_PARAM;
1008     }
1009 
1010     handler_->PostSyncTask([=]() {
1011         AddSubscriberInner(subscriber);
1012     });
1013     return ERR_OK;
1014 }
1015 
AddSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)1016 ErrCode BgContinuousTaskMgr::AddSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
1017 {
1018     auto remoteObj = subscriber->AsObject();
1019     auto findSuscriber = [&remoteObj](const auto& target) {
1020         return remoteObj == target->AsObject();
1021     };
1022 
1023     auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSuscriber);
1024     if (subscriberIter != bgTaskSubscribers_.end()) {
1025         BGTASK_LOGW("target subscriber already exist");
1026         return ERR_BGTASK_OBJECT_EXISTS;
1027     }
1028 
1029     bgTaskSubscribers_.emplace_back(subscriber);
1030 
1031     if (subscriber->AsObject() == nullptr) {
1032         BGTASK_LOGW("subscriber is nullptr.");
1033         return ERR_BGTASK_INVALID_PARAM;
1034     }
1035     if (subscriberRecipients_.find(subscriber->AsObject()) != subscriberRecipients_.end()) {
1036         BGTASK_LOGW("bgtask subscriber object not exist.");
1037         return ERR_BGTASK_OBJECT_EXISTS;
1038     }
1039     sptr<RemoteDeathRecipient> deathRecipient = new (std::nothrow) RemoteDeathRecipient(
1040         [this](const wptr<IRemoteObject> &remote) { this->OnRemoteSubscriberDied(remote); });
1041     if (!deathRecipient) {
1042         BGTASK_LOGE("create death recipient failed");
1043         return ERR_BGTASK_INVALID_PARAM;
1044     }
1045     subscriber->AsObject()->AddDeathRecipient(deathRecipient);
1046     subscriberRecipients_.emplace(subscriber->AsObject(), deathRecipient);
1047     BGTASK_LOGI("Add continuous task subscriber succeed");
1048     return ERR_OK;
1049 }
1050 
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)1051 ErrCode BgContinuousTaskMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
1052 {
1053     if (subscriber == nullptr) {
1054         BGTASK_LOGE("subscriber is null.");
1055         return ERR_BGTASK_INVALID_PARAM;
1056     }
1057 
1058     handler_->PostSyncTask([=]() {
1059         RemoveSubscriberInner(subscriber);
1060     });
1061     return ERR_OK;
1062 }
1063 
RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)1064 ErrCode BgContinuousTaskMgr::RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
1065 {
1066     auto remote = subscriber->AsObject();
1067     if (remote == nullptr) {
1068         BGTASK_LOGE("Subscriber' object is null.");
1069         return ERR_BGTASK_INVALID_PARAM;
1070     }
1071     auto findSubscriber = [&remote](const auto &targetSubscriber) {
1072         return remote == targetSubscriber->AsObject();
1073     };
1074 
1075     auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSubscriber);
1076     if (subscriberIter == bgTaskSubscribers_.end()) {
1077         BGTASK_LOGE("subscriber to remove is not exists.");
1078         return ERR_BGTASK_INVALID_PARAM;
1079     }
1080 
1081     auto iter = subscriberRecipients_.find(remote);
1082     if (iter != subscriberRecipients_.end()) {
1083         iter->first->RemoveDeathRecipient(iter->second);
1084         subscriberRecipients_.erase(iter);
1085     }
1086     bgTaskSubscribers_.erase(subscriberIter);
1087     BGTASK_LOGI("Remove continuous task subscriber succeed");
1088     return ERR_OK;
1089 }
1090 
GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)1091 ErrCode BgContinuousTaskMgr::GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
1092 {
1093     if (!isSysReady_.load()) {
1094         BGTASK_LOGW("manager is not ready");
1095         return ERR_BGTASK_SYS_NOT_READY;
1096     }
1097 
1098     ErrCode result = ERR_OK;
1099 
1100     handler_->PostSyncTask([this, &list, &result]() {
1101         result = this->GetContinuousTaskAppsInner(list);
1102         }, AppExecFwk::EventQueue::Priority::HIGH);
1103 
1104     return result;
1105 }
1106 
GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)1107 ErrCode BgContinuousTaskMgr::GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
1108 {
1109     if (continuousTaskInfosMap_.empty()) {
1110         return ERR_OK;
1111     }
1112 
1113     for (auto record : continuousTaskInfosMap_) {
1114         auto appInfo = std::make_shared<ContinuousTaskCallbackInfo>(record.second->bgModeId_, record.second->uid_,
1115             record.second->pid_, record.second->abilityName_, record.second->isFromWebview_, record.second->isBatchApi_,
1116             record.second->bgModeIds_, record.second->abilityId_, record.second->fullTokenId_);
1117         list.push_back(appInfo);
1118     }
1119     return ERR_OK;
1120 }
1121 
ShellDump(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1122 ErrCode BgContinuousTaskMgr::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo)
1123 {
1124     if (!isSysReady_.load()) {
1125         BGTASK_LOGW("manager is not ready");
1126         return ERR_BGTASK_SYS_NOT_READY;
1127     }
1128     ErrCode result = ERR_OK;
1129     handler_->PostSyncTask([&]() {
1130         result = ShellDumpInner(dumpOption, dumpInfo);
1131     });
1132 
1133     return result;
1134 }
1135 
ShellDumpInner(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1136 ErrCode BgContinuousTaskMgr::ShellDumpInner(const std::vector<std::string> &dumpOption,
1137     std::vector<std::string> &dumpInfo)
1138 {
1139     if (dumpOption[1] == DUMP_PARAM_LIST_ALL) {
1140         DumpAllTaskInfo(dumpInfo);
1141     } else if (dumpOption[1] == DUMP_PARAM_CANCEL_ALL) {
1142         DumpCancelTask(dumpOption, true);
1143     } else if (dumpOption[1] == DUMP_PARAM_CANCEL) {
1144         DumpCancelTask(dumpOption, false);
1145     } else {
1146         BGTASK_LOGW("invalid dump param");
1147     }
1148     return ERR_OK;
1149 }
1150 
DumpAllTaskInfo(std::vector<std::string> & dumpInfo)1151 void BgContinuousTaskMgr::DumpAllTaskInfo(std::vector<std::string> &dumpInfo)
1152 {
1153     std::stringstream stream;
1154     if (continuousTaskInfosMap_.empty()) {
1155         dumpInfo.emplace_back("No running continuous task\n");
1156         return;
1157     }
1158     std::unordered_map<std::string, std::shared_ptr<ContinuousTaskRecord>>::iterator iter;
1159     uint32_t index = 1;
1160     for (iter = continuousTaskInfosMap_.begin(); iter != continuousTaskInfosMap_.end(); ++iter) {
1161         stream.str("");
1162         stream.clear();
1163         stream << "No." << index;
1164         stream << "\tcontinuousTaskKey: " << iter->first << "\n";
1165         stream << "\tcontinuousTaskValue:" << "\n";
1166         stream << "\t\tbundleName: " << iter->second->GetBundleName() << "\n";
1167         stream << "\t\tabilityName: " << iter->second->GetAbilityName() << "\n";
1168         stream << "\t\tisFromWebview: " << (iter->second->IsFromWebview() ? "true" : "false") << "\n";
1169         stream << "\t\tisFromNewApi: " << (iter->second->IsNewApi() ? "true" : "false") << "\n";
1170         stream << "\t\tbackgroundMode: " << g_continuousTaskModeName[GetBgModeNameIndex(
1171             iter->second->GetBgModeId(), iter->second->IsNewApi())] << "\n";
1172         stream << "\t\tisBatchApi: " << (iter->second->isBatchApi_ ? "true" : "false") << "\n";
1173         stream << "\t\tbackgroundModes: " << iter->second->ToString(iter->second->bgModeIds_) << "\n";
1174         stream << "\t\tuid: " << iter->second->GetUid() << "\n";
1175         stream << "\t\tuserId: " << iter->second->GetUserId() << "\n";
1176         stream << "\t\tpid: " << iter->second->GetPid() << "\n";
1177         stream << "\t\tnotificationLabel: " << iter->second->GetNotificationLabel() << "\n";
1178         stream << "\t\tnotificationId: " << iter->second->GetNotificationId() << "\n";
1179         if (iter->second->wantAgentInfo_ != nullptr) {
1180             stream << "\t\twantAgentBundleName: " << iter->second->wantAgentInfo_->bundleName_ << "\n";
1181             stream << "\t\twantAgentAbilityName: " << iter->second->wantAgentInfo_->abilityName_ << "\n";
1182         } else {
1183             stream << "\t\twantAgentBundleName: " << "NULL" << "\n";
1184             stream << "\t\twantAgentAbilityName: " << "NULL" << "\n";
1185         }
1186         stream << "\n";
1187         dumpInfo.emplace_back(stream.str());
1188         index++;
1189     }
1190 }
1191 
DumpCancelTask(const std::vector<std::string> & dumpOption,bool cleanAll)1192 void BgContinuousTaskMgr::DumpCancelTask(const std::vector<std::string> &dumpOption, bool cleanAll)
1193 {
1194     if (cleanAll) {
1195         std::set<int32_t> uids;
1196         for (auto item : continuousTaskInfosMap_) {
1197             NotificationTools::GetInstance()->CancelNotification(item.second->GetNotificationLabel(),
1198                 item.second->GetNotificationId());
1199             OnContinuousTaskChanged(item.second, ContinuousTaskEventTriggerType::TASK_CANCEL);
1200             uids.insert(item.second->uid_);
1201         }
1202         continuousTaskInfosMap_.clear();
1203         RefreshTaskRecord();
1204         for (int32_t uid : uids) {
1205             HandleAppContinuousTaskStop(uid);
1206         }
1207     } else {
1208         if (dumpOption.size() < MAX_DUMP_PARAM_NUMS) {
1209             BGTASK_LOGW("invalid dump param");
1210             return;
1211         }
1212         std::string taskKey = dumpOption[2];
1213         auto iter = continuousTaskInfosMap_.find(taskKey);
1214         if (iter == continuousTaskInfosMap_.end()) {
1215             return;
1216         }
1217         NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
1218             iter->second->GetNotificationId());
1219         RemoveContinuousTaskRecord(taskKey);
1220     }
1221 }
1222 
SetReason(const std::string & mapKey,int32_t reason)1223 void BgContinuousTaskMgr::SetReason(const std::string &mapKey, int32_t reason)
1224 {
1225     auto iter = continuousTaskInfosMap_.find(mapKey);
1226     if (iter == continuousTaskInfosMap_.end()) {
1227         BGTASK_LOGW("SetReason failure, no matched task: %{public}s", mapKey.c_str());
1228     } else {
1229         auto record = iter->second;
1230         record->reason_ = reason;
1231     }
1232 }
1233 
RemoveContinuousTaskRecord(const std::string & mapKey)1234 bool BgContinuousTaskMgr::RemoveContinuousTaskRecord(const std::string &mapKey)
1235 {
1236     if (continuousTaskInfosMap_.find(mapKey) == continuousTaskInfosMap_.end()) {
1237         BGTASK_LOGW("remove TaskInfo failure, no matched task: %{public}s", mapKey.c_str());
1238         return false;
1239     }
1240     BGTASK_LOGI("erase task info: %{public}s", mapKey.c_str());
1241     auto record = continuousTaskInfosMap_.at(mapKey);
1242     OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1243     continuousTaskInfosMap_.erase(mapKey);
1244     HandleAppContinuousTaskStop(record->uid_);
1245     RefreshTaskRecord();
1246     return true;
1247 }
1248 
StopContinuousTaskByUser(const std::string & mapKey)1249 bool BgContinuousTaskMgr::StopContinuousTaskByUser(const std::string &mapKey)
1250 {
1251     if (!isSysReady_.load()) {
1252         BGTASK_LOGW("manager is not ready");
1253         return false;
1254     }
1255     bool result = true;
1256     SetReason(mapKey, REMOVE_NOTIFICATION_CANCEL);
1257     handler_->PostSyncTask([this, mapKey, &result]() {
1258         result = RemoveContinuousTaskRecord(mapKey);
1259     });
1260     return result;
1261 }
1262 
OnRemoteSubscriberDied(const wptr<IRemoteObject> & object)1263 void BgContinuousTaskMgr::OnRemoteSubscriberDied(const wptr<IRemoteObject> &object)
1264 {
1265     if (!isSysReady_.load()) {
1266         BGTASK_LOGW("manager is not ready");
1267         return;
1268     }
1269     if (object == nullptr) {
1270         BGTASK_LOGE("remote object is null.");
1271         return;
1272     }
1273 
1274     handler_->PostSyncTask([this, &object]() { this->OnRemoteSubscriberDiedInner(object); });
1275 }
1276 
OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> & object)1277 void BgContinuousTaskMgr::OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> &object)
1278 {
1279     sptr<IRemoteObject> objectProxy = object.promote();
1280     if (!objectProxy) {
1281         BGTASK_LOGE("get remote object failed");
1282         return;
1283     }
1284     auto iter = bgTaskSubscribers_.begin();
1285     while (iter != bgTaskSubscribers_.end()) {
1286         if ((*iter)->AsObject() == objectProxy) {
1287             iter = bgTaskSubscribers_.erase(iter);
1288         } else {
1289             iter++;
1290         }
1291     }
1292     subscriberRecipients_.erase(objectProxy);
1293 }
1294 
OnAbilityStateChanged(int32_t uid,const std::string & abilityName,int32_t abilityId)1295 void BgContinuousTaskMgr::OnAbilityStateChanged(int32_t uid, const std::string &abilityName, int32_t abilityId)
1296 {
1297     if (!isSysReady_.load()) {
1298         BGTASK_LOGW("manager is not ready");
1299         return;
1300     }
1301     auto iter = continuousTaskInfosMap_.begin();
1302     while (iter != continuousTaskInfosMap_.end()) {
1303         if (iter->second->uid_ == uid && iter->second->abilityName_ == abilityName &&
1304             iter->second->abilityId_ == abilityId) {
1305             auto record = iter->second;
1306             BGTASK_LOGI("OnAbilityStateChanged uid: %{public}d, bundleName: %{public}s abilityName: %{public}s"
1307                 "bgModeId: %{public}d, abilityId: %{public}d", uid, record->bundleName_.c_str(),
1308                 record->abilityName_.c_str(), record->bgModeId_, record->abilityId_);
1309             record->reason_ = SYSTEM_CANCEL;
1310             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1311             if (!iter->second->isFromWebview_) {
1312                 NotificationTools::GetInstance()->CancelNotification(
1313                     record->GetNotificationLabel(), record->GetNotificationId());
1314             }
1315             iter = continuousTaskInfosMap_.erase(iter);
1316             HandleAppContinuousTaskStop(record->uid_);
1317             RefreshTaskRecord();
1318         } else {
1319             iter++;
1320         }
1321     }
1322 }
1323 
OnAppStopped(int32_t uid)1324 void BgContinuousTaskMgr::OnAppStopped(int32_t uid)
1325 {
1326     if (!isSysReady_.load()) {
1327         BGTASK_LOGW("manager is not ready");
1328         return;
1329     }
1330     auto iter = continuousTaskInfosMap_.begin();
1331     while (iter != continuousTaskInfosMap_.end()) {
1332         if (iter->second->uid_ == uid) {
1333             auto record = iter->second;
1334             BGTASK_LOGI("OnAppStopped uid: %{public}d, bundleName: %{public}s abilityName: %{public}s"
1335                 "bgModeId: %{public}d, abilityId: %{public}d", uid, record->bundleName_.c_str(),
1336                 record->abilityName_.c_str(), record->bgModeId_, record->abilityId_);
1337             record->reason_ = SYSTEM_CANCEL;
1338             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1339             if (!iter->second->isFromWebview_) {
1340                 NotificationTools::GetInstance()->CancelNotification(
1341                     record->GetNotificationLabel(), record->GetNotificationId());
1342             }
1343             iter = continuousTaskInfosMap_.erase(iter);
1344             HandleAppContinuousTaskStop(record->uid_);
1345             RefreshTaskRecord();
1346         } else {
1347             iter++;
1348         }
1349     }
1350 }
1351 
GetModeNumByTypeIds(const std::vector<uint32_t> & typeIds)1352 uint32_t BgContinuousTaskMgr::GetModeNumByTypeIds(const std::vector<uint32_t> &typeIds)
1353 {
1354     uint32_t modeNum = 0;
1355     for (auto mode : typeIds) {
1356         modeNum |= (1 << (mode - 1));
1357     }
1358     return modeNum;
1359 }
1360 
NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskCallbackInfo> & continuousTaskCallbackInfo)1361 void BgContinuousTaskMgr::NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,
1362     const std::shared_ptr<ContinuousTaskCallbackInfo> &continuousTaskCallbackInfo)
1363 {
1364     switch (changeEventType) {
1365         case ContinuousTaskEventTriggerType::TASK_START:
1366             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1367                 BGTASK_LOGD("continuous task start callback trigger");
1368                 (*iter)->OnContinuousTaskStart(continuousTaskCallbackInfo);
1369             }
1370             break;
1371         case ContinuousTaskEventTriggerType::TASK_UPDATE:
1372             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1373                 BGTASK_LOGD("continuous task update callback trigger");
1374                 (*iter)->OnContinuousTaskUpdate(continuousTaskCallbackInfo);
1375             }
1376             break;
1377         case ContinuousTaskEventTriggerType::TASK_CANCEL:
1378             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1379                 BGTASK_LOGD("continuous task stop callback trigger");
1380                 (*iter)->OnContinuousTaskStop(continuousTaskCallbackInfo);
1381             }
1382             break;
1383     }
1384 }
1385 
ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskRecord> & continuousTaskInfo)1386 void BgContinuousTaskMgr::ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,
1387     const std::shared_ptr<ContinuousTaskRecord> &continuousTaskInfo)
1388 {
1389     switch (changeEventType) {
1390         case ContinuousTaskEventTriggerType::TASK_START:
1391         case ContinuousTaskEventTriggerType::TASK_UPDATE:
1392             HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_APPLY",
1393                 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1394                 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1395                 "ABILITY", continuousTaskInfo->GetAbilityName(),
1396                 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1397                 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId());
1398             break;
1399         case ContinuousTaskEventTriggerType::TASK_CANCEL:
1400             HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_CANCEL",
1401                 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1402                 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1403                 "ABILITY", continuousTaskInfo->GetAbilityName(),
1404                 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1405                 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId(), "STOP_REASON", continuousTaskInfo->reason_);
1406             break;
1407     }
1408 }
1409 
OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,ContinuousTaskEventTriggerType changeEventType)1410 void BgContinuousTaskMgr::OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,
1411     ContinuousTaskEventTriggerType changeEventType)
1412 {
1413     if (continuousTaskInfo == nullptr) {
1414         BGTASK_LOGW("ContinuousTaskRecord is null");
1415         return;
1416     }
1417 
1418     if (bgTaskSubscribers_.empty()) {
1419         BGTASK_LOGI("Background Task Subscriber List is empty");
1420         return;
1421     }
1422 
1423     std::shared_ptr<ContinuousTaskCallbackInfo> continuousTaskCallbackInfo
1424         = std::make_shared<ContinuousTaskCallbackInfo>(continuousTaskInfo->GetBgModeId(),
1425         continuousTaskInfo->GetUid(), continuousTaskInfo->GetPid(), continuousTaskInfo->GetAbilityName(),
1426         continuousTaskInfo->IsFromWebview(), continuousTaskInfo->isBatchApi_, continuousTaskInfo->bgModeIds_,
1427         continuousTaskInfo->abilityId_, continuousTaskInfo->fullTokenId_);
1428     BGTASK_LOGD("mode %{public}d isBatch %{public}d modes size %{public}u",
1429         continuousTaskCallbackInfo->GetTypeId(), continuousTaskCallbackInfo->IsBatchApi(),
1430         static_cast<uint32_t>(continuousTaskCallbackInfo->GetTypeIds().size()));
1431     NotifySubscribers(changeEventType, continuousTaskCallbackInfo);
1432     ReportHisysEvent(changeEventType, continuousTaskInfo);
1433 }
1434 
OnBundleInfoChanged(const std::string & action,const std::string & bundleName,int32_t uid)1435 void BgContinuousTaskMgr::OnBundleInfoChanged(const std::string &action, const std::string &bundleName, int32_t uid)
1436 {
1437     if (!isSysReady_.load()) {
1438         BGTASK_LOGW("manager is not ready");
1439         return;
1440     }
1441     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED
1442         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED
1443         || action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED
1444         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED
1445         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED
1446         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED) {
1447         cachedBundleInfos_.erase(uid);
1448     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) {
1449         cachedBundleInfos_.erase(uid);
1450         auto iter = continuousTaskInfosMap_.begin();
1451         while (iter != continuousTaskInfosMap_.end()) {
1452             if (iter->second->GetUid() == uid) {
1453                 auto record = iter->second;
1454                 record->reason_ = SYSTEM_CANCEL;
1455                 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1456                 NotificationTools::GetInstance()->CancelNotification(
1457                     record->GetNotificationLabel(), record->GetNotificationId());
1458                 iter = continuousTaskInfosMap_.erase(iter);
1459                 HandleAppContinuousTaskStop(uid);
1460                 RefreshTaskRecord();
1461             } else {
1462                 iter++;
1463             }
1464         }
1465     } else {
1466         BGTASK_LOGW("get unregister common event!");
1467         return;
1468     }
1469 }
1470 
OnAccountsStateChanged(int32_t id)1471 void BgContinuousTaskMgr::OnAccountsStateChanged(int32_t id)
1472 {
1473     std::vector<int32_t> activatedOsAccountIds;
1474 #ifdef HAS_OS_ACCOUNT_PART
1475     if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds) != ERR_OK) {
1476         BGTASK_LOGE("query activated account failed");
1477         return;
1478     }
1479 #else // HAS_OS_ACCOUNT_PART
1480     activatedOsAccountIds.push_back(DEFAULT_OS_ACCOUNT_ID);
1481     BGTASK_LOGI("there is no account part, use default id.");
1482 #endif // HAS_OS_ACCOUNT_PART
1483     auto iter = continuousTaskInfosMap_.begin();
1484     while (iter != continuousTaskInfosMap_.end()) {
1485         auto idIter = find(activatedOsAccountIds.begin(), activatedOsAccountIds.end(), iter->second->GetUserId());
1486         if (idIter == activatedOsAccountIds.end()) {
1487             auto record = iter->second;
1488             record->reason_ = SYSTEM_CANCEL;
1489             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1490             NotificationTools::GetInstance()->CancelNotification(
1491                 record->GetNotificationLabel(), record->GetNotificationId());
1492             iter = continuousTaskInfosMap_.erase(iter);
1493             HandleAppContinuousTaskStop(record->uid_);
1494             RefreshTaskRecord();
1495         } else {
1496             iter++;
1497         }
1498     }
1499 }
1500 
HandleAppContinuousTaskStop(int32_t uid)1501 void BgContinuousTaskMgr::HandleAppContinuousTaskStop(int32_t uid)
1502 {
1503     auto findUid = [uid](const auto &target) {
1504         return uid == target.second->GetUid();
1505     };
1506     auto findUidIter = find_if(continuousTaskInfosMap_.begin(), continuousTaskInfosMap_.end(), findUid);
1507     if (findUidIter != continuousTaskInfosMap_.end()) {
1508         return;
1509     }
1510     BGTASK_LOGI("All continuous task has stopped of uid: %{public}d, so notify related subsystem", uid);
1511     for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); iter++) {
1512         (*iter)->OnAppContinuousTaskStop(uid);
1513     }
1514 }
1515 
RefreshTaskRecord()1516 int32_t BgContinuousTaskMgr::RefreshTaskRecord()
1517 {
1518     int32_t ret = DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
1519     if (ret != ERR_OK) {
1520         BGTASK_LOGE("refresh data failed");
1521         return ret;
1522     }
1523     return ERR_OK;
1524 }
1525 
GetMainAbilityLabel(const std::string & bundleName,int32_t userId)1526 std::string BgContinuousTaskMgr::GetMainAbilityLabel(const std::string &bundleName, int32_t userId)
1527 {
1528     AppExecFwk::BundleInfo bundleInfo;
1529     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
1530         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
1531         BGTASK_LOGE("Get %{public}s bundle info failed", bundleName.c_str());
1532         return "";
1533     }
1534     auto resourceManager = GetBundleResMgr(bundleInfo);
1535     if (resourceManager == nullptr) {
1536         BGTASK_LOGE("Get %{public}s resource manager failed", bundleName.c_str());
1537         return "";
1538     }
1539 
1540     AppExecFwk::ApplicationInfo applicationInfo;
1541     if (!BundleManagerHelper::GetInstance()->GetApplicationInfo(bundleName,
1542         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, applicationInfo)) {
1543         BGTASK_LOGE("failed to get applicationInfo from AppExecFwk, bundleName is %{public}s", bundleName.c_str());
1544         return "";
1545     }
1546 
1547     std::string mainAbilityLabel {""};
1548     resourceManager->GetStringById(static_cast<uint32_t>(applicationInfo.labelId), mainAbilityLabel);
1549     BGTASK_LOGI("Get main ability label: %{public}s by labelId: %{public}d", mainAbilityLabel.c_str(),
1550         applicationInfo.labelId);
1551     mainAbilityLabel = mainAbilityLabel.empty() ? applicationInfo.label : mainAbilityLabel;
1552     return mainAbilityLabel;
1553 }
1554 
OnConfigurationChanged(const AppExecFwk::Configuration & configuration)1555 void BgContinuousTaskMgr::OnConfigurationChanged(const AppExecFwk::Configuration &configuration)
1556 {
1557     if (!isSysReady_.load()) {
1558         BGTASK_LOGW("manager is not ready");
1559         return;
1560     }
1561     std::string languageChange = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
1562     if (languageChange.empty()) {
1563         return;
1564     }
1565     BGTASK_LOGI("System language config has changed");
1566     GetNotificationPrompt();
1567     cachedBundleInfos_.clear();
1568     std::map<std::string, std::pair<std::string, std::string>> newPromptInfos;
1569     auto iter = continuousTaskInfosMap_.begin();
1570     while (iter != continuousTaskInfosMap_.end()) {
1571         auto record = iter->second;
1572         if (!CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
1573             std::string mainAbilityLabel = GetMainAbilityLabel(record->bundleName_, record->userId_);
1574 
1575             std::string notificationText {""};
1576             uint32_t index = GetBgModeNameIndex(record->bgModeId_, record->isNewApi_);
1577             if (index < BGMODE_NUMS) {
1578                 notificationText = continuousTaskText_.at(index);
1579             }
1580             newPromptInfos.emplace(record->notificationLabel_, std::make_pair(mainAbilityLabel, notificationText));
1581         }
1582         iter++;
1583     }
1584     NotificationTools::GetInstance()->RefreshContinuousNotifications(newPromptInfos, bgTaskUid_);
1585 }
1586 
HandleVoipTaskRemove()1587 void BgContinuousTaskMgr::HandleVoipTaskRemove()
1588 {
1589     auto iter = continuousTaskInfosMap_.begin();
1590     while (iter != continuousTaskInfosMap_.end()) {
1591         auto record = iter->second;
1592         if (record->isFromWebview_ && CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::VOIP)) {
1593             BGTASK_LOGI("HandleVoipTaskRemove uid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
1594                 " bgModeId: %{public}d, abilityId: %{public}d", record->uid_, record->bundleName_.c_str(),
1595                 record->abilityName_.c_str(), BackgroundMode::VOIP, record->abilityId_);
1596             record->reason_ = SYSTEM_CANCEL;
1597             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1598             iter = continuousTaskInfosMap_.erase(iter);
1599             HandleAppContinuousTaskStop(record->uid_);
1600             RefreshTaskRecord();
1601         } else {
1602             iter++;
1603         }
1604     }
1605 }
1606 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)1607 void BgContinuousTaskMgr::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
1608 {
1609     if (!isSysReady_.load()) {
1610         BGTASK_LOGW("manager is not ready");
1611         return;
1612     }
1613     switch (systemAbilityId) {
1614         case SA_ID_VOIP_CALL_MANAGER:
1615             {
1616                 BGTASK_LOGI("remove voip system ability, systemAbilityId: %{public}d", systemAbilityId);
1617                 auto task = [this]() { this->HandleVoipTaskRemove(); };
1618                 handler_->PostTask(task);
1619             }
1620             break;
1621         default:
1622             break;
1623     }
1624 }
1625 }  // namespace BackgroundTaskMgr
1626 }  // namespace OHOS
1627