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