• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 maxNotificationId = -1;
226     int32_t maxContinuousTaskId = -1;
227 
228     while (iter != continuousTaskInfosMap_.end()) {
229         bool pidIsAlive = checkPidCondition(allProcesses, iter->second->GetPid());
230         int32_t notificationId = iter->second->GetNotificationId();
231         if (notificationId > maxNotificationId) {
232             maxNotificationId = notificationId;
233         }
234         if (iter->second->continuousTaskId_ > maxContinuousTaskId) {
235             maxContinuousTaskId = iter->second->continuousTaskId_;
236         }
237 
238         if (pidIsAlive) {
239             if (iter->second->GetNotificationId() == -1) {
240                 BGTASK_LOGI("notification id is -1, continue");
241                 iter++;
242                 continue;
243             }
244             if (cachedBundleInfos_.find(iter->second->GetUid()) == cachedBundleInfos_.end()) {
245                 std::string mainAbilityLabel = GetMainAbilityLabel(iter->second->GetBundleName(),
246                     iter->second->GetUserId());
247                 SetCachedBundleInfo(iter->second->GetUid(), iter->second->GetUserId(),
248                     iter->second->GetBundleName(), mainAbilityLabel);
249             }
250             SendContinuousTaskNotification(iter->second);
251             BGTASK_LOGI("restore notification id %{public}d", iter->second->GetNotificationId());
252             iter++;
253         } else {
254             BGTASK_LOGI("process %{public}d die, not restore notification id %{public}d", iter->second->GetPid(),
255                 iter->second->GetNotificationId());
256             iter = continuousTaskInfosMap_.erase(iter);
257         }
258     }
259     if (maxNotificationId != -1) {
260         BGTASK_LOGI("set maxNotificationId %{public}d", maxNotificationId);
261         NotificationTools::SetNotificationIdIndex(maxNotificationId);
262     }
263     if (maxContinuousTaskId != -1) {
264         BGTASK_LOGI("set maxContinuousTaskId %{public}d", maxContinuousTaskId);
265         continuousTaskIdIndex_ = maxContinuousTaskId;
266     }
267 }
268 
checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t pid)269 bool BgContinuousTaskMgr::checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
270     int32_t pid)
271 {
272     auto findPid = [pid](const auto &target) {
273         return pid == target.pid_;
274     };
275     auto findPidIter = find_if(allProcesses.begin(), allProcesses.end(), findPid);
276     return findPidIter != allProcesses.end();
277 }
278 
checkNotificationCondition(const std::set<std::string> & notificationLabels,const std::string & label)279 bool BgContinuousTaskMgr::checkNotificationCondition(const std::set<std::string> &notificationLabels,
280     const std::string &label)
281 {
282 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
283     auto findLabel = [label](const auto &target) {
284         return label == target;
285     };
286     auto findLabelIter = find_if(notificationLabels.begin(), notificationLabels.end(), findLabel);
287     return findLabelIter != notificationLabels.end();
288 #else
289     return true;
290 #endif
291 }
292 
InitRequiredResourceInfo()293 void BgContinuousTaskMgr::InitRequiredResourceInfo()
294 {
295     if (!GetNotificationPrompt()) {
296         BGTASK_LOGW("init required resource info failed");
297     }
298     HandlePersistenceData();
299     isSysReady_.store(true);
300     DelayedSingleton<BackgroundTaskMgrService>::GetInstance()->SetReady(ServiceReadyState::CONTINUOUS_SERVICE_READY);
301     BGTASK_LOGI("SetReady CONTINUOUS_SERVICE_READY");
302 }
303 
RegisterNotificationSubscriber()304 bool BgContinuousTaskMgr::RegisterNotificationSubscriber()
305 {
306     bool res = true;
307 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
308     subscriber_ = std::make_shared<TaskNotificationSubscriber>();
309     if (Notification::NotificationHelper::SubscribeNotificationSelf(*subscriber_) != ERR_OK) {
310         BGTASK_LOGE("SubscribeNotificationSelf failed!");
311         res = false;
312     }
313 #endif
314     return res;
315 }
316 
RegisterAppStateObserver()317 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterAppStateObserver()
318 {
319     appStateObserver_ = new (std::nothrow) AppStateObserver(); // must be sprt
320     if (!appStateObserver_) {
321         BGTASK_LOGE("appStateObserver_ null");
322         return false;
323     }
324     auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
325         RegisterApplicationStateObserver(appStateObserver_);
326     if (res != ERR_OK) {
327         BGTASK_LOGE("RegisterApplicationStateObserver error");
328         return false;
329     }
330     appStateObserver_->SetEventHandler(handler_);
331     return true;
332 }
333 
UnregisterAppStateObserver()334 void BgContinuousTaskMgr::UnregisterAppStateObserver()
335 {
336     if (!appStateObserver_) {
337         return;
338     }
339     auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
340         UnregisterApplicationStateObserver(appStateObserver_);
341     if (res != ERR_OK) {
342         BGTASK_LOGE("UnregisterApplicationStateObserver error");
343         return;
344     }
345     appStateObserver_ = nullptr;
346     BGTASK_LOGI("UnregisterApplicationStateObserver ok");
347 }
348 
RegisterConfigurationObserver()349 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterConfigurationObserver()
350 {
351     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
352     if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
353         BGTASK_LOGW("connect to app mgr service failed");
354         return false;
355     }
356     configChangeObserver_ = sptr<AppExecFwk::IConfigurationObserver>(
357         new (std::nothrow) ConfigChangeObserver(handler_, shared_from_this()));
358     if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) {
359         return false;
360     }
361     return true;
362 }
363 
GetBundleResMgr(const AppExecFwk::BundleInfo & bundleInfo)364 std::shared_ptr<Global::Resource::ResourceManager> BgContinuousTaskMgr::GetBundleResMgr(
365     const AppExecFwk::BundleInfo &bundleInfo)
366 {
367     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
368     if (!resourceManager) {
369         BGTASK_LOGE("create resourceManager failed");
370         return nullptr;
371     }
372     for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
373         std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
374         if (moduleResPath.empty()) {
375             continue;
376         }
377         BGTASK_LOGD("GetBundleResMgr, moduleResPath: %{private}s", moduleResPath.c_str());
378         if (!resourceManager->AddResource(moduleResPath.c_str())) {
379             BGTASK_LOGW("GetBundleResMgr AddResource failed");
380         }
381     }
382     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
383 #ifdef SUPPORT_GRAPHICS
384     UErrorCode status = U_ZERO_ERROR;
385     icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
386     resConfig->SetLocaleInfo(locale);
387 #endif // SUPPORT_GRAPHICS
388     resourceManager->UpdateResConfig(*resConfig);
389     return resourceManager;
390 }
391 
GetNotificationPrompt()392 bool BgContinuousTaskMgr::GetNotificationPrompt()
393 {
394     continuousTaskText_.clear();
395     AppExecFwk::BundleInfo bundleInfo;
396     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(BG_TASK_RES_BUNDLE_NAME,
397         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo)) {
398         BGTASK_LOGE("get background task res: %{public}s bundle info failed", BG_TASK_RES_BUNDLE_NAME);
399         return false;
400     }
401     auto resourceManager = GetBundleResMgr(bundleInfo);
402     if (resourceManager == nullptr) {
403         BGTASK_LOGE("Get bgtask resource hap manager failed");
404         return false;
405     }
406     std::string taskText {""};
407     for (std::string name : g_taskPromptResNames) {
408         resourceManager->GetStringByName(name.c_str(), taskText);
409         if (taskText.empty()) {
410             BGTASK_LOGE("get continuous task notification text failed!");
411             return false;
412         }
413         BGTASK_LOGI("get taskText: %{public}s", taskText.c_str());
414         continuousTaskText_.push_back(taskText);
415     }
416     return true;
417 }
418 
RegisterSysCommEventListener()419 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterSysCommEventListener()
420 {
421     bool res = true;
422     EventFwk::MatchingSkills matchingSkills;
423     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
424     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
425     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
426     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED);
427     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED);
428     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED);
429     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED);
430     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
431     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
432     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
433     EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills);
434     systemEventListener_ = std::make_shared<SystemEventObserver>(commonEventSubscribeInfo);
435     if (systemEventListener_ != nullptr) {
436         systemEventListener_->SetEventHandler(handler_);
437         systemEventListener_->SetBgContinuousTaskMgr(shared_from_this());
438         res = systemEventListener_->Subscribe();
439     }
440     return res;
441 }
442 
GetBgTaskUid()443 int32_t BgContinuousTaskMgr::GetBgTaskUid()
444 {
445     return bgTaskUid_;
446 }
447 
SetCachedBundleInfo(int32_t uid,int32_t userId,const std::string & bundleName,const std::string & appName)448 bool BgContinuousTaskMgr::SetCachedBundleInfo(int32_t uid, int32_t userId,
449     const std::string &bundleName, const std::string &appName)
450 {
451     AppExecFwk::BundleInfo bundleInfo;
452     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
453         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
454         BGTASK_LOGE("get bundle info: %{public}s failure!", bundleName.c_str());
455         return false;
456     }
457 
458     CachedBundleInfo cachedBundleInfo = CachedBundleInfo();
459     cachedBundleInfo.appName_ = appName;
460     if (AddAbilityBgModeInfos(bundleInfo, cachedBundleInfo)) {
461         cachedBundleInfos_.emplace(uid, cachedBundleInfo);
462         return true;
463     }
464     return false;
465 }
466 
AddAbilityBgModeInfos(const AppExecFwk::BundleInfo & bundleInfo,CachedBundleInfo & cachedBundleInfo)467 bool BgContinuousTaskMgr::AddAbilityBgModeInfos(const AppExecFwk::BundleInfo &bundleInfo,
468     CachedBundleInfo &cachedBundleInfo)
469 {
470     for (auto abilityInfo : bundleInfo.abilityInfos) {
471         if (abilityInfo.backgroundModes != INVALID_BGMODE) {
472             cachedBundleInfo.abilityBgMode_.emplace(abilityInfo.name, abilityInfo.backgroundModes);
473             BGTASK_LOGI("abilityName: %{public}s, abilityNameHash: %{public}s, Background Mode: %{public}u.",
474                 abilityInfo.name.c_str(), std::to_string(std::hash<std::string>()(abilityInfo.name)).c_str(),
475                 abilityInfo.backgroundModes);
476         }
477     }
478     if (cachedBundleInfo.abilityBgMode_.empty()) {
479         return false;
480     }
481     return true;
482 }
483 
CheckBgmodeType(uint32_t configuredBgMode,uint32_t requestedBgModeId,bool isNewApi,uint64_t fullTokenId)484 ErrCode BgContinuousTaskMgr::CheckBgmodeType(uint32_t configuredBgMode, uint32_t requestedBgModeId,
485     bool isNewApi, uint64_t fullTokenId)
486 {
487     if (!isNewApi) {
488         if (configuredBgMode == INVALID_BGMODE) {
489             BGTASK_LOGE("ability without background mode config");
490             return ERR_BGMODE_NULL_OR_TYPE_ERR;
491         } else {
492             return ERR_OK;
493         }
494     } else {
495         uint32_t recordedBgMode = BG_MODE_INDEX_HEAD << (requestedBgModeId - 1);
496         if (recordedBgMode == SYSTEM_APP_BGMODE_WIFI_INTERACTION &&
497             !BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId)) {
498             BGTASK_LOGE("wifiInteraction background mode only support for system app");
499             return ERR_BGTASK_NOT_SYSTEM_APP;
500         }
501         if (recordedBgMode == PC_BGMODE_TASK_KEEPING && !SUPPORT_TASK_KEEPING) {
502             BGTASK_LOGE("task keeping is not supported, please set param "
503                 "persist.sys.bgtask_support_task_keeping.");
504             return ERR_BGTASK_KEEPING_TASK_VERIFY_ERR;
505         }
506         if (requestedBgModeId == INVALID_BGMODE || (configuredBgMode &
507             (BG_MODE_INDEX_HEAD << (requestedBgModeId - 1))) == 0) {
508             BGTASK_LOGE("requested background mode is not declared in config file, configuredBgMode: %{public}d",
509                 configuredBgMode);
510             return ERR_BGTASK_INVALID_BGMODE;
511         }
512     }
513     return ERR_OK;
514 }
515 
GetBackgroundModeInfo(int32_t uid,const std::string & abilityName)516 uint32_t BgContinuousTaskMgr::GetBackgroundModeInfo(int32_t uid, const std::string &abilityName)
517 {
518     if (cachedBundleInfos_.find(uid) != cachedBundleInfos_.end()) {
519         auto cachedBundleInfo = cachedBundleInfos_.at(uid);
520         if (cachedBundleInfo.abilityBgMode_.find(abilityName) !=
521             cachedBundleInfo.abilityBgMode_.end()) {
522             return cachedBundleInfo.abilityBgMode_.at(abilityName);
523         }
524     }
525     return INVALID_BGMODE;
526 }
527 
CheckTaskParam(const sptr<ContinuousTaskParam> & taskParam)528 bool CheckTaskParam(const sptr<ContinuousTaskParam> &taskParam)
529 {
530     if (!taskParam) {
531         BGTASK_LOGE("continuous task params is null!");
532         return false;
533     }
534 
535     if (taskParam->isNewApi_) {
536         if (taskParam->wantAgent_ == nullptr || taskParam->abilityName_.empty()) {
537             BGTASK_LOGE("continuous task params invalid!");
538             return false;
539         }
540         if (taskParam->isBatchApi_ && taskParam->bgModeIds_.empty()) {
541             BGTASK_LOGE("bgModeIds_ is empty");
542             return false;
543         }
544         if (taskParam->abilityId_ < 0) {
545             BGTASK_LOGE("abilityId_ is invalid");
546         }
547     } else {
548         if (taskParam->abilityName_.empty()) {
549             BGTASK_LOGE("continuous task params invalid!");
550             return false;
551         }
552     }
553     return true;
554 }
555 
CheckBgmodeTypeForInner(uint32_t requestedBgModeId)556 ErrCode BgContinuousTaskMgr::CheckBgmodeTypeForInner(uint32_t requestedBgModeId)
557 {
558     if (requestedBgModeId == INVALID_BGMODE || requestedBgModeId >= BGMODE_NUMS) {
559         BGTASK_LOGE("requested background mode is not declared in config file!");
560         return ERR_BGTASK_INVALID_BGMODE;
561     }
562     return ERR_OK;
563 }
564 
RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)565 ErrCode BgContinuousTaskMgr::RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
566 {
567     if (!isSysReady_.load()) {
568         BGTASK_LOGW("manager is not ready");
569         return ERR_BGTASK_SYS_NOT_READY;
570     }
571 
572     if (!taskParam) {
573         BGTASK_LOGE("continuous task param is null!");
574         return ERR_BGTASK_CHECK_TASK_PARAM;
575     }
576     int32_t callingUid = IPCSkeleton::GetCallingUid();
577     // webview sdk申请长时任务,上下文在应用。callkit sa 申请长时时,上下文在sa;
578     if (callingUid != VOIP_SA_UID && callingUid != taskParam->uid_) {
579         BGTASK_LOGE("continuous task param uid %{public}d is invalid, real %{public}d", taskParam->uid_, callingUid);
580         return ERR_BGTASK_CHECK_TASK_PARAM;
581     }
582     BGTASK_LOGI("continuous task param uid %{public}d, real %{public}d", taskParam->uid_, callingUid);
583     if (taskParam->isStart_) {
584         return StartBackgroundRunningForInner(taskParam);
585     }
586     return StopBackgroundRunningForInner(taskParam);
587 }
588 
StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)589 ErrCode BgContinuousTaskMgr::StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
590 {
591     ErrCode result = ERR_OK;
592     int32_t uid = taskParam->uid_;
593     pid_t callingPid = IPCSkeleton::GetCallingPid();
594     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
595     if (IPCSkeleton::GetCallingUid() == VOIP_SA_UID) {
596         fullTokenId = taskParam->tokenId_;
597     }
598     std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
599     std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
600     int32_t userId = -1;
601 
602 #ifdef HAS_OS_ACCOUNT_PART
603     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId);
604 #else // HAS_OS_ACCOUNT_PART
605     GetOsAccountIdFromUid(uid, userId);
606 #endif // HAS_OS_ACCOUNT_PART
607 
608     std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
609         abilityName, uid, callingPid, taskParam->bgModeId_);
610     continuousTaskRecord->isNewApi_ = true;
611     continuousTaskRecord->isFromWebview_ = true;
612     continuousTaskRecord->userId_ = userId;
613     continuousTaskRecord->fullTokenId_ = fullTokenId;
614 
615     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
616         "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
617     handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
618         result = this->StartBackgroundRunningInner(continuousTaskRecord);
619         }, AppExecFwk::EventQueue::Priority::HIGH);
620 
621     return result;
622 }
623 
StartBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)624 ErrCode BgContinuousTaskMgr::StartBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
625 {
626     if (!isSysReady_.load()) {
627         return ERR_BGTASK_SYS_NOT_READY;
628     }
629 
630     if (!CheckTaskParam(taskParam)) {
631         return ERR_BGTASK_CHECK_TASK_PARAM;
632     }
633     ErrCode result = ERR_OK;
634 
635     int32_t callingUid = IPCSkeleton::GetCallingUid();
636     pid_t callingPid = IPCSkeleton::GetCallingPid();
637     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
638     std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(callingUid);
639     int32_t userId = -1;
640 #ifdef HAS_OS_ACCOUNT_PART
641     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId);
642 #else // HAS_OS_ACCOUNT_PART
643     GetOsAccountIdFromUid(callingUid, userId);
644 #endif // HAS_OS_ACCOUNT_PART
645 
646     if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
647         BGTASK_LOGE("background mode permission is not passed");
648         return ERR_BGTASK_PERMISSION_DENIED;
649     }
650 
651     std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
652         taskParam->abilityName_, callingUid, callingPid, taskParam->bgModeId_, taskParam->isBatchApi_,
653         taskParam->bgModeIds_, taskParam->abilityId_);
654     continuousTaskRecord->wantAgent_ = taskParam->wantAgent_;
655     continuousTaskRecord->userId_ = userId;
656     continuousTaskRecord->isNewApi_ = taskParam->isNewApi_;
657     continuousTaskRecord->appName_ = taskParam->appName_;
658     continuousTaskRecord->fullTokenId_ = fullTokenId;
659     continuousTaskRecord->isSystem_ = BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId);
660 
661     if (taskParam->wantAgent_ != nullptr && taskParam->wantAgent_->GetPendingWant() != nullptr) {
662         auto target = taskParam->wantAgent_->GetPendingWant()->GetTarget();
663         auto want = taskParam->wantAgent_->GetPendingWant()->GetWant(target);
664         if (want != nullptr) {
665             std::shared_ptr<WantAgentInfo> info = std::make_shared<WantAgentInfo>();
666             info->bundleName_ = want->GetOperation().GetBundleName();
667             info->abilityName_ = want->GetOperation().GetAbilityName();
668             continuousTaskRecord->wantAgentInfo_ = info;
669         }
670     }
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     taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
679     taskParam->continuousTaskId_ = continuousTaskRecord->continuousTaskId_;
680     return result;
681 }
682 
UpdateBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)683 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
684 {
685     if (!isSysReady_.load()) {
686         BGTASK_LOGW("manager is not ready");
687         return ERR_BGTASK_SYS_NOT_READY;
688     }
689     if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
690         BGTASK_LOGE("background mode permission is not passed");
691         return ERR_BGTASK_PERMISSION_DENIED;
692     }
693     ErrCode result = ERR_OK;
694     int32_t callingUid = IPCSkeleton::GetCallingUid();
695 
696     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
697         "BackgroundTaskManager::ContinuousTask::Service::UpdateBackgroundRunningInner");
698     std::string taskInfoMapKey = std::to_string(callingUid) + SEPARATOR + taskParam->abilityName_ + SEPARATOR +
699         std::to_string(taskParam->abilityId_);
700     auto self = shared_from_this();
701     handler_->PostSyncTask([self, &taskInfoMapKey, &result, taskParam]() mutable {
702         if (!self) {
703             BGTASK_LOGE("self is null");
704             result = ERR_BGTASK_SERVICE_INNER_ERROR;
705             return;
706         }
707         result = self->UpdateBackgroundRunningInner(taskInfoMapKey, taskParam);
708         }, AppExecFwk::EventQueue::Priority::HIGH);
709     return result;
710 }
711 
UpdateBackgroundRunningInner(const std::string & taskInfoMapKey,const sptr<ContinuousTaskParam> & taskParam)712 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunningInner(const std::string &taskInfoMapKey,
713     const sptr<ContinuousTaskParam> &taskParam)
714 {
715     ErrCode ret;
716 
717     auto iter = continuousTaskInfosMap_.find(taskInfoMapKey);
718     if (iter == continuousTaskInfosMap_.end()) {
719         BGTASK_LOGW("continuous task is not exist: %{public}s, use start befor update", taskInfoMapKey.c_str());
720         return ERR_BGTASK_OBJECT_NOT_EXIST;
721     }
722 
723     auto continuousTaskRecord = iter->second;
724     auto oldModes = continuousTaskRecord->bgModeIds_;
725 
726     BGTASK_LOGI("continuous task mode %{public}d, old modes: %{public}s, new modes %{public}s, isBatchApi %{public}d,"
727         " abilityId %{public}d", continuousTaskRecord->bgModeId_,
728         continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
729         continuousTaskRecord->ToString(taskParam->bgModeIds_).c_str(),
730         continuousTaskRecord->isBatchApi_, continuousTaskRecord->abilityId_);
731     // update continuoustask by same modes.
732     if (CommonUtils::CheckModesSame(oldModes, taskParam->bgModeIds_)) {
733         BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same modes.",
734             continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
735         return ERR_OK;
736     }
737 
738     uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_, continuousTaskRecord->abilityName_);
739     for (auto it =  taskParam->bgModeIds_.begin(); it != taskParam->bgModeIds_.end(); it++) {
740         ret = CheckBgmodeType(configuredBgMode, *it, true, continuousTaskRecord->fullTokenId_);
741         if (ret != ERR_OK) {
742             BGTASK_LOGE("CheckBgmodeType error, config mode: %{public}u, apply mode: %{public}u.", configuredBgMode,
743                 *it);
744             return ret;
745         }
746     }
747     continuousTaskRecord->bgModeIds_ = taskParam->bgModeIds_;
748     continuousTaskRecord->isBatchApi_ = taskParam->isBatchApi_;
749 
750     // old and new task hava mode: DATA_TRANSFER, not update notification
751     if (CommonUtils::CheckExistMode(oldModes, BackgroundMode::DATA_TRANSFER) &&
752         CommonUtils::CheckExistMode(continuousTaskRecord->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
753         BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same mode: DATA_TRANSFER",
754             continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
755     } else {
756         ret = SendContinuousTaskNotification(continuousTaskRecord);
757         if (ret != ERR_OK) {
758             BGTASK_LOGE("publish error");
759             return ret;
760         }
761     }
762     OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_UPDATE);
763     taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
764     taskParam->continuousTaskId_ = continuousTaskRecord->GetContinuousTaskId();
765     return RefreshTaskRecord();
766 }
767 
StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)768 ErrCode BgContinuousTaskMgr::StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
769 {
770     std::string taskInfoMapKey = std::to_string(continuousTaskRecord->uid_) + SEPARATOR
771         + continuousTaskRecord->abilityName_ + SEPARATOR + std::to_string(continuousTaskRecord->abilityId_);
772     if (continuousTaskInfosMap_.find(taskInfoMapKey) != continuousTaskInfosMap_.end()) {
773         BGTASK_LOGW("continuous task is already exist: %{public}s", taskInfoMapKey.c_str());
774         return ERR_BGTASK_OBJECT_EXISTS;
775     }
776     BGTASK_LOGI("continuous task mode: %{public}u, modes %{public}s, isBatchApi %{public}d, uid %{public}d,"
777         " abilityId %{public}d", continuousTaskRecord->bgModeId_,
778         continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
779         continuousTaskRecord->isBatchApi_, continuousTaskRecord->uid_, continuousTaskRecord->abilityId_);
780     if (!continuousTaskRecord->isFromWebview_
781         && cachedBundleInfos_.find(continuousTaskRecord->uid_) == cachedBundleInfos_.end()) {
782         std::string mainAbilityLabel = GetMainAbilityLabel(continuousTaskRecord->bundleName_,
783             continuousTaskRecord->userId_);
784         SetCachedBundleInfo(continuousTaskRecord->uid_, continuousTaskRecord->userId_,
785             continuousTaskRecord->bundleName_, mainAbilityLabel);
786     }
787 
788     ErrCode ret;
789     if (continuousTaskRecord->isFromWebview_) {
790         ret = CheckBgmodeTypeForInner(continuousTaskRecord->bgModeId_);
791     } else {
792         uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_,
793             continuousTaskRecord->abilityName_);
794         for (auto it = continuousTaskRecord->bgModeIds_.begin(); it != continuousTaskRecord->bgModeIds_.end(); it++) {
795             ret = CheckBgmodeType(configuredBgMode, *it, continuousTaskRecord->isNewApi_,
796                 continuousTaskRecord->fullTokenId_);
797             if (ret != ERR_OK) {
798                 BGTASK_LOGE("CheckBgmodeType invalid!");
799                 return ret;
800             }
801         }
802     }
803 
804     if (!continuousTaskRecord->isFromWebview_) {
805         ret = SendContinuousTaskNotification(continuousTaskRecord);
806         if (ret != ERR_OK) {
807             BGTASK_LOGE("publish error");
808             return ret;
809         }
810     }
811     continuousTaskRecord->continuousTaskId_ = ++continuousTaskIdIndex_;
812     continuousTaskInfosMap_.emplace(taskInfoMapKey, continuousTaskRecord);
813     OnContinuousTaskChanged(continuousTaskRecord, ContinuousTaskEventTriggerType::TASK_START);
814     return RefreshTaskRecord();
815 }
816 
GetBgModeNameIndex(uint32_t bgModeId,bool isNewApi)817 uint32_t GetBgModeNameIndex(uint32_t bgModeId, bool isNewApi)
818 {
819     if (!isNewApi) {
820         return BGMODE_NUMS - 1;
821     } else {
822         return bgModeId - 1;
823     }
824 }
825 
SendContinuousTaskNotification(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)826 ErrCode BgContinuousTaskMgr::SendContinuousTaskNotification(
827     std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
828 {
829     if (continuousTaskText_.empty()) {
830         BGTASK_LOGE("get notification prompt info failed, continuousTaskText_ is empty");
831         return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
832     }
833     std::string appName {""};
834     if (cachedBundleInfos_.find(continuousTaskRecord->uid_) != cachedBundleInfos_.end()) {
835         appName = cachedBundleInfos_.at(continuousTaskRecord->uid_).appName_;
836     }
837     if (appName.empty()) {
838         BGTASK_LOGE("appName is empty");
839         return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
840     }
841 
842     std::string notificationText {""};
843     for (auto mode : continuousTaskRecord->bgModeIds_) {
844         if (mode == BackgroundMode::AUDIO_PLAYBACK || ((mode == BackgroundMode::VOIP ||
845             mode == BackgroundMode::AUDIO_RECORDING) && continuousTaskRecord->IsSystem())) {
846             continue;
847         }
848         BGTASK_LOGD("mode %{public}d", mode);
849         uint32_t index = GetBgModeNameIndex(mode, continuousTaskRecord->isNewApi_);
850         if (index < continuousTaskText_.size()) {
851             notificationText += continuousTaskText_.at(index);
852             notificationText += "\n";
853         } else {
854             BGTASK_LOGI("index is invalid");
855             return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
856         }
857     }
858     if (notificationText.empty()) {
859         if (continuousTaskRecord->GetNotificationId() != -1) {
860             NotificationTools::GetInstance()->CancelNotification(
861                 continuousTaskRecord->GetNotificationLabel(), continuousTaskRecord->GetNotificationId());
862             continuousTaskRecord->notificationId_ = -1;
863         }
864         return ERR_OK;
865     }
866     BGTASK_LOGD("notificationText %{public}s", notificationText.c_str());
867     return NotificationTools::GetInstance()->PublishNotification(continuousTaskRecord,
868         appName, notificationText, bgTaskUid_);
869 }
870 
StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)871 ErrCode BgContinuousTaskMgr::StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
872 {
873     ErrCode result = ERR_OK;
874     int32_t uid = taskParam->uid_;
875     int32_t abilityId = taskParam->abilityId_;
876     std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
877 
878     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
879         "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
880     handler_->PostSyncTask([this, uid, abilityName, abilityId, &result]() {
881         result = this->StopBackgroundRunningInner(uid, abilityName, abilityId);
882         }, AppExecFwk::EventQueue::Priority::HIGH);
883 
884     return result;
885 }
886 
StopBackgroundRunning(const std::string & abilityName,int32_t abilityId)887 ErrCode BgContinuousTaskMgr::StopBackgroundRunning(const std::string &abilityName, int32_t abilityId)
888 {
889     if (!isSysReady_.load()) {
890         BGTASK_LOGW("manager is not ready");
891         return ERR_BGTASK_SYS_NOT_READY;
892     }
893     if (abilityName.empty()) {
894         BGTASK_LOGE("abilityName is empty!");
895         return ERR_BGTASK_INVALID_PARAM;
896     }
897     if (abilityId < 0) {
898         BGTASK_LOGE("abilityId is Invalid!");
899     }
900     int32_t callingUid = IPCSkeleton::GetCallingUid();
901 
902     ErrCode result = ERR_OK;
903 
904     HitraceScoped traceScoped(HITRACE_TAG_OHOS,
905         "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
906     handler_->PostSyncTask([this, callingUid, abilityName, abilityId, &result]() {
907         result = this->StopBackgroundRunningInner(callingUid, abilityName, abilityId);
908         }, AppExecFwk::EventQueue::Priority::HIGH);
909 
910     return result;
911 }
912 
StopBackgroundRunningInner(int32_t uid,const std::string & abilityName,int32_t abilityId)913 ErrCode BgContinuousTaskMgr::StopBackgroundRunningInner(int32_t uid, const std::string &abilityName,
914     int32_t abilityId)
915 {
916     std::string mapKey = std::to_string(uid) + SEPARATOR + abilityName + SEPARATOR + std::to_string(abilityId);
917 
918     auto iter = continuousTaskInfosMap_.find(mapKey);
919     if (iter == continuousTaskInfosMap_.end()) {
920         BGTASK_LOGW("%{public}s continuous task not exists", mapKey.c_str());
921         return ERR_BGTASK_OBJECT_NOT_EXIST;
922     }
923     BGTASK_LOGI("%{public}s stop continuous task", mapKey.c_str());
924     ErrCode result = ERR_OK;
925     if (iter->second->GetNotificationId() != -1) {
926         result = NotificationTools::GetInstance()->CancelNotification(
927             iter->second->GetNotificationLabel(), iter->second->GetNotificationId());
928     }
929 
930     RemoveContinuousTaskRecord(mapKey);
931     return result;
932 }
933 
StopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)934 void BgContinuousTaskMgr::StopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
935 {
936     if (!isSysReady_.load()) {
937         BGTASK_LOGW("manager is not ready");
938         return;
939     }
940     auto self = shared_from_this();
941     auto task = [self, uid, pid, taskType, key]() {
942         if (self) {
943             self->HandleStopContinuousTask(uid, pid, taskType, key);
944         }
945     };
946     handler_->PostTask(task);
947 }
948 
HandleStopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)949 void BgContinuousTaskMgr::HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
950 {
951     BGTASK_LOGI("StopContinuousTask taskType: %{public}d, key %{public}s", taskType, key.c_str());
952     if (taskType == BackgroundMode::DATA_TRANSFER) {
953         RemoveContinuousTaskRecordByUidAndMode(uid, taskType);
954         return;
955     }
956     if (taskType == ALL_MODES) {
957         RemoveContinuousTaskRecordByUid(uid);
958         return;
959     }
960     if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) {
961         BGTASK_LOGW("remove TaskInfo failure, no matched task: %{public}s", key.c_str());
962         return;
963     }
964     NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(),
965         continuousTaskInfosMap_[key]->GetNotificationId());
966     SetReason(key, FREEZE_CANCEL);
967     RemoveContinuousTaskRecord(key);
968 }
969 
RemoveContinuousTaskRecordByUid(int32_t uid)970 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUid(int32_t uid)
971 {
972     auto iter = continuousTaskInfosMap_.begin();
973     while (iter != continuousTaskInfosMap_.end()) {
974         if (iter->second->GetUid() != uid) {
975             ++iter;
976             continue;
977         }
978         BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
979         iter->second->reason_ = FREEZE_CANCEL;
980         OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
981         NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
982             iter->second->GetNotificationId());
983         iter = continuousTaskInfosMap_.erase(iter);
984         RefreshTaskRecord();
985     }
986     HandleAppContinuousTaskStop(uid);
987 }
988 
RemoveContinuousTaskRecordByUidAndMode(int32_t uid,uint32_t mode)989 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUidAndMode(int32_t uid, uint32_t mode)
990 {
991     auto iter = continuousTaskInfosMap_.begin();
992     while (iter != continuousTaskInfosMap_.end()) {
993         if (iter->second->GetUid() != uid) {
994             ++iter;
995             continue;
996         }
997         auto findModeIter = std::find(iter->second->bgModeIds_.begin(), iter->second->bgModeIds_.end(), mode);
998         if (findModeIter == iter->second->bgModeIds_.end()) {
999             ++iter;
1000             continue;
1001         }
1002         BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
1003         iter->second->reason_ = FREEZE_CANCEL;
1004         OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
1005         NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
1006             iter->second->GetNotificationId());
1007         iter = continuousTaskInfosMap_.erase(iter);
1008         RefreshTaskRecord();
1009     }
1010     HandleAppContinuousTaskStop(uid);
1011 }
1012 
AddSubscriber(const std::shared_ptr<SubscriberInfo> subscriberInfo)1013 ErrCode BgContinuousTaskMgr::AddSubscriber(const std::shared_ptr<SubscriberInfo> subscriberInfo)
1014 {
1015     if (subscriberInfo == nullptr || subscriberInfo->subscriber_ == nullptr ||
1016         subscriberInfo->subscriber_->AsObject() == nullptr) {
1017         BGTASK_LOGE("subscriber is null.");
1018         return ERR_BGTASK_INVALID_PARAM;
1019     }
1020 
1021     handler_->PostSyncTask([=]() {
1022         AddSubscriberInner(subscriberInfo);
1023     });
1024     return ERR_OK;
1025 }
1026 
AddSubscriberInner(const std::shared_ptr<SubscriberInfo> subscriberInfo)1027 ErrCode BgContinuousTaskMgr::AddSubscriberInner(const std::shared_ptr<SubscriberInfo> subscriberInfo)
1028 {
1029     BGTASK_LOGD("BgContinuousTaskMgr enter");
1030     auto remoteObj = subscriberInfo->subscriber_->AsObject();
1031     auto findSuscriber = [&remoteObj](const auto& target) {
1032         return remoteObj == target->subscriber_->AsObject();
1033     };
1034 
1035     auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSuscriber);
1036     if (subscriberIter != bgTaskSubscribers_.end()) {
1037         BGTASK_LOGW("target subscriber already exist");
1038         return ERR_BGTASK_OBJECT_EXISTS;
1039     }
1040     bgTaskSubscribers_.emplace_back(subscriberInfo);
1041 
1042     if (!susriberDeathRecipient_) {
1043         susriberDeathRecipient_ = new (std::nothrow) RemoteDeathRecipient(
1044             [this](const wptr<IRemoteObject> &remote) { this->OnRemoteSubscriberDied(remote); });
1045     }
1046     if (susriberDeathRecipient_) {
1047         remoteObj->AddDeathRecipient(susriberDeathRecipient_);
1048     }
1049     BGTASK_LOGI("continuous subscribers size %{public}d", static_cast<int32_t>(bgTaskSubscribers_.size()));
1050     return ERR_OK;
1051 }
1052 
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)1053 ErrCode BgContinuousTaskMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
1054 {
1055     if (subscriber == nullptr) {
1056         BGTASK_LOGE("subscriber is null.");
1057         return ERR_BGTASK_INVALID_PARAM;
1058     }
1059 
1060     handler_->PostSyncTask([=]() {
1061         RemoveSubscriberInner(subscriber);
1062     });
1063     return ERR_OK;
1064 }
1065 
RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)1066 ErrCode BgContinuousTaskMgr::RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
1067 {
1068     auto remote = subscriber->AsObject();
1069     if (remote == nullptr) {
1070         BGTASK_LOGE("Subscriber' object is null.");
1071         return ERR_BGTASK_INVALID_PARAM;
1072     }
1073     auto findSubscriber = [&remote](const auto &info) {
1074         return remote == info->subscriber_->AsObject();
1075     };
1076 
1077     auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSubscriber);
1078     if (subscriberIter == bgTaskSubscribers_.end()) {
1079         BGTASK_LOGE("subscriber to remove is not exists.");
1080         return ERR_BGTASK_INVALID_PARAM;
1081     }
1082     if (susriberDeathRecipient_) {
1083         remote->RemoveDeathRecipient(susriberDeathRecipient_);
1084     }
1085     bgTaskSubscribers_.erase(subscriberIter);
1086     BGTASK_LOGI("Remove continuous task subscriber succeed");
1087     return ERR_OK;
1088 }
1089 
GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)1090 ErrCode BgContinuousTaskMgr::GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
1091 {
1092     if (!isSysReady_.load()) {
1093         BGTASK_LOGW("manager is not ready");
1094         return ERR_BGTASK_SYS_NOT_READY;
1095     }
1096 
1097     ErrCode result = ERR_OK;
1098 
1099     handler_->PostSyncTask([this, &list, &result]() {
1100         result = this->GetContinuousTaskAppsInner(list);
1101         }, AppExecFwk::EventQueue::Priority::HIGH);
1102 
1103     return result;
1104 }
1105 
GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)1106 ErrCode BgContinuousTaskMgr::GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
1107 {
1108     if (continuousTaskInfosMap_.empty()) {
1109         return ERR_OK;
1110     }
1111 
1112     for (auto record : continuousTaskInfosMap_) {
1113         auto appInfo = std::make_shared<ContinuousTaskCallbackInfo>(record.second->bgModeId_, record.second->uid_,
1114             record.second->pid_, record.second->abilityName_, record.second->isFromWebview_, record.second->isBatchApi_,
1115             record.second->bgModeIds_, record.second->abilityId_, record.second->fullTokenId_);
1116         list.push_back(appInfo);
1117     }
1118     return ERR_OK;
1119 }
1120 
ShellDump(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1121 ErrCode BgContinuousTaskMgr::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo)
1122 {
1123     if (!isSysReady_.load()) {
1124         BGTASK_LOGW("manager is not ready");
1125         return ERR_BGTASK_SYS_NOT_READY;
1126     }
1127     ErrCode result = ERR_OK;
1128     handler_->PostSyncTask([&]() {
1129         result = ShellDumpInner(dumpOption, dumpInfo);
1130     });
1131 
1132     return result;
1133 }
1134 
ShellDumpInner(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1135 ErrCode BgContinuousTaskMgr::ShellDumpInner(const std::vector<std::string> &dumpOption,
1136     std::vector<std::string> &dumpInfo)
1137 {
1138     if (dumpOption[1] == DUMP_PARAM_LIST_ALL) {
1139         DumpAllTaskInfo(dumpInfo);
1140     } else if (dumpOption[1] == DUMP_PARAM_CANCEL_ALL) {
1141         DumpCancelTask(dumpOption, true);
1142     } else if (dumpOption[1] == DUMP_PARAM_CANCEL) {
1143         DumpCancelTask(dumpOption, false);
1144     } else {
1145         BGTASK_LOGW("invalid dump param");
1146     }
1147     return ERR_OK;
1148 }
1149 
DumpAllTaskInfo(std::vector<std::string> & dumpInfo)1150 void BgContinuousTaskMgr::DumpAllTaskInfo(std::vector<std::string> &dumpInfo)
1151 {
1152     std::stringstream stream;
1153     if (continuousTaskInfosMap_.empty()) {
1154         dumpInfo.emplace_back("No running continuous task\n");
1155         return;
1156     }
1157     std::unordered_map<std::string, std::shared_ptr<ContinuousTaskRecord>>::iterator iter;
1158     uint32_t index = 1;
1159     for (iter = continuousTaskInfosMap_.begin(); iter != continuousTaskInfosMap_.end(); ++iter) {
1160         stream.str("");
1161         stream.clear();
1162         stream << "No." << index;
1163         stream << "\tcontinuousTaskKey: " << iter->first << "\n";
1164         stream << "\tcontinuousTaskValue:" << "\n";
1165         stream << "\t\tbundleName: " << iter->second->GetBundleName() << "\n";
1166         stream << "\t\tabilityName: " << iter->second->GetAbilityName() << "\n";
1167         stream << "\t\tisFromWebview: " << (iter->second->IsFromWebview() ? "true" : "false") << "\n";
1168         stream << "\t\tisFromNewApi: " << (iter->second->IsNewApi() ? "true" : "false") << "\n";
1169         stream << "\t\tbackgroundMode: " << g_continuousTaskModeName[GetBgModeNameIndex(
1170             iter->second->GetBgModeId(), iter->second->IsNewApi())] << "\n";
1171         stream << "\t\tisBatchApi: " << (iter->second->isBatchApi_ ? "true" : "false") << "\n";
1172         stream << "\t\tbackgroundModes: " << iter->second->ToString(iter->second->bgModeIds_) << "\n";
1173         stream << "\t\tuid: " << iter->second->GetUid() << "\n";
1174         stream << "\t\tuserId: " << iter->second->GetUserId() << "\n";
1175         stream << "\t\tpid: " << iter->second->GetPid() << "\n";
1176         stream << "\t\tnotificationLabel: " << iter->second->GetNotificationLabel() << "\n";
1177         stream << "\t\tnotificationId: " << iter->second->GetNotificationId() << "\n";
1178         stream << "\t\tcontinuousTaskId: " << iter->second->continuousTaskId_ << "\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     handler_->PostSyncTask([this, &object]() { this->OnRemoteSubscriberDiedInner(object); });
1274 }
1275 
OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> & object)1276 void BgContinuousTaskMgr::OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> &object)
1277 {
1278     sptr<IRemoteObject> objectProxy = object.promote();
1279     if (!objectProxy) {
1280         BGTASK_LOGE("get remote object failed");
1281         return;
1282     }
1283     auto iter = bgTaskSubscribers_.begin();
1284     while (iter != bgTaskSubscribers_.end()) {
1285         if ((*iter)->subscriber_->AsObject() == objectProxy) {
1286             BGTASK_LOGI("OnRemoteSubscriberDiedInner erase it");
1287             iter = bgTaskSubscribers_.erase(iter);
1288         } else {
1289             iter++;
1290         }
1291     }
1292     BGTASK_LOGI("continuous subscriber die, list size is %{public}d", static_cast<int>(bgTaskSubscribers_.size()));
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 
CanNotifyHap(const std::shared_ptr<SubscriberInfo> subscriberInfo,const std::shared_ptr<ContinuousTaskCallbackInfo> & callbackInfo)1361 bool BgContinuousTaskMgr::CanNotifyHap(const std::shared_ptr<SubscriberInfo> subscriberInfo,
1362     const std::shared_ptr<ContinuousTaskCallbackInfo> &callbackInfo)
1363 {
1364     if (subscriberInfo->isHap_ && subscriberInfo->uid_ == callbackInfo->GetCreatorUid() &&
1365         (callbackInfo->GetCancelReason() == REMOVE_NOTIFICATION_CANCEL ||
1366         callbackInfo->GetCancelReason() == FREEZE_CANCEL)) {
1367         return true;
1368     }
1369     return false;
1370 }
1371 
NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskCallbackInfo> & continuousTaskCallbackInfo)1372 void BgContinuousTaskMgr::NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,
1373     const std::shared_ptr<ContinuousTaskCallbackInfo> &continuousTaskCallbackInfo)
1374 {
1375     switch (changeEventType) {
1376         case ContinuousTaskEventTriggerType::TASK_START:
1377             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1378                 BGTASK_LOGD("continuous task start callback trigger");
1379                 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1380                     (*iter)->subscriber_->OnContinuousTaskStart(continuousTaskCallbackInfo);
1381                 }
1382             }
1383             break;
1384         case ContinuousTaskEventTriggerType::TASK_UPDATE:
1385             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1386                 BGTASK_LOGD("continuous task update callback trigger");
1387                 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1388                     (*iter)->subscriber_->OnContinuousTaskUpdate(continuousTaskCallbackInfo);
1389                 }
1390             }
1391             break;
1392         case ContinuousTaskEventTriggerType::TASK_CANCEL:
1393             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1394                 BGTASK_LOGD("continuous task stop callback trigger");
1395                 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1396                     // notify all sa
1397                     (*iter)->subscriber_->OnContinuousTaskStop(continuousTaskCallbackInfo);
1398                 } else if (CanNotifyHap(*iter, continuousTaskCallbackInfo) && (*iter)->subscriber_) {
1399                     // notify self hap
1400                     BGTASK_LOGI("uid %{public}d is hap and uid is same, need notify cancel", (*iter)->uid_);
1401                     (*iter)->subscriber_->OnContinuousTaskStop(continuousTaskCallbackInfo);
1402                 }
1403             }
1404             break;
1405     }
1406 }
1407 
ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskRecord> & continuousTaskInfo)1408 void BgContinuousTaskMgr::ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,
1409     const std::shared_ptr<ContinuousTaskRecord> &continuousTaskInfo)
1410 {
1411     switch (changeEventType) {
1412         case ContinuousTaskEventTriggerType::TASK_START:
1413         case ContinuousTaskEventTriggerType::TASK_UPDATE:
1414             HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_APPLY",
1415                 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1416                 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1417                 "ABILITY", continuousTaskInfo->GetAbilityName(),
1418                 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1419                 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId());
1420             break;
1421         case ContinuousTaskEventTriggerType::TASK_CANCEL:
1422             HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_CANCEL",
1423                 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1424                 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1425                 "ABILITY", continuousTaskInfo->GetAbilityName(),
1426                 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1427                 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId(), "STOP_REASON", continuousTaskInfo->reason_);
1428             break;
1429     }
1430 }
1431 
OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,ContinuousTaskEventTriggerType changeEventType)1432 void BgContinuousTaskMgr::OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,
1433     ContinuousTaskEventTriggerType changeEventType)
1434 {
1435     if (continuousTaskInfo == nullptr) {
1436         BGTASK_LOGW("ContinuousTaskRecord is null");
1437         return;
1438     }
1439 
1440     if (bgTaskSubscribers_.empty()) {
1441         BGTASK_LOGI("Background Task Subscriber List is empty");
1442         return;
1443     }
1444 
1445     std::shared_ptr<ContinuousTaskCallbackInfo> continuousTaskCallbackInfo
1446         = std::make_shared<ContinuousTaskCallbackInfo>(continuousTaskInfo->GetBgModeId(),
1447         continuousTaskInfo->GetUid(), continuousTaskInfo->GetPid(), continuousTaskInfo->GetAbilityName(),
1448         continuousTaskInfo->IsFromWebview(), continuousTaskInfo->isBatchApi_, continuousTaskInfo->bgModeIds_,
1449         continuousTaskInfo->abilityId_, continuousTaskInfo->fullTokenId_);
1450     BGTASK_LOGD("mode %{public}d isBatch %{public}d modes size %{public}u",
1451         continuousTaskCallbackInfo->GetTypeId(), continuousTaskCallbackInfo->IsBatchApi(),
1452         static_cast<uint32_t>(continuousTaskCallbackInfo->GetTypeIds().size()));
1453     continuousTaskCallbackInfo->SetContinuousTaskId(continuousTaskInfo->continuousTaskId_);
1454     continuousTaskCallbackInfo->SetCancelReason(continuousTaskInfo->reason_);
1455     NotifySubscribers(changeEventType, continuousTaskCallbackInfo);
1456     ReportHisysEvent(changeEventType, continuousTaskInfo);
1457 }
1458 
OnBundleInfoChanged(const std::string & action,const std::string & bundleName,int32_t uid)1459 void BgContinuousTaskMgr::OnBundleInfoChanged(const std::string &action, const std::string &bundleName, int32_t uid)
1460 {
1461     if (!isSysReady_.load()) {
1462         BGTASK_LOGW("manager is not ready");
1463         return;
1464     }
1465     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED
1466         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED
1467         || action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED
1468         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED
1469         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED
1470         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED) {
1471         cachedBundleInfos_.erase(uid);
1472     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) {
1473         cachedBundleInfos_.erase(uid);
1474         auto iter = continuousTaskInfosMap_.begin();
1475         while (iter != continuousTaskInfosMap_.end()) {
1476             if (iter->second->GetUid() == uid) {
1477                 auto record = iter->second;
1478                 record->reason_ = SYSTEM_CANCEL;
1479                 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1480                 NotificationTools::GetInstance()->CancelNotification(
1481                     record->GetNotificationLabel(), record->GetNotificationId());
1482                 iter = continuousTaskInfosMap_.erase(iter);
1483                 HandleAppContinuousTaskStop(uid);
1484                 RefreshTaskRecord();
1485             } else {
1486                 iter++;
1487             }
1488         }
1489     } else {
1490         BGTASK_LOGW("get unregister common event!");
1491         return;
1492     }
1493 }
1494 
OnAccountsStateChanged(int32_t id)1495 void BgContinuousTaskMgr::OnAccountsStateChanged(int32_t id)
1496 {
1497     std::vector<int32_t> activatedOsAccountIds;
1498 #ifdef HAS_OS_ACCOUNT_PART
1499     if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds) != ERR_OK) {
1500         BGTASK_LOGE("query activated account failed");
1501         return;
1502     }
1503 #else // HAS_OS_ACCOUNT_PART
1504     activatedOsAccountIds.push_back(DEFAULT_OS_ACCOUNT_ID);
1505     BGTASK_LOGI("there is no account part, use default id.");
1506 #endif // HAS_OS_ACCOUNT_PART
1507     auto iter = continuousTaskInfosMap_.begin();
1508     while (iter != continuousTaskInfosMap_.end()) {
1509         auto idIter = find(activatedOsAccountIds.begin(), activatedOsAccountIds.end(), iter->second->GetUserId());
1510         if (idIter == activatedOsAccountIds.end()) {
1511             auto record = iter->second;
1512             record->reason_ = SYSTEM_CANCEL;
1513             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1514             NotificationTools::GetInstance()->CancelNotification(
1515                 record->GetNotificationLabel(), record->GetNotificationId());
1516             iter = continuousTaskInfosMap_.erase(iter);
1517             HandleAppContinuousTaskStop(record->uid_);
1518             RefreshTaskRecord();
1519         } else {
1520             iter++;
1521         }
1522     }
1523 }
1524 
HandleAppContinuousTaskStop(int32_t uid)1525 void BgContinuousTaskMgr::HandleAppContinuousTaskStop(int32_t uid)
1526 {
1527     auto findUid = [uid](const auto &target) {
1528         return uid == target.second->GetUid();
1529     };
1530     auto findUidIter = find_if(continuousTaskInfosMap_.begin(), continuousTaskInfosMap_.end(), findUid);
1531     if (findUidIter != continuousTaskInfosMap_.end()) {
1532         return;
1533     }
1534     BGTASK_LOGI("All continuous task has stopped of uid: %{public}d, so notify related subsystem", uid);
1535     for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); iter++) {
1536         if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1537             (*iter)->subscriber_->OnAppContinuousTaskStop(uid);
1538         }
1539     }
1540 }
1541 
RefreshTaskRecord()1542 int32_t BgContinuousTaskMgr::RefreshTaskRecord()
1543 {
1544     int32_t ret = DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
1545     if (ret != ERR_OK) {
1546         BGTASK_LOGE("refresh data failed");
1547         return ret;
1548     }
1549     return ERR_OK;
1550 }
1551 
GetMainAbilityLabel(const std::string & bundleName,int32_t userId)1552 std::string BgContinuousTaskMgr::GetMainAbilityLabel(const std::string &bundleName, int32_t userId)
1553 {
1554     AppExecFwk::BundleInfo bundleInfo;
1555     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
1556         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
1557         BGTASK_LOGE("Get %{public}s bundle info failed", bundleName.c_str());
1558         return "";
1559     }
1560     auto resourceManager = GetBundleResMgr(bundleInfo);
1561     if (resourceManager == nullptr) {
1562         BGTASK_LOGE("Get %{public}s resource manager failed", bundleName.c_str());
1563         return "";
1564     }
1565 
1566     AppExecFwk::ApplicationInfo applicationInfo;
1567     if (!BundleManagerHelper::GetInstance()->GetApplicationInfo(bundleName,
1568         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, applicationInfo)) {
1569         BGTASK_LOGE("failed to get applicationInfo from AppExecFwk, bundleName is %{public}s", bundleName.c_str());
1570         return "";
1571     }
1572 
1573     std::string mainAbilityLabel {""};
1574     resourceManager->GetStringById(static_cast<uint32_t>(applicationInfo.labelId), mainAbilityLabel);
1575     BGTASK_LOGI("Get main ability label: %{public}s by labelId: %{public}d", mainAbilityLabel.c_str(),
1576         applicationInfo.labelId);
1577     mainAbilityLabel = mainAbilityLabel.empty() ? applicationInfo.label : mainAbilityLabel;
1578     return mainAbilityLabel;
1579 }
1580 
OnConfigurationChanged(const AppExecFwk::Configuration & configuration)1581 void BgContinuousTaskMgr::OnConfigurationChanged(const AppExecFwk::Configuration &configuration)
1582 {
1583     if (!isSysReady_.load()) {
1584         BGTASK_LOGW("manager is not ready");
1585         return;
1586     }
1587     std::string languageChange = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
1588     if (languageChange.empty()) {
1589         return;
1590     }
1591     BGTASK_LOGI("System language config has changed");
1592     GetNotificationPrompt();
1593     cachedBundleInfos_.clear();
1594     std::map<std::string, std::pair<std::string, std::string>> newPromptInfos;
1595     auto iter = continuousTaskInfosMap_.begin();
1596     while (iter != continuousTaskInfosMap_.end()) {
1597         auto record = iter->second;
1598         if (!CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
1599             std::string mainAbilityLabel = GetMainAbilityLabel(record->bundleName_, record->userId_);
1600 
1601             std::string notificationText {""};
1602             uint32_t index = GetBgModeNameIndex(record->bgModeId_, record->isNewApi_);
1603             if (index < BGMODE_NUMS) {
1604                 notificationText = continuousTaskText_.at(index);
1605             }
1606             newPromptInfos.emplace(record->notificationLabel_, std::make_pair(mainAbilityLabel, notificationText));
1607         }
1608         iter++;
1609     }
1610     NotificationTools::GetInstance()->RefreshContinuousNotifications(newPromptInfos, bgTaskUid_);
1611 }
1612 
HandleVoipTaskRemove()1613 void BgContinuousTaskMgr::HandleVoipTaskRemove()
1614 {
1615     auto iter = continuousTaskInfosMap_.begin();
1616     while (iter != continuousTaskInfosMap_.end()) {
1617         auto record = iter->second;
1618         if (record->isFromWebview_ && CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::VOIP)) {
1619             BGTASK_LOGI("HandleVoipTaskRemove uid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
1620                 " bgModeId: %{public}d, abilityId: %{public}d", record->uid_, record->bundleName_.c_str(),
1621                 record->abilityName_.c_str(), BackgroundMode::VOIP, record->abilityId_);
1622             record->reason_ = SYSTEM_CANCEL;
1623             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1624             iter = continuousTaskInfosMap_.erase(iter);
1625             HandleAppContinuousTaskStop(record->uid_);
1626             RefreshTaskRecord();
1627         } else {
1628             iter++;
1629         }
1630     }
1631 }
1632 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)1633 void BgContinuousTaskMgr::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
1634 {
1635     if (!isSysReady_.load()) {
1636         BGTASK_LOGW("manager is not ready");
1637         return;
1638     }
1639     switch (systemAbilityId) {
1640         case SA_ID_VOIP_CALL_MANAGER:
1641             {
1642                 BGTASK_LOGI("remove voip system ability, systemAbilityId: %{public}d", systemAbilityId);
1643                 auto task = [this]() { this->HandleVoipTaskRemove(); };
1644                 handler_->PostTask(task);
1645             }
1646             break;
1647         default:
1648             break;
1649     }
1650 }
1651 }  // namespace BackgroundTaskMgr
1652 }  // namespace OHOS
1653