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