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