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