• 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 
18 #include <sstream>
19 
20 #include "app_mgr_client.h"
21 #include "bundle_constants.h"
22 #include "bundle_manager_helper.h"
23 #include "common_event_support.h"
24 #include "common_event_manager.h"
25 #include "errors.h"
26 #include "hitrace_meter.h"
27 #include "if_system_ability_manager.h"
28 #include "iremote_object.h"
29 #include "iservice_registry.h"
30 #ifdef HAS_OS_ACCOUNT_PART
31 #include "os_account_manager.h"
32 #endif // HAS_OS_ACCOUNT_PART
33 #include "notification_tools.h"
34 #include "parameters.h"
35 #include "running_process_info.h"
36 #include "string_wrapper.h"
37 #include "system_ability_definition.h"
38 
39 #include "bgtaskmgr_inner_errors.h"
40 #include "continuous_task_record.h"
41 #include "continuous_task_log.h"
42 #include "system_event_observer.h"
43 #include "data_storage_helper.h"
44 #ifdef SUPPORT_GRAPHICS
45 #include "locale_config.h"
46 #endif // SUPPORT_GRAPHICS
47 
48 namespace OHOS {
49 namespace BackgroundTaskMgr {
50 namespace {
51 static const char *g_taskPromptResNames[] = {
52     "ohos_bgmode_prompt_data_transfer",
53     "ohos_bgmode_prompt_audio_playback",
54     "ohos_bgmode_prompt_audio_recording",
55     "ohos_bgmode_prompt_location",
56     "ohos_bgmode_prompt_bluetooth_interaction",
57     "ohos_bgmode_prompt_multidevice_connection",
58     "ohos_bgmode_prompt_wifi_interaction",
59     "ohos_bgmode_prompt_voip",
60     "ohos_bgmode_prompt_task_keeping",
61     "ohos_bgmode_prompt_default_value",
62 };
63 
64 static constexpr char BG_CONTINUOUS_TASK_MGR_NAME[] = "BgContinuousTaskMgr";
65 static constexpr char SEPARATOR[] = "_";
66 static constexpr char DUMP_PARAM_LIST_ALL[] = "--all";
67 static constexpr char DUMP_PARAM_CANCEL_ALL[] = "--cancel_all";
68 static constexpr char DUMP_PARAM_CANCEL[] = "--cancel";
69 static constexpr char BGMODE_PERMISSION[] = "ohos.permission.KEEP_BACKGROUND_RUNNING";
70 static constexpr char BG_TASK_RES_BUNDLE_NAME[] = "ohos.backgroundtaskmgr.resources";
71 static constexpr char DEVICE_TYPE_PC[] = "pc";
72 static constexpr uint32_t SYSTEM_APP_BGMODE_WIFI_INTERACTION = 64;
73 static constexpr uint32_t SYSTEM_APP_BGMODE_VOIP = 128;
74 static constexpr uint32_t PC_BGMODE_TASK_KEEPING = 256;
75 static constexpr int32_t DEFAULT_NOTIFICATION_ID = 0;
76 static constexpr int32_t DELAY_TIME = 2000;
77 static constexpr int32_t MAX_DUMP_PARAM_NUMS = 3;
78 static constexpr int32_t UNSET_UID = -1;
79 static constexpr uint32_t INVALID_BGMODE = 0;
80 static constexpr uint32_t BG_MODE_INDEX_HEAD = 1;
81 static constexpr uint32_t BGMODE_NUMS = 10;
82 
83 #ifndef HAS_OS_ACCOUNT_PART
84 constexpr int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part
85 constexpr int32_t UID_TRANSFORM_DIVISOR = 200000;
GetOsAccountIdFromUid(int32_t uid,int32_t & osAccountId)86 static void GetOsAccountIdFromUid(int32_t uid, int32_t &osAccountId)
87 {
88     osAccountId = uid / UID_TRANSFORM_DIVISOR;
89 }
90 #endif // HAS_OS_ACCOUNT_PART
91 }
92 
BgContinuousTaskMgr()93 BgContinuousTaskMgr::BgContinuousTaskMgr() {}
94 
~BgContinuousTaskMgr()95 BgContinuousTaskMgr::~BgContinuousTaskMgr() {}
96 
Init()97 bool BgContinuousTaskMgr::Init()
98 {
99     runner_ = AppExecFwk::EventRunner::Create(BG_CONTINUOUS_TASK_MGR_NAME);
100     if (runner_ == nullptr) {
101         BGTASK_LOGE("BgContinuousTaskMgr runner create failed!");
102         return false;
103     }
104     handler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner_);
105     if (handler_ == nullptr) {
106         BGTASK_LOGE("BgContinuousTaskMgr handler create failed!");
107         return false;
108     }
109     std::string identity = IPCSkeleton::ResetCallingIdentity();
110     bgTaskUid_ = IPCSkeleton::GetCallingUid();
111     BGTASK_LOGI("BgContinuousTaskMgr service uid is: %{public}d", bgTaskUid_);
112     IPCSkeleton::SetCallingIdentity(identity);
113     auto registerTask = [this]() { this->InitNecessaryState(); };
114     handler_->PostSyncTask(registerTask);
115     return true;
116 }
117 
Clear()118 void BgContinuousTaskMgr::Clear()
119 {
120 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
121     Notification::NotificationHelper::UnSubscribeNotification(*subscriber_);
122 #endif
123     if (systemEventListener_ != nullptr) {
124         systemEventListener_->Unsubscribe();
125     }
126     if (appStateObserver_ != nullptr) {
127         appStateObserver_->Unsubscribe();
128     }
129 }
130 
InitNecessaryState()131 void BgContinuousTaskMgr::InitNecessaryState()
132 {
133     sptr<ISystemAbilityManager> systemAbilityManager
134         = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
135     if (systemAbilityManager == nullptr
136         || systemAbilityManager->CheckSystemAbility(APP_MGR_SERVICE_ID) == nullptr
137         || systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) == nullptr
138 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
139         || systemAbilityManager->CheckSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID) == nullptr
140 #endif
141         || systemAbilityManager->CheckSystemAbility(COMMON_EVENT_SERVICE_ID) == nullptr) {
142         BGTASK_LOGW("request system service is not ready yet!");
143         auto task = [this]() { this->InitNecessaryState(); };
144         handler_->PostTask(task, DELAY_TIME);
145         return;
146     }
147 
148     if (!RegisterNotificationSubscriber()) {
149         BGTASK_LOGE("RegisterNotificationSubscriber failed");
150         return;
151     }
152     if (!RegisterAppStateObserver()) {
153         BGTASK_LOGE("RegisterAppStateObserver failed");
154         return;
155     }
156     if (!RegisterSysCommEventListener()) {
157         BGTASK_LOGE("RegisterSysCommEventListener failed");
158         return;
159     }
160     if (!RegisterConfigurationObserver()) {
161         BGTASK_LOGE("RegisterConfigurationObserver failed");
162         return;
163     }
164     deviceType_ = OHOS::system::GetParameter("const.build.characteristics", "");
165     BGTASK_LOGI("current device type is: %{public}s", deviceType_.c_str());
166     InitRequiredResourceInfo();
167 }
168 
HandlePersistenceData()169 void BgContinuousTaskMgr::HandlePersistenceData()
170 {
171     BGTASK_LOGI("service restart, restore data");
172     DelayedSingleton<DataStorageHelper>::GetInstance()->RestoreTaskRecord(continuousTaskInfosMap_);
173     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
174     std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos;
175     if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
176         BGTASK_LOGW("connect to app mgr service failed");
177         return;
178     }
179     appMgrClient->GetAllRunningProcesses(allAppProcessInfos);
180     std::set<std::string> labels;
181     NotificationTools::GetInstance()->GetAllActiveNotificationsLabels(labels);
182     CheckPersistenceData(allAppProcessInfos, labels);
183     DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
184 }
185 
CheckPersistenceData(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,const std::set<std::string> & allLabels)186 void BgContinuousTaskMgr::CheckPersistenceData(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
187     const std::set<std::string> &allLabels)
188 {
189     int32_t recordPid;
190     auto iter = continuousTaskInfosMap_.begin();
191     while (iter != continuousTaskInfosMap_.end()) {
192         recordPid = iter->second->GetPid();
193         const std::string recordLabel = iter->second->GetNotificationLabel();
194         if (checkPidCondition(allProcesses, recordPid) && checkNotificationCondition(allLabels, recordLabel)) {
195             BGTASK_LOGI("target continuous task exist");
196             iter++;
197             continue;
198         }
199 
200         if (!checkPidCondition(allProcesses, recordPid) && checkNotificationCondition(allLabels, recordLabel)) {
201             BGTASK_LOGI("pid: %{public}d not exist, label: %{public}s exist", recordPid, recordLabel.c_str());
202             NotificationTools::GetInstance()->CancelNotification(recordLabel, DEFAULT_NOTIFICATION_ID);
203             iter = continuousTaskInfosMap_.erase(iter);
204             continue;
205         }
206 
207         if (checkPidCondition(allProcesses, recordPid) && !checkNotificationCondition(allLabels, recordLabel)) {
208             BGTASK_LOGI("pid: %{public}d exist, label: %{public}s not exist", recordPid, recordLabel.c_str());
209             iter = continuousTaskInfosMap_.erase(iter);
210             continue;
211         }
212 
213         if (!checkPidCondition(allProcesses, recordPid) && !checkNotificationCondition(allLabels, recordLabel)) {
214             BGTASK_LOGI("pid: %{public}d not exist, label: %{public}s not exist", recordPid, recordLabel.c_str());
215             iter = continuousTaskInfosMap_.erase(iter);
216             continue;
217         }
218     }
219 }
220 
checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t pid)221 bool BgContinuousTaskMgr::checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
222     int32_t pid)
223 {
224     auto findPid = [pid](const auto &target) {
225         return pid == target.pid_;
226     };
227     auto findPidIter = find_if(allProcesses.begin(), allProcesses.end(), findPid);
228     return findPidIter != allProcesses.end();
229 }
230 
checkNotificationCondition(const std::set<std::string> & notificationLabels,const std::string & label)231 bool BgContinuousTaskMgr::checkNotificationCondition(const std::set<std::string> &notificationLabels,
232     const std::string &label)
233 {
234 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
235     auto findLabel = [label](const auto &target) {
236         return label == target;
237     };
238     auto findLabelIter = find_if(notificationLabels.begin(), notificationLabels.end(), findLabel);
239     return findLabelIter != notificationLabels.end();
240 #else
241     return true;
242 #endif
243 }
244 
InitRequiredResourceInfo()245 void BgContinuousTaskMgr::InitRequiredResourceInfo()
246 {
247     if (!GetNotificationPrompt()) {
248         BGTASK_LOGW("init required resource info failed. will try again");
249         isSysReady_.store(false);
250         auto task = [this]() { this->InitRequiredResourceInfo(); };
251         handler_->PostTask(task, DELAY_TIME);
252         return;
253     }
254     HandlePersistenceData();
255     isSysReady_.store(true);
256 }
257 
RegisterNotificationSubscriber()258 bool BgContinuousTaskMgr::RegisterNotificationSubscriber()
259 {
260     bool res = true;
261 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
262     subscriber_ = std::make_shared<TaskNotificationSubscriber>();
263     if (Notification::NotificationHelper::SubscribeNotification(*subscriber_) != ERR_OK) {
264         BGTASK_LOGE("SubscribeNotification failed!");
265         res = false;
266     }
267 #endif
268     return res;
269 }
270 
RegisterAppStateObserver()271 bool BgContinuousTaskMgr::RegisterAppStateObserver()
272 {
273     bool res = true;
274     appStateObserver_ = DelayedSingleton<AppStateObserver>::GetInstance();
275     if (appStateObserver_ != nullptr) {
276         appStateObserver_->SetEventHandler(handler_);
277         appStateObserver_->SetBgContinuousTaskMgr(shared_from_this());
278         res = appStateObserver_->Subscribe();
279     }
280     return res;
281 }
282 
RegisterConfigurationObserver()283 bool BgContinuousTaskMgr::RegisterConfigurationObserver()
284 {
285     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
286     if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
287         BGTASK_LOGW("connect to app mgr service failed");
288         return false;
289     }
290     configChangeObserver_ = sptr<AppExecFwk::IConfigurationObserver>(
291         new (std::nothrow) ConfigChangeObserver(handler_, shared_from_this()));
292     if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) {
293         return false;
294     }
295     return true;
296 }
297 
GetBundleResMgr(const AppExecFwk::BundleInfo & bundleInfo)298 std::shared_ptr<Global::Resource::ResourceManager> BgContinuousTaskMgr::GetBundleResMgr(
299     const AppExecFwk::BundleInfo &bundleInfo)
300 {
301     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
302     if (!resourceManager) {
303         BGTASK_LOGE("create resourceManager failed");
304         return nullptr;
305     }
306     for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
307         std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
308         if (moduleResPath.empty()) {
309             continue;
310         }
311         if (!resourceManager->AddResource(moduleResPath.c_str())) {
312             BGTASK_LOGW("GetBundleResMgr AddResource failed");
313         }
314     }
315     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
316 #ifdef SUPPORT_GRAPHICS
317     UErrorCode status = U_ZERO_ERROR;
318     icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
319     resConfig->SetLocaleInfo(locale);
320 #endif // SUPPORT_GRAPHICS
321     resourceManager->UpdateResConfig(*resConfig);
322     return resourceManager;
323 }
324 
GetNotificationPrompt()325 bool BgContinuousTaskMgr::GetNotificationPrompt()
326 {
327     continuousTaskText_.clear();
328     AppExecFwk::BundleInfo bundleInfo;
329     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(BG_TASK_RES_BUNDLE_NAME,
330         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo)) {
331         BGTASK_LOGE("get background task res: %{public}s bundle info failed", BG_TASK_RES_BUNDLE_NAME);
332         return false;
333     }
334     auto resourceManager = GetBundleResMgr(bundleInfo);
335     if (resourceManager == nullptr) {
336         BGTASK_LOGE("Get bgtask resource hap manager failed");
337         return false;
338     }
339     std::string taskText {""};
340     for (std::string name : g_taskPromptResNames) {
341         resourceManager->GetStringByName(name.c_str(), taskText);
342         if (taskText.empty()) {
343             BGTASK_LOGE("get continuous task notification text failed!");
344             return false;
345         }
346         BGTASK_LOGI("get taskText: %{public}s", taskText.c_str());
347         continuousTaskText_.push_back(taskText);
348     }
349     return true;
350 }
351 
RegisterSysCommEventListener()352 bool BgContinuousTaskMgr::RegisterSysCommEventListener()
353 {
354     bool res = true;
355     EventFwk::MatchingSkills matchingSkills;
356     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
357     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
358     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
359     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED);
360     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED);
361     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED);
362     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED);
363     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
364     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
365     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
366     EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills);
367     systemEventListener_ = std::make_shared<SystemEventObserver>(commonEventSubscribeInfo);
368     if (systemEventListener_ != nullptr) {
369         systemEventListener_->SetEventHandler(handler_);
370         systemEventListener_->SetBgContinuousTaskMgr(shared_from_this());
371         res = systemEventListener_->Subscribe();
372     }
373     return res;
374 }
375 
GetBgTaskUid()376 int32_t BgContinuousTaskMgr::GetBgTaskUid()
377 {
378     return bgTaskUid_;
379 }
380 
SetCachedBundleInfo(int32_t uid,int32_t userId,const std::string & bundleName,const std::string & appName)381 bool BgContinuousTaskMgr::SetCachedBundleInfo(int32_t uid, int32_t userId,
382     const std::string &bundleName, const std::string &appName)
383 {
384     AppExecFwk::BundleInfo bundleInfo;
385     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
386         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
387         BGTASK_LOGE("get bundle info: %{public}s failure!", bundleName.c_str());
388         return false;
389     }
390 
391     CachedBundleInfo cachedBundleInfo = CachedBundleInfo();
392     cachedBundleInfo.appName_ = appName;
393     if (AddAbilityBgModeInfos(bundleInfo, cachedBundleInfo)) {
394         cachedBundleInfos_.emplace(uid, cachedBundleInfo);
395         return true;
396     }
397     return false;
398 }
399 
AddAbilityBgModeInfos(const AppExecFwk::BundleInfo & bundleInfo,CachedBundleInfo & cachedBundleInfo)400 bool BgContinuousTaskMgr::AddAbilityBgModeInfos(const AppExecFwk::BundleInfo &bundleInfo,
401     CachedBundleInfo &cachedBundleInfo)
402 {
403     for (auto abilityInfo : bundleInfo.abilityInfos) {
404         if (abilityInfo.backgroundModes != INVALID_BGMODE) {
405             cachedBundleInfo.abilityBgMode_.emplace(abilityInfo.name, abilityInfo.backgroundModes);
406             BGTASK_LOGI("abilityName: %{public}s, abilityNameHash: %{public}s, Background Mode: %{public}u.",
407                 abilityInfo.name.c_str(), std::to_string(std::hash<std::string>()(abilityInfo.name)).c_str(),
408                 abilityInfo.backgroundModes);
409         }
410     }
411     if (cachedBundleInfo.abilityBgMode_.empty()) {
412         return false;
413     }
414     return true;
415 }
416 
CheckBgmodeType(uint32_t configuredBgMode,uint32_t requestedBgModeId,bool isNewApi,int32_t uid)417 ErrCode BgContinuousTaskMgr::CheckBgmodeType(uint32_t configuredBgMode, uint32_t requestedBgModeId,
418     bool isNewApi, int32_t uid)
419 {
420     if (!isNewApi) {
421         if (configuredBgMode == INVALID_BGMODE) {
422             BGTASK_LOGE("ability without background mode config");
423             return ERR_BGMODE_NULL_OR_TYPE_ERR;
424         } else {
425             return ERR_OK;
426         }
427     } else {
428         uint32_t recordedBgMode = BG_MODE_INDEX_HEAD << (requestedBgModeId - 1);
429         if ((recordedBgMode == SYSTEM_APP_BGMODE_WIFI_INTERACTION || recordedBgMode == SYSTEM_APP_BGMODE_VOIP)
430             && !BundleManagerHelper::GetInstance()->IsSystemApp(uid)) {
431             BGTASK_LOGE("voip and wifiInteraction background mode only support for system app");
432             return ERR_BGTASK_WIFI_VOIP_VERIFY_ERR;
433         }
434         if (recordedBgMode == PC_BGMODE_TASK_KEEPING
435             && deviceType_ != DEVICE_TYPE_PC) {
436             BGTASK_LOGE("task keeping background mode only support for pc device");
437             return ERR_BGTASK_KEEPING_TASK_VERIFY_ERR;
438         }
439         if (requestedBgModeId == INVALID_BGMODE || (configuredBgMode &
440             (BG_MODE_INDEX_HEAD << (requestedBgModeId - 1))) == 0) {
441             BGTASK_LOGE("requested background mode is not declared in config file!");
442             return ERR_BGTASK_INVALID_BGMODE;
443         }
444     }
445     return ERR_OK;
446 }
447 
GetBackgroundModeInfo(int32_t uid,const std::string & abilityName)448 uint32_t BgContinuousTaskMgr::GetBackgroundModeInfo(int32_t uid, const std::string &abilityName)
449 {
450     if (cachedBundleInfos_.find(uid) != cachedBundleInfos_.end()) {
451         auto cachedBundleInfo = cachedBundleInfos_.at(uid);
452         if (cachedBundleInfo.abilityBgMode_.find(abilityName) !=
453             cachedBundleInfo.abilityBgMode_.end()) {
454             return cachedBundleInfo.abilityBgMode_.at(abilityName);
455         }
456     }
457     return INVALID_BGMODE;
458 }
459 
CheckTaskParam(const sptr<ContinuousTaskParam> & taskParam)460 bool CheckTaskParam(const sptr<ContinuousTaskParam> &taskParam)
461 {
462     if (!taskParam) {
463         BGTASK_LOGE("continuous task params is null!");
464         return false;
465     }
466 
467     if (taskParam->isNewApi_) {
468         if (taskParam->wantAgent_ == nullptr || taskParam->abilityName_.empty()) {
469             BGTASK_LOGE("continuous task params invalid!");
470             return false;
471         }
472     } else {
473         if (taskParam->abilityName_.empty()) {
474             BGTASK_LOGE("continuous task params invalid!");
475             return false;
476         }
477     }
478     return true;
479 }
480 
StartBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)481 ErrCode BgContinuousTaskMgr::StartBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
482 {
483     if (!isSysReady_.load()) {
484         BGTASK_LOGW("manager is not ready");
485         return ERR_BGTASK_SYS_NOT_READY;
486     }
487 
488     if (!CheckTaskParam(taskParam)) {
489         return ERR_BGTASK_CHECK_TASK_PARAM;
490     }
491 
492     ErrCode result = ERR_OK;
493 
494     int32_t callingUid = IPCSkeleton::GetCallingUid();
495     pid_t callingPid = IPCSkeleton::GetCallingPid();
496     std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(callingUid);
497     int32_t userId = -1;
498 #ifdef HAS_OS_ACCOUNT_PART
499     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId);
500 #else // HAS_OS_ACCOUNT_PART
501     GetOsAccountIdFromUid(callingUid, userId);
502 #endif // HAS_OS_ACCOUNT_PART
503 
504     if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
505         BGTASK_LOGE("background mode permission is not passed");
506         return ERR_BGTASK_PERMISSION_DENIED;
507     }
508 
509     std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>();
510     continuousTaskRecord->bundleName_ = bundleName;
511     continuousTaskRecord->abilityName_ = taskParam->abilityName_;
512     continuousTaskRecord->wantAgent_ = taskParam->wantAgent_;
513     continuousTaskRecord->userId_ = userId;
514     continuousTaskRecord->uid_ = callingUid;
515     continuousTaskRecord->pid_ = callingPid;
516     continuousTaskRecord->bgModeId_ = taskParam->bgModeId_;
517     continuousTaskRecord->isNewApi_ = taskParam->isNewApi_;
518     continuousTaskRecord->appName_ = taskParam->appName_;
519 
520     if (taskParam->wantAgent_ != nullptr && taskParam->wantAgent_->GetPendingWant() != nullptr) {
521         auto target = taskParam->wantAgent_->GetPendingWant()->GetTarget();
522         auto want = taskParam->wantAgent_->GetPendingWant()->GetWant(target);
523         if (want != nullptr) {
524             std::shared_ptr<WantAgentInfo> info = std::make_shared<WantAgentInfo>();
525             info->bundleName_ = want->GetOperation().GetBundleName();
526             info->abilityName_ = want->GetOperation().GetAbilityName();
527             continuousTaskRecord->wantAgentInfo_ = info;
528         }
529     }
530 
531     StartTrace(HITRACE_TAG_OHOS, "BgContinuousTaskMgr::StartBackgroundRunningInner");
532     handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
533         result = this->StartBackgroundRunningInner(continuousTaskRecord);
534         }, AppExecFwk::EventQueue::Priority::HIGH);
535     FinishTrace(HITRACE_TAG_OHOS);
536 
537     return result;
538 }
539 
StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)540 ErrCode BgContinuousTaskMgr::StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
541 {
542     std::string taskInfoMapKey = std::to_string(continuousTaskRecord->uid_) + SEPARATOR
543         + continuousTaskRecord->abilityName_;
544     if (continuousTaskInfosMap_.find(taskInfoMapKey) != continuousTaskInfosMap_.end()) {
545         BGTASK_LOGW("continuous task is already exist: %{public}s", taskInfoMapKey.c_str());
546         return ERR_BGTASK_OBJECT_EXISTS;
547     }
548 
549     if (cachedBundleInfos_.find(continuousTaskRecord->uid_) == cachedBundleInfos_.end()) {
550         std::string mainAbilityLabel = GetMainAbilityLabel(continuousTaskRecord->bundleName_,
551             continuousTaskRecord->userId_);
552         SetCachedBundleInfo(continuousTaskRecord->uid_, continuousTaskRecord->userId_,
553             continuousTaskRecord->bundleName_, mainAbilityLabel);
554     }
555 
556     uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_,
557         continuousTaskRecord->abilityName_);
558     ErrCode ret = CheckBgmodeType(configuredBgMode, continuousTaskRecord->bgModeId_, continuousTaskRecord->isNewApi_,
559         continuousTaskRecord->uid_);
560     if (ret != ERR_OK) {
561         BGTASK_LOGE("background mode invalid!");
562         return ret;
563     }
564     ret = SendContinuousTaskNotification(continuousTaskRecord);
565     if (ret != ERR_OK) {
566         BGTASK_LOGE("publish error");
567         return ret;
568     }
569     continuousTaskInfosMap_.emplace(taskInfoMapKey, continuousTaskRecord);
570     OnContinuousTaskChanged(continuousTaskRecord, ContinuousTaskEventTriggerType::TASK_START);
571     ret = RefreshTaskRecord();
572     if (ret != ERR_OK) {
573         return ret;
574     }
575     return ERR_OK;
576 }
577 
GetBgModeNameIndex(uint32_t bgModeId,bool isNewApi)578 uint32_t GetBgModeNameIndex(uint32_t bgModeId, bool isNewApi)
579 {
580     if (!isNewApi) {
581         return BGMODE_NUMS - 1;
582     } else {
583         return bgModeId - 1;
584     }
585 }
586 
SendContinuousTaskNotification(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)587 ErrCode BgContinuousTaskMgr::SendContinuousTaskNotification(
588     std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
589 {
590     std::string notificationText {""};
591     uint32_t index = GetBgModeNameIndex(continuousTaskRecord->GetBgModeId(), continuousTaskRecord->isNewApi_);
592     if (index < BGMODE_NUMS) {
593         notificationText = continuousTaskText_.at(index);
594     }
595     std::string appName {""};
596     if (cachedBundleInfos_.find(continuousTaskRecord->uid_) != cachedBundleInfos_.end()) {
597         appName = cachedBundleInfos_.at(continuousTaskRecord->uid_).appName_;
598     }
599     if (appName.empty() || notificationText.empty()) {
600         BGTASK_LOGE("get notification prompt info failed");
601         return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
602     }
603 
604     return NotificationTools::GetInstance()->PublishNotification(continuousTaskRecord,
605         appName, notificationText, bgTaskUid_);
606 }
607 
StopBackgroundRunning(const std::string & abilityName)608 ErrCode BgContinuousTaskMgr::StopBackgroundRunning(const std::string &abilityName)
609 {
610     if (!isSysReady_.load()) {
611         BGTASK_LOGW("manager is not ready");
612         return ERR_BGTASK_SYS_NOT_READY;
613     }
614     if (abilityName.empty()) {
615         BGTASK_LOGE("abilityName is empty!");
616         return ERR_BGTASK_INVALID_PARAM;
617     }
618     int32_t callingUid = IPCSkeleton::GetCallingUid();
619 
620     ErrCode result = ERR_OK;
621 
622     StartTrace(HITRACE_TAG_OHOS, "BgContinuousTaskMgr::StopBackgroundRunningInner");
623     handler_->PostSyncTask([this, callingUid, abilityName, &result]() {
624         result = this->StopBackgroundRunningInner(callingUid, abilityName);
625         }, AppExecFwk::EventQueue::Priority::HIGH);
626     FinishTrace(HITRACE_TAG_OHOS);
627 
628     return result;
629 }
630 
StopBackgroundRunningInner(int32_t uid,const std::string & abilityName)631 ErrCode BgContinuousTaskMgr::StopBackgroundRunningInner(int32_t uid, const std::string &abilityName)
632 {
633     std::string mapKey = std::to_string(uid) + SEPARATOR + abilityName;
634 
635     auto iter = continuousTaskInfosMap_.find(mapKey);
636     if (iter == continuousTaskInfosMap_.end()) {
637         BGTASK_LOGW("%{public}s continuous task not exists", mapKey.c_str());
638         return ERR_BGTASK_OBJECT_NOT_EXIST;
639     }
640     ErrCode result = NotificationTools::GetInstance()->CancelNotification(
641         iter->second->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
642     RemoveContinuousTaskRecord(mapKey);
643     return result;
644 }
645 
StopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType)646 void BgContinuousTaskMgr::StopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType)
647 {
648     BGTASK_LOGD("StopContinuousTask begin uid: %{public}d, pid: %{public}d, taskType: %{public}d",
649         uid, pid, taskType);
650     if (!isSysReady_.load()) {
651         BGTASK_LOGW("manager is not ready");
652         return;
653     }
654     auto task = [this, uid, pid, taskType]() { this->HandleStopContinuousTask(uid, pid, taskType); };
655     handler_->PostTask(task);
656 }
657 
HandleStopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType)658 void BgContinuousTaskMgr::HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType)
659 {
660     // uid == -1 means target type continuoust task required condition is not met, so cancel all this kind of tasks;
661     if (uid == UNSET_UID) {
662         RemoveSpecifiedBgTask(taskType);
663         return;
664     }
665     auto iter = continuousTaskInfosMap_.begin();
666     int32_t uidNum = 0;
667     bool uidExist = false;
668     while (iter != continuousTaskInfosMap_.end()) {
669         int32_t recordUid = iter->second->GetUid();
670         uint32_t bgmodeId = iter->second->GetBgModeId();
671         if (recordUid != uid) {
672             iter++;
673             continue;
674         }
675         uidNum++;
676         uidExist = true;
677         if (bgmodeId == taskType) {
678             OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
679             NotificationTools::GetInstance()->CancelNotification(
680                 iter->second->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
681             iter = continuousTaskInfosMap_.erase(iter);
682             RefreshTaskRecord();
683             uidNum--;
684         } else {
685             iter++;
686         }
687     }
688     if (uidExist && uidNum == 0) {
689         HandleAppContinuousTaskStop(uid);
690     }
691 }
692 
RemoveSpecifiedBgTask(uint32_t taskType)693 void BgContinuousTaskMgr::RemoveSpecifiedBgTask(uint32_t taskType)
694 {
695     std::map<int32_t, int32_t> appTaskNum;
696     auto iter = continuousTaskInfosMap_.begin();
697     while (iter != continuousTaskInfosMap_.end()) {
698         int32_t uid = iter->second->GetUid();
699         if (appTaskNum.find(uid) != appTaskNum.end()) {
700             appTaskNum[uid]++;
701         } else {
702             appTaskNum[uid] = 1;
703         }
704         if (iter->second->GetBgModeId() == taskType) {
705             OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
706             NotificationTools::GetInstance()->CancelNotification(
707                 iter->second->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
708             iter = continuousTaskInfosMap_.erase(iter);
709             RefreshTaskRecord();
710             appTaskNum[uid]--;
711         } else {
712             iter++;
713         }
714     }
715     for (auto var : appTaskNum) {
716         if (var.second == 0) {
717             HandleAppContinuousTaskStop(var.first);
718         }
719     }
720 }
721 
AddSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)722 ErrCode BgContinuousTaskMgr::AddSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
723 {
724     if (subscriber == nullptr) {
725         BGTASK_LOGE("subscriber is null.");
726         return ERR_BGTASK_INVALID_PARAM;
727     }
728 
729     handler_->PostTask([=]() {
730         AddSubscriberInner(subscriber);
731     });
732     return ERR_OK;
733 }
734 
AddSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)735 ErrCode BgContinuousTaskMgr::AddSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
736 {
737     auto remoteObj = subscriber->AsObject();
738     auto findSuscriber = [&remoteObj](const auto& target) {
739         return remoteObj == target->AsObject();
740     };
741 
742     auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSuscriber);
743     if (subscriberIter != bgTaskSubscribers_.end()) {
744         BGTASK_LOGW("target subscriber already exist");
745         return ERR_BGTASK_OBJECT_EXISTS;
746     }
747 
748     bgTaskSubscribers_.emplace_back(subscriber);
749 
750     if (subscriber->AsObject() == nullptr) {
751         return ERR_BGTASK_INVALID_PARAM;
752     }
753     if (subscriberRecipients_.find(subscriber->AsObject()) != subscriberRecipients_.end()) {
754         return ERR_BGTASK_OBJECT_EXISTS;
755     }
756     sptr<RemoteDeathRecipient> deathRecipient = new (std::nothrow) RemoteDeathRecipient(
757         [this](const wptr<IRemoteObject> &remote) { this->OnRemoteSubscriberDied(remote); });
758     if (!deathRecipient) {
759         BGTASK_LOGE("create death recipient failed");
760         return ERR_BGTASK_INVALID_PARAM;
761     }
762     subscriber->AsObject()->AddDeathRecipient(deathRecipient);
763     subscriberRecipients_.emplace(subscriber->AsObject(), deathRecipient);
764     subscriber->OnConnected();
765     BGTASK_LOGD("Add continuous task subscriber succeed");
766     return ERR_OK;
767 }
768 
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)769 ErrCode BgContinuousTaskMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
770 {
771     if (subscriber == nullptr) {
772         BGTASK_LOGE("subscriber is null.");
773         return ERR_BGTASK_INVALID_PARAM;
774     }
775 
776     handler_->PostTask([=]() {
777         RemoveSubscriberInner(subscriber);
778     });
779     return ERR_OK;
780 }
781 
RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)782 ErrCode BgContinuousTaskMgr::RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
783 {
784     auto remote = subscriber->AsObject();
785     if (remote == nullptr) {
786         BGTASK_LOGE("Subscriber' object is null.");
787         return ERR_BGTASK_INVALID_PARAM;
788     }
789     auto findSubscriber = [&remote](const auto &targetSubscriber) {
790         return remote == targetSubscriber->AsObject();
791     };
792 
793     auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSubscriber);
794     if (subscriberIter == bgTaskSubscribers_.end()) {
795         BGTASK_LOGE("subscriber to remove is not exists.");
796         return ERR_BGTASK_INVALID_PARAM;
797     }
798 
799     auto iter = subscriberRecipients_.find(remote);
800     if (iter != subscriberRecipients_.end()) {
801         iter->first->RemoveDeathRecipient(iter->second);
802         subscriberRecipients_.erase(iter);
803     }
804     bgTaskSubscribers_.erase(subscriberIter);
805     BGTASK_LOGD("Remove continuous task subscriber succeed");
806     return ERR_OK;
807 }
808 
GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)809 ErrCode BgContinuousTaskMgr::GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
810 {
811     if (!isSysReady_.load()) {
812         BGTASK_LOGW("manager is not ready");
813         return ERR_BGTASK_SYS_NOT_READY;
814     }
815 
816     ErrCode result = ERR_OK;
817 
818     handler_->PostSyncTask([this, &list, &result]() {
819         result = this->GetContinuousTaskAppsInner(list);
820         }, AppExecFwk::EventQueue::Priority::HIGH);
821 
822     return result;
823 }
824 
GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)825 ErrCode BgContinuousTaskMgr::GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
826 {
827     if (continuousTaskInfosMap_.empty()) {
828         return ERR_OK;
829     }
830 
831     for (auto record : continuousTaskInfosMap_) {
832         auto appInfo = std::make_shared<ContinuousTaskCallbackInfo>(record.second->bgModeId_, record.second->uid_,
833             record.second->pid_, record.second->abilityName_);
834         list.push_back(appInfo);
835     }
836     return ERR_OK;
837 }
838 
ShellDump(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)839 ErrCode BgContinuousTaskMgr::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo)
840 {
841     if (!isSysReady_.load()) {
842         BGTASK_LOGW("manager is not ready");
843         return ERR_BGTASK_SYS_NOT_READY;
844     }
845     ErrCode result = ERR_OK;
846     handler_->PostSyncTask([&]() {
847         result = ShellDumpInner(dumpOption, dumpInfo);
848     });
849 
850     return result;
851 }
852 
ShellDumpInner(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)853 ErrCode BgContinuousTaskMgr::ShellDumpInner(const std::vector<std::string> &dumpOption,
854     std::vector<std::string> &dumpInfo)
855 {
856     if (dumpOption[1] == DUMP_PARAM_LIST_ALL) {
857         DumpAllTaskInfo(dumpInfo);
858     } else if (dumpOption[1] == DUMP_PARAM_CANCEL_ALL) {
859         DumpCancelTask(dumpOption, true);
860     } else if (dumpOption[1] == DUMP_PARAM_CANCEL) {
861         DumpCancelTask(dumpOption, false);
862     } else {
863         BGTASK_LOGW("invalid dump param");
864     }
865     return ERR_OK;
866 }
867 
DumpAllTaskInfo(std::vector<std::string> & dumpInfo)868 void BgContinuousTaskMgr::DumpAllTaskInfo(std::vector<std::string> &dumpInfo)
869 {
870     std::stringstream stream;
871     if (continuousTaskInfosMap_.empty()) {
872         dumpInfo.emplace_back("No running continuous task\n");
873         return;
874     }
875     std::unordered_map<std::string, std::shared_ptr<ContinuousTaskRecord>>::iterator iter;
876     uint32_t index = 1;
877     for (iter = continuousTaskInfosMap_.begin(); iter != continuousTaskInfosMap_.end(); ++iter) {
878         stream.str("");
879         stream.clear();
880         stream << "No." << index;
881         stream << "\tcontinuousTaskKey: " << iter->first << "\n";
882         stream << "\tcontinuousTaskValue:" << "\n";
883         stream << "\t\tbundleName: " << iter->second->GetBundleName() << "\n";
884         stream << "\t\tabilityName: " << iter->second->GetAbilityName() << "\n";
885         stream << "\t\tisFromNewApi: " << (iter->second->IsNewApi() ? "true" : "false") << "\n";
886         stream << "\t\tbackgroundMode: " << g_continuousTaskModeName[GetBgModeNameIndex(
887             iter->second->GetBgModeId(), iter->second->IsNewApi())] << "\n";
888         stream << "\t\tuid: " << iter->second->GetUid() << "\n";
889         stream << "\t\tuserId: " << iter->second->GetUserId() << "\n";
890         stream << "\t\tpid: " << iter->second->GetPid() << "\n";
891         stream << "\t\tnotificationLabel: " << iter->second->GetNotificationLabel() << "\n";
892         if (iter->second->wantAgentInfo_ != nullptr) {
893             stream << "\t\twantAgentBundleName: " << iter->second->wantAgentInfo_->bundleName_ << "\n";
894             stream << "\t\twantAgentAbilityName: " << iter->second->wantAgentInfo_->abilityName_ << "\n";
895         } else {
896             stream << "\t\twantAgentBundleName: " << "NULL" << "\n";
897             stream << "\t\twantAgentAbilityName: " << "NULL" << "\n";
898         }
899         stream << "\n";
900         dumpInfo.emplace_back(stream.str());
901         index++;
902     }
903 }
904 
DumpCancelTask(const std::vector<std::string> & dumpOption,bool cleanAll)905 void BgContinuousTaskMgr::DumpCancelTask(const std::vector<std::string> &dumpOption, bool cleanAll)
906 {
907     if (cleanAll) {
908         std::set<int32_t> uids;
909         for (auto item : continuousTaskInfosMap_) {
910             NotificationTools::GetInstance()->CancelNotification(item.second->GetNotificationLabel(),
911                 DEFAULT_NOTIFICATION_ID);
912             OnContinuousTaskChanged(item.second, ContinuousTaskEventTriggerType::TASK_CANCEL);
913             uids.insert(item.second->uid_);
914         }
915         continuousTaskInfosMap_.clear();
916         RefreshTaskRecord();
917         for (int32_t uid : uids) {
918             HandleAppContinuousTaskStop(uid);
919         }
920     } else {
921         if (dumpOption.size() < MAX_DUMP_PARAM_NUMS) {
922             BGTASK_LOGW("invalid dump param");
923             return;
924         }
925         std::string taskKey = dumpOption[2];
926         auto iter = continuousTaskInfosMap_.find(taskKey);
927         if (iter == continuousTaskInfosMap_.end()) {
928             return;
929         }
930         NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
931             DEFAULT_NOTIFICATION_ID);
932         RemoveContinuousTaskRecord(taskKey);
933     }
934 }
935 
RemoveContinuousTaskRecord(const std::string & mapKey)936 bool BgContinuousTaskMgr::RemoveContinuousTaskRecord(const std::string &mapKey)
937 {
938     BGTASK_LOGD("task info: %{public}s", mapKey.c_str());
939     if (continuousTaskInfosMap_.find(mapKey) == continuousTaskInfosMap_.end()) {
940         BGTASK_LOGW("remove TaskInfo failure, no matched task: %{public}s", mapKey.c_str());
941         return false;
942     }
943     auto record = continuousTaskInfosMap_.at(mapKey);
944     OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
945     continuousTaskInfosMap_.erase(mapKey);
946     HandleAppContinuousTaskStop(record->uid_);
947     RefreshTaskRecord();
948     return true;
949 }
950 
StopContinuousTaskByUser(const std::string & mapKey)951 bool BgContinuousTaskMgr::StopContinuousTaskByUser(const std::string &mapKey)
952 {
953     if (!isSysReady_.load()) {
954         BGTASK_LOGW("manager is not ready");
955         return false;
956     }
957     bool result = true;
958     handler_->PostSyncTask([this, mapKey, &result]() {
959         result = RemoveContinuousTaskRecord(mapKey);
960     });
961     return result;
962 }
963 
OnRemoteSubscriberDied(const wptr<IRemoteObject> & object)964 void BgContinuousTaskMgr::OnRemoteSubscriberDied(const wptr<IRemoteObject> &object)
965 {
966     if (!isSysReady_.load()) {
967         BGTASK_LOGW("manager is not ready");
968         return;
969     }
970     if (object == nullptr) {
971         BGTASK_LOGE("remote object is null.");
972         return;
973     }
974 
975     handler_->PostSyncTask([this, &object]() { this->OnRemoteSubscriberDiedInner(object); });
976 }
977 
OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> & object)978 void BgContinuousTaskMgr::OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> &object)
979 {
980     sptr<IRemoteObject> objectProxy = object.promote();
981     if (!objectProxy) {
982         BGTASK_LOGE("get remote object failed");
983         return;
984     }
985     auto iter = bgTaskSubscribers_.begin();
986     while (iter != bgTaskSubscribers_.end()) {
987         if ((*iter)->AsObject() == objectProxy) {
988             iter = bgTaskSubscribers_.erase(iter);
989         } else {
990             iter++;
991         }
992     }
993     subscriberRecipients_.erase(objectProxy);
994 }
995 
OnAbilityStateChanged(int32_t uid,const std::string & abilityName)996 void BgContinuousTaskMgr::OnAbilityStateChanged(int32_t uid, const std::string &abilityName)
997 {
998     if (!isSysReady_.load()) {
999         BGTASK_LOGW("manager is not ready");
1000         return;
1001     }
1002     auto iter = continuousTaskInfosMap_.begin();
1003     while (iter != continuousTaskInfosMap_.end()) {
1004         if (iter->second->uid_ == uid && iter->second->abilityName_ == abilityName) {
1005             auto record = iter->second;
1006             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1007             NotificationTools::GetInstance()->CancelNotification(
1008                 record->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
1009             iter = continuousTaskInfosMap_.erase(iter);
1010             HandleAppContinuousTaskStop(record->uid_);
1011             RefreshTaskRecord();
1012         } else {
1013             iter++;
1014         }
1015     }
1016 }
1017 
OnProcessDied(int32_t uid,int32_t pid)1018 void BgContinuousTaskMgr::OnProcessDied(int32_t uid, int32_t pid)
1019 {
1020     if (!isSysReady_.load()) {
1021         BGTASK_LOGW("manager is not ready");
1022         return;
1023     }
1024 
1025     auto iter = continuousTaskInfosMap_.begin();
1026     while (iter != continuousTaskInfosMap_.end()) {
1027         if (iter->second->GetPid() == pid) {
1028             auto record = iter->second;
1029             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1030             NotificationTools::GetInstance()->CancelNotification(
1031                 record->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
1032             iter = continuousTaskInfosMap_.erase(iter);
1033             HandleAppContinuousTaskStop(record->uid_);
1034             RefreshTaskRecord();
1035         } else {
1036             iter++;
1037         }
1038     }
1039 }
1040 
OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,ContinuousTaskEventTriggerType changeEventType)1041 void BgContinuousTaskMgr::OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,
1042     ContinuousTaskEventTriggerType changeEventType)
1043 {
1044     if (continuousTaskInfo == nullptr) {
1045         BGTASK_LOGW("ContinuousTaskRecord is null");
1046         return;
1047     }
1048 
1049     if (bgTaskSubscribers_.empty()) {
1050         BGTASK_LOGI("Background Task Subscriber List is empty");
1051         return;
1052     }
1053 
1054     std::shared_ptr<ContinuousTaskCallbackInfo> continuousTaskCallbackInfo
1055         = std::make_shared<ContinuousTaskCallbackInfo>(continuousTaskInfo->GetBgModeId(),
1056         continuousTaskInfo->GetUid(), continuousTaskInfo->GetPid(), continuousTaskInfo->GetAbilityName());
1057 
1058     switch (changeEventType) {
1059         case ContinuousTaskEventTriggerType::TASK_START:
1060             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1061                 BGTASK_LOGD("continuous task start callback trigger");
1062                 (*iter)->OnContinuousTaskStart(continuousTaskCallbackInfo);
1063             }
1064             break;
1065         case ContinuousTaskEventTriggerType::TASK_CANCEL:
1066             for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1067                 BGTASK_LOGD("continuous task stop callback trigger");
1068                 (*iter)->OnContinuousTaskStop(continuousTaskCallbackInfo);
1069             }
1070             break;
1071     }
1072 }
1073 
OnBundleInfoChanged(const std::string & action,const std::string & bundleName,int32_t uid)1074 void BgContinuousTaskMgr::OnBundleInfoChanged(const std::string &action, const std::string &bundleName, int32_t uid)
1075 {
1076     if (!isSysReady_.load()) {
1077         BGTASK_LOGW("manager is not ready");
1078         return;
1079     }
1080     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED
1081         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED
1082         || action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED
1083         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED
1084         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED
1085         || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED) {
1086         cachedBundleInfos_.erase(uid);
1087     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) {
1088         cachedBundleInfos_.erase(uid);
1089         auto iter = continuousTaskInfosMap_.begin();
1090         while (iter != continuousTaskInfosMap_.end()) {
1091             if (iter->second->GetUid() == uid) {
1092                 auto record = iter->second;
1093                 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1094                 NotificationTools::GetInstance()->CancelNotification(
1095                     record->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
1096                 iter = continuousTaskInfosMap_.erase(iter);
1097                 HandleAppContinuousTaskStop(uid);
1098                 RefreshTaskRecord();
1099             } else {
1100                 iter++;
1101             }
1102         }
1103     } else {
1104         BGTASK_LOGW("get unregister common event!");
1105         return;
1106     }
1107 }
1108 
OnAccountsStateChanged(int32_t id)1109 void BgContinuousTaskMgr::OnAccountsStateChanged(int32_t id)
1110 {
1111     std::vector<int32_t> activatedOsAccountIds;
1112 #ifdef HAS_OS_ACCOUNT_PART
1113     if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds) != ERR_OK) {
1114         BGTASK_LOGE("query activated account failed");
1115         return;
1116     }
1117 #else // HAS_OS_ACCOUNT_PART
1118     activatedOsAccountIds.push_back(DEFAULT_OS_ACCOUNT_ID);
1119     BGTASK_LOGI("there is no account part, use default id.");
1120 #endif // HAS_OS_ACCOUNT_PART
1121     auto iter = continuousTaskInfosMap_.begin();
1122     while (iter != continuousTaskInfosMap_.end()) {
1123         auto idIter = find(activatedOsAccountIds.begin(), activatedOsAccountIds.end(), iter->second->GetUserId());
1124         if (idIter == activatedOsAccountIds.end()) {
1125             auto record = iter->second;
1126             OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1127             NotificationTools::GetInstance()->CancelNotification(
1128                 record->GetNotificationLabel(), DEFAULT_NOTIFICATION_ID);
1129             iter = continuousTaskInfosMap_.erase(iter);
1130             HandleAppContinuousTaskStop(record->uid_);
1131             RefreshTaskRecord();
1132         } else {
1133             iter++;
1134         }
1135     }
1136 }
1137 
HandleAppContinuousTaskStop(int32_t uid)1138 void BgContinuousTaskMgr::HandleAppContinuousTaskStop(int32_t uid)
1139 {
1140     auto findUid = [uid](const auto &target) {
1141         return uid == target.second->GetUid();
1142     };
1143     auto findUidIter = find_if(continuousTaskInfosMap_.begin(), continuousTaskInfosMap_.end(), findUid);
1144     if (findUidIter != continuousTaskInfosMap_.end()) {
1145         return;
1146     }
1147     BGTASK_LOGI("All continuous task has stopped of uid: %{public}d, so notify related subsystem", uid);
1148     for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); iter++) {
1149         (*iter)->OnAppContinuousTaskStop(uid);
1150     }
1151 }
1152 
RefreshTaskRecord()1153 int32_t BgContinuousTaskMgr::RefreshTaskRecord()
1154 {
1155     int32_t ret = DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
1156     if (ret != ERR_OK) {
1157         BGTASK_LOGE("refresh data failed");
1158         return ret;
1159     }
1160     return ERR_OK;
1161 }
1162 
GetMainAbilityLabel(const std::string & bundleName,int32_t userId)1163 std::string BgContinuousTaskMgr::GetMainAbilityLabel(const std::string &bundleName, int32_t userId)
1164 {
1165     AppExecFwk::BundleInfo bundleInfo;
1166     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
1167         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
1168         BGTASK_LOGE("Get %{public}s bundle info failed", bundleName.c_str());
1169         return "";
1170     }
1171     auto resourceManager = GetBundleResMgr(bundleInfo);
1172     if (resourceManager == nullptr) {
1173         BGTASK_LOGE("Get %{public}s resource manager failed", bundleName.c_str());
1174         return "";
1175     }
1176 
1177     AAFwk::Want want;
1178     want.SetAction("action.system.home");
1179     want.AddEntity("entity.system.home");
1180     want.SetElementName("", bundleName, "", "");
1181     AppExecFwk::AbilityInfo abilityInfo;
1182     if (!BundleManagerHelper::GetInstance()->QueryAbilityInfo(want,
1183         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, abilityInfo)) {
1184         BGTASK_LOGE("Get %{public}s main ability info failed", bundleName.c_str());
1185         return "";
1186     }
1187     std::string mainAbilityLabel {""};
1188     resourceManager->GetStringById(static_cast<uint32_t>(abilityInfo.labelId), mainAbilityLabel);
1189     BGTASK_LOGI("Get main ability label: %{public}s by labelId: %{public}d", mainAbilityLabel.c_str(),
1190         abilityInfo.labelId);
1191     mainAbilityLabel = mainAbilityLabel.empty() ? abilityInfo.label : mainAbilityLabel;
1192     return mainAbilityLabel;
1193 }
1194 
OnConfigurationChanged(const AppExecFwk::Configuration & configuration)1195 void BgContinuousTaskMgr::OnConfigurationChanged(const AppExecFwk::Configuration &configuration)
1196 {
1197     BGTASK_LOGI("System language config has changed");
1198     if (!isSysReady_.load()) {
1199         BGTASK_LOGW("manager is not ready");
1200         return;
1201     }
1202     GetNotificationPrompt();
1203     cachedBundleInfos_.clear();
1204     std::map<std::string, std::pair<std::string, std::string>> newPromptInfos;
1205     auto iter = continuousTaskInfosMap_.begin();
1206     while (iter != continuousTaskInfosMap_.end()) {
1207         auto record = iter->second;
1208         std::string mainAbilityLabel = GetMainAbilityLabel(record->bundleName_, record->userId_);
1209 
1210         std::string notificationText {""};
1211         uint32_t index = GetBgModeNameIndex(record->bgModeId_, record->isNewApi_);
1212         if (index < BGMODE_NUMS) {
1213             notificationText = continuousTaskText_.at(index);
1214         }
1215         newPromptInfos.emplace(record->notificationLabel_, std::make_pair(mainAbilityLabel, notificationText));
1216         iter++;
1217     }
1218     NotificationTools::GetInstance()->RefreshContinuousNotifications(newPromptInfos, bgTaskUid_);
1219 }
1220 }  // namespace BackgroundTaskMgr
1221 }  // namespace OHOS
1222