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 maxNotificationId = -1;
226 int32_t maxContinuousTaskId = -1;
227
228 while (iter != continuousTaskInfosMap_.end()) {
229 bool pidIsAlive = checkPidCondition(allProcesses, iter->second->GetPid());
230 int32_t notificationId = iter->second->GetNotificationId();
231 if (notificationId > maxNotificationId) {
232 maxNotificationId = notificationId;
233 }
234 if (iter->second->continuousTaskId_ > maxContinuousTaskId) {
235 maxContinuousTaskId = iter->second->continuousTaskId_;
236 }
237
238 if (pidIsAlive) {
239 if (iter->second->GetNotificationId() == -1) {
240 BGTASK_LOGI("notification id is -1, continue");
241 iter++;
242 continue;
243 }
244 if (cachedBundleInfos_.find(iter->second->GetUid()) == cachedBundleInfos_.end()) {
245 std::string mainAbilityLabel = GetMainAbilityLabel(iter->second->GetBundleName(),
246 iter->second->GetUserId());
247 SetCachedBundleInfo(iter->second->GetUid(), iter->second->GetUserId(),
248 iter->second->GetBundleName(), mainAbilityLabel);
249 }
250 SendContinuousTaskNotification(iter->second);
251 BGTASK_LOGI("restore notification id %{public}d", iter->second->GetNotificationId());
252 iter++;
253 } else {
254 BGTASK_LOGI("process %{public}d die, not restore notification id %{public}d", iter->second->GetPid(),
255 iter->second->GetNotificationId());
256 iter = continuousTaskInfosMap_.erase(iter);
257 }
258 }
259 if (maxNotificationId != -1) {
260 BGTASK_LOGI("set maxNotificationId %{public}d", maxNotificationId);
261 NotificationTools::SetNotificationIdIndex(maxNotificationId);
262 }
263 if (maxContinuousTaskId != -1) {
264 BGTASK_LOGI("set maxContinuousTaskId %{public}d", maxContinuousTaskId);
265 continuousTaskIdIndex_ = maxContinuousTaskId;
266 }
267 }
268
checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> & allProcesses,int32_t pid)269 bool BgContinuousTaskMgr::checkPidCondition(const std::vector<AppExecFwk::RunningProcessInfo> &allProcesses,
270 int32_t pid)
271 {
272 auto findPid = [pid](const auto &target) {
273 return pid == target.pid_;
274 };
275 auto findPidIter = find_if(allProcesses.begin(), allProcesses.end(), findPid);
276 return findPidIter != allProcesses.end();
277 }
278
checkNotificationCondition(const std::set<std::string> & notificationLabels,const std::string & label)279 bool BgContinuousTaskMgr::checkNotificationCondition(const std::set<std::string> ¬ificationLabels,
280 const std::string &label)
281 {
282 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
283 auto findLabel = [label](const auto &target) {
284 return label == target;
285 };
286 auto findLabelIter = find_if(notificationLabels.begin(), notificationLabels.end(), findLabel);
287 return findLabelIter != notificationLabels.end();
288 #else
289 return true;
290 #endif
291 }
292
InitRequiredResourceInfo()293 void BgContinuousTaskMgr::InitRequiredResourceInfo()
294 {
295 if (!GetNotificationPrompt()) {
296 BGTASK_LOGW("init required resource info failed");
297 }
298 HandlePersistenceData();
299 isSysReady_.store(true);
300 DelayedSingleton<BackgroundTaskMgrService>::GetInstance()->SetReady(ServiceReadyState::CONTINUOUS_SERVICE_READY);
301 BGTASK_LOGI("SetReady CONTINUOUS_SERVICE_READY");
302 }
303
RegisterNotificationSubscriber()304 bool BgContinuousTaskMgr::RegisterNotificationSubscriber()
305 {
306 bool res = true;
307 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
308 subscriber_ = std::make_shared<TaskNotificationSubscriber>();
309 if (Notification::NotificationHelper::SubscribeNotificationSelf(*subscriber_) != ERR_OK) {
310 BGTASK_LOGE("SubscribeNotificationSelf failed!");
311 res = false;
312 }
313 #endif
314 return res;
315 }
316
RegisterAppStateObserver()317 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterAppStateObserver()
318 {
319 appStateObserver_ = new (std::nothrow) AppStateObserver(); // must be sprt
320 if (!appStateObserver_) {
321 BGTASK_LOGE("appStateObserver_ null");
322 return false;
323 }
324 auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
325 RegisterApplicationStateObserver(appStateObserver_);
326 if (res != ERR_OK) {
327 BGTASK_LOGE("RegisterApplicationStateObserver error");
328 return false;
329 }
330 appStateObserver_->SetEventHandler(handler_);
331 return true;
332 }
333
UnregisterAppStateObserver()334 void BgContinuousTaskMgr::UnregisterAppStateObserver()
335 {
336 if (!appStateObserver_) {
337 return;
338 }
339 auto res = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->
340 UnregisterApplicationStateObserver(appStateObserver_);
341 if (res != ERR_OK) {
342 BGTASK_LOGE("UnregisterApplicationStateObserver error");
343 return;
344 }
345 appStateObserver_ = nullptr;
346 BGTASK_LOGI("UnregisterApplicationStateObserver ok");
347 }
348
RegisterConfigurationObserver()349 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterConfigurationObserver()
350 {
351 auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
352 if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
353 BGTASK_LOGW("connect to app mgr service failed");
354 return false;
355 }
356 configChangeObserver_ = sptr<AppExecFwk::IConfigurationObserver>(
357 new (std::nothrow) ConfigChangeObserver(handler_, shared_from_this()));
358 if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) {
359 return false;
360 }
361 return true;
362 }
363
GetBundleResMgr(const AppExecFwk::BundleInfo & bundleInfo)364 std::shared_ptr<Global::Resource::ResourceManager> BgContinuousTaskMgr::GetBundleResMgr(
365 const AppExecFwk::BundleInfo &bundleInfo)
366 {
367 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
368 if (!resourceManager) {
369 BGTASK_LOGE("create resourceManager failed");
370 return nullptr;
371 }
372 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
373 std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
374 if (moduleResPath.empty()) {
375 continue;
376 }
377 BGTASK_LOGD("GetBundleResMgr, moduleResPath: %{private}s", moduleResPath.c_str());
378 if (!resourceManager->AddResource(moduleResPath.c_str())) {
379 BGTASK_LOGW("GetBundleResMgr AddResource failed");
380 }
381 }
382 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
383 #ifdef SUPPORT_GRAPHICS
384 UErrorCode status = U_ZERO_ERROR;
385 icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
386 resConfig->SetLocaleInfo(locale);
387 #endif // SUPPORT_GRAPHICS
388 resourceManager->UpdateResConfig(*resConfig);
389 return resourceManager;
390 }
391
GetNotificationPrompt()392 bool BgContinuousTaskMgr::GetNotificationPrompt()
393 {
394 continuousTaskText_.clear();
395 AppExecFwk::BundleInfo bundleInfo;
396 if (!BundleManagerHelper::GetInstance()->GetBundleInfo(BG_TASK_RES_BUNDLE_NAME,
397 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo)) {
398 BGTASK_LOGE("get background task res: %{public}s bundle info failed", BG_TASK_RES_BUNDLE_NAME);
399 return false;
400 }
401 auto resourceManager = GetBundleResMgr(bundleInfo);
402 if (resourceManager == nullptr) {
403 BGTASK_LOGE("Get bgtask resource hap manager failed");
404 return false;
405 }
406 std::string taskText {""};
407 for (std::string name : g_taskPromptResNames) {
408 resourceManager->GetStringByName(name.c_str(), taskText);
409 if (taskText.empty()) {
410 BGTASK_LOGE("get continuous task notification text failed!");
411 return false;
412 }
413 BGTASK_LOGI("get taskText: %{public}s", taskText.c_str());
414 continuousTaskText_.push_back(taskText);
415 }
416 return true;
417 }
418
RegisterSysCommEventListener()419 __attribute__((no_sanitize("cfi"))) bool BgContinuousTaskMgr::RegisterSysCommEventListener()
420 {
421 bool res = true;
422 EventFwk::MatchingSkills matchingSkills;
423 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
424 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
425 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
426 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED);
427 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED);
428 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED);
429 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED);
430 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
431 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
432 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
433 EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills);
434 systemEventListener_ = std::make_shared<SystemEventObserver>(commonEventSubscribeInfo);
435 if (systemEventListener_ != nullptr) {
436 systemEventListener_->SetEventHandler(handler_);
437 systemEventListener_->SetBgContinuousTaskMgr(shared_from_this());
438 res = systemEventListener_->Subscribe();
439 }
440 return res;
441 }
442
GetBgTaskUid()443 int32_t BgContinuousTaskMgr::GetBgTaskUid()
444 {
445 return bgTaskUid_;
446 }
447
SetCachedBundleInfo(int32_t uid,int32_t userId,const std::string & bundleName,const std::string & appName)448 bool BgContinuousTaskMgr::SetCachedBundleInfo(int32_t uid, int32_t userId,
449 const std::string &bundleName, const std::string &appName)
450 {
451 AppExecFwk::BundleInfo bundleInfo;
452 if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
453 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
454 BGTASK_LOGE("get bundle info: %{public}s failure!", bundleName.c_str());
455 return false;
456 }
457
458 CachedBundleInfo cachedBundleInfo = CachedBundleInfo();
459 cachedBundleInfo.appName_ = appName;
460 if (AddAbilityBgModeInfos(bundleInfo, cachedBundleInfo)) {
461 cachedBundleInfos_.emplace(uid, cachedBundleInfo);
462 return true;
463 }
464 return false;
465 }
466
AddAbilityBgModeInfos(const AppExecFwk::BundleInfo & bundleInfo,CachedBundleInfo & cachedBundleInfo)467 bool BgContinuousTaskMgr::AddAbilityBgModeInfos(const AppExecFwk::BundleInfo &bundleInfo,
468 CachedBundleInfo &cachedBundleInfo)
469 {
470 for (auto abilityInfo : bundleInfo.abilityInfos) {
471 if (abilityInfo.backgroundModes != INVALID_BGMODE) {
472 cachedBundleInfo.abilityBgMode_.emplace(abilityInfo.name, abilityInfo.backgroundModes);
473 BGTASK_LOGI("abilityName: %{public}s, abilityNameHash: %{public}s, Background Mode: %{public}u.",
474 abilityInfo.name.c_str(), std::to_string(std::hash<std::string>()(abilityInfo.name)).c_str(),
475 abilityInfo.backgroundModes);
476 }
477 }
478 if (cachedBundleInfo.abilityBgMode_.empty()) {
479 return false;
480 }
481 return true;
482 }
483
CheckBgmodeType(uint32_t configuredBgMode,uint32_t requestedBgModeId,bool isNewApi,uint64_t fullTokenId)484 ErrCode BgContinuousTaskMgr::CheckBgmodeType(uint32_t configuredBgMode, uint32_t requestedBgModeId,
485 bool isNewApi, uint64_t fullTokenId)
486 {
487 if (!isNewApi) {
488 if (configuredBgMode == INVALID_BGMODE) {
489 BGTASK_LOGE("ability without background mode config");
490 return ERR_BGMODE_NULL_OR_TYPE_ERR;
491 } else {
492 return ERR_OK;
493 }
494 } else {
495 uint32_t recordedBgMode = BG_MODE_INDEX_HEAD << (requestedBgModeId - 1);
496 if (recordedBgMode == SYSTEM_APP_BGMODE_WIFI_INTERACTION &&
497 !BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId)) {
498 BGTASK_LOGE("wifiInteraction background mode only support for system app");
499 return ERR_BGTASK_NOT_SYSTEM_APP;
500 }
501 if (recordedBgMode == PC_BGMODE_TASK_KEEPING && !SUPPORT_TASK_KEEPING) {
502 BGTASK_LOGE("task keeping is not supported, please set param "
503 "persist.sys.bgtask_support_task_keeping.");
504 return ERR_BGTASK_KEEPING_TASK_VERIFY_ERR;
505 }
506 if (requestedBgModeId == INVALID_BGMODE || (configuredBgMode &
507 (BG_MODE_INDEX_HEAD << (requestedBgModeId - 1))) == 0) {
508 BGTASK_LOGE("requested background mode is not declared in config file, configuredBgMode: %{public}d",
509 configuredBgMode);
510 return ERR_BGTASK_INVALID_BGMODE;
511 }
512 }
513 return ERR_OK;
514 }
515
GetBackgroundModeInfo(int32_t uid,const std::string & abilityName)516 uint32_t BgContinuousTaskMgr::GetBackgroundModeInfo(int32_t uid, const std::string &abilityName)
517 {
518 if (cachedBundleInfos_.find(uid) != cachedBundleInfos_.end()) {
519 auto cachedBundleInfo = cachedBundleInfos_.at(uid);
520 if (cachedBundleInfo.abilityBgMode_.find(abilityName) !=
521 cachedBundleInfo.abilityBgMode_.end()) {
522 return cachedBundleInfo.abilityBgMode_.at(abilityName);
523 }
524 }
525 return INVALID_BGMODE;
526 }
527
CheckTaskParam(const sptr<ContinuousTaskParam> & taskParam)528 bool CheckTaskParam(const sptr<ContinuousTaskParam> &taskParam)
529 {
530 if (!taskParam) {
531 BGTASK_LOGE("continuous task params is null!");
532 return false;
533 }
534
535 if (taskParam->isNewApi_) {
536 if (taskParam->wantAgent_ == nullptr || taskParam->abilityName_.empty()) {
537 BGTASK_LOGE("continuous task params invalid!");
538 return false;
539 }
540 if (taskParam->isBatchApi_ && taskParam->bgModeIds_.empty()) {
541 BGTASK_LOGE("bgModeIds_ is empty");
542 return false;
543 }
544 if (taskParam->abilityId_ < 0) {
545 BGTASK_LOGE("abilityId_ is invalid");
546 }
547 } else {
548 if (taskParam->abilityName_.empty()) {
549 BGTASK_LOGE("continuous task params invalid!");
550 return false;
551 }
552 }
553 return true;
554 }
555
CheckBgmodeTypeForInner(uint32_t requestedBgModeId)556 ErrCode BgContinuousTaskMgr::CheckBgmodeTypeForInner(uint32_t requestedBgModeId)
557 {
558 if (requestedBgModeId == INVALID_BGMODE || requestedBgModeId >= BGMODE_NUMS) {
559 BGTASK_LOGE("requested background mode is not declared in config file!");
560 return ERR_BGTASK_INVALID_BGMODE;
561 }
562 return ERR_OK;
563 }
564
RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)565 ErrCode BgContinuousTaskMgr::RequestBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
566 {
567 if (!isSysReady_.load()) {
568 BGTASK_LOGW("manager is not ready");
569 return ERR_BGTASK_SYS_NOT_READY;
570 }
571
572 if (!taskParam) {
573 BGTASK_LOGE("continuous task param is null!");
574 return ERR_BGTASK_CHECK_TASK_PARAM;
575 }
576 int32_t callingUid = IPCSkeleton::GetCallingUid();
577 // webview sdk申请长时任务,上下文在应用。callkit sa 申请长时时,上下文在sa;
578 if (callingUid != VOIP_SA_UID && callingUid != taskParam->uid_) {
579 BGTASK_LOGE("continuous task param uid %{public}d is invalid, real %{public}d", taskParam->uid_, callingUid);
580 return ERR_BGTASK_CHECK_TASK_PARAM;
581 }
582 BGTASK_LOGI("continuous task param uid %{public}d, real %{public}d", taskParam->uid_, callingUid);
583 if (taskParam->isStart_) {
584 return StartBackgroundRunningForInner(taskParam);
585 }
586 return StopBackgroundRunningForInner(taskParam);
587 }
588
StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)589 ErrCode BgContinuousTaskMgr::StartBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
590 {
591 ErrCode result = ERR_OK;
592 int32_t uid = taskParam->uid_;
593 pid_t callingPid = IPCSkeleton::GetCallingPid();
594 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
595 if (IPCSkeleton::GetCallingUid() == VOIP_SA_UID) {
596 fullTokenId = taskParam->tokenId_;
597 }
598 std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
599 std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
600 int32_t userId = -1;
601
602 #ifdef HAS_OS_ACCOUNT_PART
603 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId);
604 #else // HAS_OS_ACCOUNT_PART
605 GetOsAccountIdFromUid(uid, userId);
606 #endif // HAS_OS_ACCOUNT_PART
607
608 std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
609 abilityName, uid, callingPid, taskParam->bgModeId_);
610 continuousTaskRecord->isNewApi_ = true;
611 continuousTaskRecord->isFromWebview_ = true;
612 continuousTaskRecord->userId_ = userId;
613 continuousTaskRecord->fullTokenId_ = fullTokenId;
614
615 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
616 "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
617 handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
618 result = this->StartBackgroundRunningInner(continuousTaskRecord);
619 }, AppExecFwk::EventQueue::Priority::HIGH);
620
621 return result;
622 }
623
StartBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)624 ErrCode BgContinuousTaskMgr::StartBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
625 {
626 if (!isSysReady_.load()) {
627 return ERR_BGTASK_SYS_NOT_READY;
628 }
629
630 if (!CheckTaskParam(taskParam)) {
631 return ERR_BGTASK_CHECK_TASK_PARAM;
632 }
633 ErrCode result = ERR_OK;
634
635 int32_t callingUid = IPCSkeleton::GetCallingUid();
636 pid_t callingPid = IPCSkeleton::GetCallingPid();
637 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
638 std::string bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(callingUid);
639 int32_t userId = -1;
640 #ifdef HAS_OS_ACCOUNT_PART
641 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId);
642 #else // HAS_OS_ACCOUNT_PART
643 GetOsAccountIdFromUid(callingUid, userId);
644 #endif // HAS_OS_ACCOUNT_PART
645
646 if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
647 BGTASK_LOGE("background mode permission is not passed");
648 return ERR_BGTASK_PERMISSION_DENIED;
649 }
650
651 std::shared_ptr<ContinuousTaskRecord> continuousTaskRecord = std::make_shared<ContinuousTaskRecord>(bundleName,
652 taskParam->abilityName_, callingUid, callingPid, taskParam->bgModeId_, taskParam->isBatchApi_,
653 taskParam->bgModeIds_, taskParam->abilityId_);
654 continuousTaskRecord->wantAgent_ = taskParam->wantAgent_;
655 continuousTaskRecord->userId_ = userId;
656 continuousTaskRecord->isNewApi_ = taskParam->isNewApi_;
657 continuousTaskRecord->appName_ = taskParam->appName_;
658 continuousTaskRecord->fullTokenId_ = fullTokenId;
659 continuousTaskRecord->isSystem_ = BundleManagerHelper::GetInstance()->IsSystemApp(fullTokenId);
660
661 if (taskParam->wantAgent_ != nullptr && taskParam->wantAgent_->GetPendingWant() != nullptr) {
662 auto target = taskParam->wantAgent_->GetPendingWant()->GetTarget();
663 auto want = taskParam->wantAgent_->GetPendingWant()->GetWant(target);
664 if (want != nullptr) {
665 std::shared_ptr<WantAgentInfo> info = std::make_shared<WantAgentInfo>();
666 info->bundleName_ = want->GetOperation().GetBundleName();
667 info->abilityName_ = want->GetOperation().GetAbilityName();
668 continuousTaskRecord->wantAgentInfo_ = info;
669 }
670 }
671
672 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
673 "BackgroundTaskManager::ContinuousTask::Service::StartBackgroundRunningInner");
674 handler_->PostSyncTask([this, continuousTaskRecord, &result]() mutable {
675 result = this->StartBackgroundRunningInner(continuousTaskRecord);
676 }, AppExecFwk::EventQueue::Priority::HIGH);
677
678 taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
679 taskParam->continuousTaskId_ = continuousTaskRecord->continuousTaskId_;
680 return result;
681 }
682
UpdateBackgroundRunning(const sptr<ContinuousTaskParam> & taskParam)683 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunning(const sptr<ContinuousTaskParam> &taskParam)
684 {
685 if (!isSysReady_.load()) {
686 BGTASK_LOGW("manager is not ready");
687 return ERR_BGTASK_SYS_NOT_READY;
688 }
689 if (!BundleManagerHelper::GetInstance()->CheckPermission(BGMODE_PERMISSION)) {
690 BGTASK_LOGE("background mode permission is not passed");
691 return ERR_BGTASK_PERMISSION_DENIED;
692 }
693 ErrCode result = ERR_OK;
694 int32_t callingUid = IPCSkeleton::GetCallingUid();
695
696 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
697 "BackgroundTaskManager::ContinuousTask::Service::UpdateBackgroundRunningInner");
698 std::string taskInfoMapKey = std::to_string(callingUid) + SEPARATOR + taskParam->abilityName_ + SEPARATOR +
699 std::to_string(taskParam->abilityId_);
700 auto self = shared_from_this();
701 handler_->PostSyncTask([self, &taskInfoMapKey, &result, taskParam]() mutable {
702 if (!self) {
703 BGTASK_LOGE("self is null");
704 result = ERR_BGTASK_SERVICE_INNER_ERROR;
705 return;
706 }
707 result = self->UpdateBackgroundRunningInner(taskInfoMapKey, taskParam);
708 }, AppExecFwk::EventQueue::Priority::HIGH);
709 return result;
710 }
711
UpdateBackgroundRunningInner(const std::string & taskInfoMapKey,const sptr<ContinuousTaskParam> & taskParam)712 ErrCode BgContinuousTaskMgr::UpdateBackgroundRunningInner(const std::string &taskInfoMapKey,
713 const sptr<ContinuousTaskParam> &taskParam)
714 {
715 ErrCode ret;
716
717 auto iter = continuousTaskInfosMap_.find(taskInfoMapKey);
718 if (iter == continuousTaskInfosMap_.end()) {
719 BGTASK_LOGW("continuous task is not exist: %{public}s, use start befor update", taskInfoMapKey.c_str());
720 return ERR_BGTASK_OBJECT_NOT_EXIST;
721 }
722
723 auto continuousTaskRecord = iter->second;
724 auto oldModes = continuousTaskRecord->bgModeIds_;
725
726 BGTASK_LOGI("continuous task mode %{public}d, old modes: %{public}s, new modes %{public}s, isBatchApi %{public}d,"
727 " abilityId %{public}d", continuousTaskRecord->bgModeId_,
728 continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
729 continuousTaskRecord->ToString(taskParam->bgModeIds_).c_str(),
730 continuousTaskRecord->isBatchApi_, continuousTaskRecord->abilityId_);
731 // update continuoustask by same modes.
732 if (CommonUtils::CheckModesSame(oldModes, taskParam->bgModeIds_)) {
733 BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same modes.",
734 continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
735 return ERR_OK;
736 }
737
738 uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_, continuousTaskRecord->abilityName_);
739 for (auto it = taskParam->bgModeIds_.begin(); it != taskParam->bgModeIds_.end(); it++) {
740 ret = CheckBgmodeType(configuredBgMode, *it, true, continuousTaskRecord->fullTokenId_);
741 if (ret != ERR_OK) {
742 BGTASK_LOGE("CheckBgmodeType error, config mode: %{public}u, apply mode: %{public}u.", configuredBgMode,
743 *it);
744 return ret;
745 }
746 }
747 continuousTaskRecord->bgModeIds_ = taskParam->bgModeIds_;
748 continuousTaskRecord->isBatchApi_ = taskParam->isBatchApi_;
749
750 // old and new task hava mode: DATA_TRANSFER, not update notification
751 if (CommonUtils::CheckExistMode(oldModes, BackgroundMode::DATA_TRANSFER) &&
752 CommonUtils::CheckExistMode(continuousTaskRecord->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
753 BGTASK_LOGI("uid: %{public}d, bundleName: %{public}s, abilityId: %{public}d have same mode: DATA_TRANSFER",
754 continuousTaskRecord->uid_, continuousTaskRecord->bundleName_.c_str(), continuousTaskRecord->abilityId_);
755 } else {
756 ret = SendContinuousTaskNotification(continuousTaskRecord);
757 if (ret != ERR_OK) {
758 BGTASK_LOGE("publish error");
759 return ret;
760 }
761 }
762 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_UPDATE);
763 taskParam->notificationId_ = continuousTaskRecord->GetNotificationId();
764 taskParam->continuousTaskId_ = continuousTaskRecord->GetContinuousTaskId();
765 return RefreshTaskRecord();
766 }
767
StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)768 ErrCode BgContinuousTaskMgr::StartBackgroundRunningInner(std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
769 {
770 std::string taskInfoMapKey = std::to_string(continuousTaskRecord->uid_) + SEPARATOR
771 + continuousTaskRecord->abilityName_ + SEPARATOR + std::to_string(continuousTaskRecord->abilityId_);
772 if (continuousTaskInfosMap_.find(taskInfoMapKey) != continuousTaskInfosMap_.end()) {
773 BGTASK_LOGW("continuous task is already exist: %{public}s", taskInfoMapKey.c_str());
774 return ERR_BGTASK_OBJECT_EXISTS;
775 }
776 BGTASK_LOGI("continuous task mode: %{public}u, modes %{public}s, isBatchApi %{public}d, uid %{public}d,"
777 " abilityId %{public}d", continuousTaskRecord->bgModeId_,
778 continuousTaskRecord->ToString(continuousTaskRecord->bgModeIds_).c_str(),
779 continuousTaskRecord->isBatchApi_, continuousTaskRecord->uid_, continuousTaskRecord->abilityId_);
780 if (!continuousTaskRecord->isFromWebview_
781 && cachedBundleInfos_.find(continuousTaskRecord->uid_) == cachedBundleInfos_.end()) {
782 std::string mainAbilityLabel = GetMainAbilityLabel(continuousTaskRecord->bundleName_,
783 continuousTaskRecord->userId_);
784 SetCachedBundleInfo(continuousTaskRecord->uid_, continuousTaskRecord->userId_,
785 continuousTaskRecord->bundleName_, mainAbilityLabel);
786 }
787
788 ErrCode ret;
789 if (continuousTaskRecord->isFromWebview_) {
790 ret = CheckBgmodeTypeForInner(continuousTaskRecord->bgModeId_);
791 } else {
792 uint32_t configuredBgMode = GetBackgroundModeInfo(continuousTaskRecord->uid_,
793 continuousTaskRecord->abilityName_);
794 for (auto it = continuousTaskRecord->bgModeIds_.begin(); it != continuousTaskRecord->bgModeIds_.end(); it++) {
795 ret = CheckBgmodeType(configuredBgMode, *it, continuousTaskRecord->isNewApi_,
796 continuousTaskRecord->fullTokenId_);
797 if (ret != ERR_OK) {
798 BGTASK_LOGE("CheckBgmodeType invalid!");
799 return ret;
800 }
801 }
802 }
803
804 if (!continuousTaskRecord->isFromWebview_) {
805 ret = SendContinuousTaskNotification(continuousTaskRecord);
806 if (ret != ERR_OK) {
807 BGTASK_LOGE("publish error");
808 return ret;
809 }
810 }
811 continuousTaskRecord->continuousTaskId_ = ++continuousTaskIdIndex_;
812 continuousTaskInfosMap_.emplace(taskInfoMapKey, continuousTaskRecord);
813 OnContinuousTaskChanged(continuousTaskRecord, ContinuousTaskEventTriggerType::TASK_START);
814 return RefreshTaskRecord();
815 }
816
GetBgModeNameIndex(uint32_t bgModeId,bool isNewApi)817 uint32_t GetBgModeNameIndex(uint32_t bgModeId, bool isNewApi)
818 {
819 if (!isNewApi) {
820 return BGMODE_NUMS - 1;
821 } else {
822 return bgModeId - 1;
823 }
824 }
825
SendContinuousTaskNotification(std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord)826 ErrCode BgContinuousTaskMgr::SendContinuousTaskNotification(
827 std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord)
828 {
829 if (continuousTaskText_.empty()) {
830 BGTASK_LOGE("get notification prompt info failed, continuousTaskText_ is empty");
831 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
832 }
833 std::string appName {""};
834 if (cachedBundleInfos_.find(continuousTaskRecord->uid_) != cachedBundleInfos_.end()) {
835 appName = cachedBundleInfos_.at(continuousTaskRecord->uid_).appName_;
836 }
837 if (appName.empty()) {
838 BGTASK_LOGE("appName is empty");
839 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
840 }
841
842 std::string notificationText {""};
843 for (auto mode : continuousTaskRecord->bgModeIds_) {
844 if (mode == BackgroundMode::AUDIO_PLAYBACK || ((mode == BackgroundMode::VOIP ||
845 mode == BackgroundMode::AUDIO_RECORDING) && continuousTaskRecord->IsSystem())) {
846 continue;
847 }
848 BGTASK_LOGD("mode %{public}d", mode);
849 uint32_t index = GetBgModeNameIndex(mode, continuousTaskRecord->isNewApi_);
850 if (index < continuousTaskText_.size()) {
851 notificationText += continuousTaskText_.at(index);
852 notificationText += "\n";
853 } else {
854 BGTASK_LOGI("index is invalid");
855 return ERR_BGTASK_NOTIFICATION_VERIFY_FAILED;
856 }
857 }
858 if (notificationText.empty()) {
859 if (continuousTaskRecord->GetNotificationId() != -1) {
860 NotificationTools::GetInstance()->CancelNotification(
861 continuousTaskRecord->GetNotificationLabel(), continuousTaskRecord->GetNotificationId());
862 continuousTaskRecord->notificationId_ = -1;
863 }
864 return ERR_OK;
865 }
866 BGTASK_LOGD("notificationText %{public}s", notificationText.c_str());
867 return NotificationTools::GetInstance()->PublishNotification(continuousTaskRecord,
868 appName, notificationText, bgTaskUid_);
869 }
870
StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> & taskParam)871 ErrCode BgContinuousTaskMgr::StopBackgroundRunningForInner(const sptr<ContinuousTaskParamForInner> &taskParam)
872 {
873 ErrCode result = ERR_OK;
874 int32_t uid = taskParam->uid_;
875 int32_t abilityId = taskParam->abilityId_;
876 std::string abilityName = "Webview" + std::to_string(taskParam->bgModeId_);
877
878 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
879 "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
880 handler_->PostSyncTask([this, uid, abilityName, abilityId, &result]() {
881 result = this->StopBackgroundRunningInner(uid, abilityName, abilityId);
882 }, AppExecFwk::EventQueue::Priority::HIGH);
883
884 return result;
885 }
886
StopBackgroundRunning(const std::string & abilityName,int32_t abilityId)887 ErrCode BgContinuousTaskMgr::StopBackgroundRunning(const std::string &abilityName, int32_t abilityId)
888 {
889 if (!isSysReady_.load()) {
890 BGTASK_LOGW("manager is not ready");
891 return ERR_BGTASK_SYS_NOT_READY;
892 }
893 if (abilityName.empty()) {
894 BGTASK_LOGE("abilityName is empty!");
895 return ERR_BGTASK_INVALID_PARAM;
896 }
897 if (abilityId < 0) {
898 BGTASK_LOGE("abilityId is Invalid!");
899 }
900 int32_t callingUid = IPCSkeleton::GetCallingUid();
901
902 ErrCode result = ERR_OK;
903
904 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
905 "BackgroundTaskManager::ContinuousTask::Service::StopBackgroundRunningInner");
906 handler_->PostSyncTask([this, callingUid, abilityName, abilityId, &result]() {
907 result = this->StopBackgroundRunningInner(callingUid, abilityName, abilityId);
908 }, AppExecFwk::EventQueue::Priority::HIGH);
909
910 return result;
911 }
912
StopBackgroundRunningInner(int32_t uid,const std::string & abilityName,int32_t abilityId)913 ErrCode BgContinuousTaskMgr::StopBackgroundRunningInner(int32_t uid, const std::string &abilityName,
914 int32_t abilityId)
915 {
916 std::string mapKey = std::to_string(uid) + SEPARATOR + abilityName + SEPARATOR + std::to_string(abilityId);
917
918 auto iter = continuousTaskInfosMap_.find(mapKey);
919 if (iter == continuousTaskInfosMap_.end()) {
920 BGTASK_LOGW("%{public}s continuous task not exists", mapKey.c_str());
921 return ERR_BGTASK_OBJECT_NOT_EXIST;
922 }
923 BGTASK_LOGI("%{public}s stop continuous task", mapKey.c_str());
924 ErrCode result = ERR_OK;
925 if (iter->second->GetNotificationId() != -1) {
926 result = NotificationTools::GetInstance()->CancelNotification(
927 iter->second->GetNotificationLabel(), iter->second->GetNotificationId());
928 }
929
930 RemoveContinuousTaskRecord(mapKey);
931 return result;
932 }
933
StopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)934 void BgContinuousTaskMgr::StopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
935 {
936 if (!isSysReady_.load()) {
937 BGTASK_LOGW("manager is not ready");
938 return;
939 }
940 auto self = shared_from_this();
941 auto task = [self, uid, pid, taskType, key]() {
942 if (self) {
943 self->HandleStopContinuousTask(uid, pid, taskType, key);
944 }
945 };
946 handler_->PostTask(task);
947 }
948
HandleStopContinuousTask(int32_t uid,int32_t pid,uint32_t taskType,const std::string & key)949 void BgContinuousTaskMgr::HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key)
950 {
951 BGTASK_LOGI("StopContinuousTask taskType: %{public}d, key %{public}s", taskType, key.c_str());
952 if (taskType == BackgroundMode::DATA_TRANSFER) {
953 RemoveContinuousTaskRecordByUidAndMode(uid, taskType);
954 return;
955 }
956 if (taskType == ALL_MODES) {
957 RemoveContinuousTaskRecordByUid(uid);
958 return;
959 }
960 if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) {
961 BGTASK_LOGW("remove TaskInfo failure, no matched task: %{public}s", key.c_str());
962 return;
963 }
964 NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(),
965 continuousTaskInfosMap_[key]->GetNotificationId());
966 SetReason(key, FREEZE_CANCEL);
967 RemoveContinuousTaskRecord(key);
968 }
969
RemoveContinuousTaskRecordByUid(int32_t uid)970 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUid(int32_t uid)
971 {
972 auto iter = continuousTaskInfosMap_.begin();
973 while (iter != continuousTaskInfosMap_.end()) {
974 if (iter->second->GetUid() != uid) {
975 ++iter;
976 continue;
977 }
978 BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
979 iter->second->reason_ = FREEZE_CANCEL;
980 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
981 NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
982 iter->second->GetNotificationId());
983 iter = continuousTaskInfosMap_.erase(iter);
984 RefreshTaskRecord();
985 }
986 HandleAppContinuousTaskStop(uid);
987 }
988
RemoveContinuousTaskRecordByUidAndMode(int32_t uid,uint32_t mode)989 void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUidAndMode(int32_t uid, uint32_t mode)
990 {
991 auto iter = continuousTaskInfosMap_.begin();
992 while (iter != continuousTaskInfosMap_.end()) {
993 if (iter->second->GetUid() != uid) {
994 ++iter;
995 continue;
996 }
997 auto findModeIter = std::find(iter->second->bgModeIds_.begin(), iter->second->bgModeIds_.end(), mode);
998 if (findModeIter == iter->second->bgModeIds_.end()) {
999 ++iter;
1000 continue;
1001 }
1002 BGTASK_LOGW("erase key %{public}s", iter->first.c_str());
1003 iter->second->reason_ = FREEZE_CANCEL;
1004 OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL);
1005 NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(),
1006 iter->second->GetNotificationId());
1007 iter = continuousTaskInfosMap_.erase(iter);
1008 RefreshTaskRecord();
1009 }
1010 HandleAppContinuousTaskStop(uid);
1011 }
1012
AddSubscriber(const std::shared_ptr<SubscriberInfo> subscriberInfo)1013 ErrCode BgContinuousTaskMgr::AddSubscriber(const std::shared_ptr<SubscriberInfo> subscriberInfo)
1014 {
1015 if (subscriberInfo == nullptr || subscriberInfo->subscriber_ == nullptr ||
1016 subscriberInfo->subscriber_->AsObject() == nullptr) {
1017 BGTASK_LOGE("subscriber is null.");
1018 return ERR_BGTASK_INVALID_PARAM;
1019 }
1020
1021 handler_->PostSyncTask([=]() {
1022 AddSubscriberInner(subscriberInfo);
1023 });
1024 return ERR_OK;
1025 }
1026
AddSubscriberInner(const std::shared_ptr<SubscriberInfo> subscriberInfo)1027 ErrCode BgContinuousTaskMgr::AddSubscriberInner(const std::shared_ptr<SubscriberInfo> subscriberInfo)
1028 {
1029 BGTASK_LOGD("BgContinuousTaskMgr enter");
1030 auto remoteObj = subscriberInfo->subscriber_->AsObject();
1031 auto findSuscriber = [&remoteObj](const auto& target) {
1032 return remoteObj == target->subscriber_->AsObject();
1033 };
1034
1035 auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSuscriber);
1036 if (subscriberIter != bgTaskSubscribers_.end()) {
1037 BGTASK_LOGW("target subscriber already exist");
1038 return ERR_BGTASK_OBJECT_EXISTS;
1039 }
1040 bgTaskSubscribers_.emplace_back(subscriberInfo);
1041
1042 if (!susriberDeathRecipient_) {
1043 susriberDeathRecipient_ = new (std::nothrow) RemoteDeathRecipient(
1044 [this](const wptr<IRemoteObject> &remote) { this->OnRemoteSubscriberDied(remote); });
1045 }
1046 if (susriberDeathRecipient_) {
1047 remoteObj->AddDeathRecipient(susriberDeathRecipient_);
1048 }
1049 BGTASK_LOGI("continuous subscribers size %{public}d", static_cast<int32_t>(bgTaskSubscribers_.size()));
1050 return ERR_OK;
1051 }
1052
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)1053 ErrCode BgContinuousTaskMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> &subscriber)
1054 {
1055 if (subscriber == nullptr) {
1056 BGTASK_LOGE("subscriber is null.");
1057 return ERR_BGTASK_INVALID_PARAM;
1058 }
1059
1060 handler_->PostSyncTask([=]() {
1061 RemoveSubscriberInner(subscriber);
1062 });
1063 return ERR_OK;
1064 }
1065
RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> & subscriber)1066 ErrCode BgContinuousTaskMgr::RemoveSubscriberInner(const sptr<IBackgroundTaskSubscriber> &subscriber)
1067 {
1068 auto remote = subscriber->AsObject();
1069 if (remote == nullptr) {
1070 BGTASK_LOGE("Subscriber' object is null.");
1071 return ERR_BGTASK_INVALID_PARAM;
1072 }
1073 auto findSubscriber = [&remote](const auto &info) {
1074 return remote == info->subscriber_->AsObject();
1075 };
1076
1077 auto subscriberIter = find_if(bgTaskSubscribers_.begin(), bgTaskSubscribers_.end(), findSubscriber);
1078 if (subscriberIter == bgTaskSubscribers_.end()) {
1079 BGTASK_LOGE("subscriber to remove is not exists.");
1080 return ERR_BGTASK_INVALID_PARAM;
1081 }
1082 if (susriberDeathRecipient_) {
1083 remote->RemoveDeathRecipient(susriberDeathRecipient_);
1084 }
1085 bgTaskSubscribers_.erase(subscriberIter);
1086 BGTASK_LOGI("Remove continuous task subscriber succeed");
1087 return ERR_OK;
1088 }
1089
GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)1090 ErrCode BgContinuousTaskMgr::GetContinuousTaskApps(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
1091 {
1092 if (!isSysReady_.load()) {
1093 BGTASK_LOGW("manager is not ready");
1094 return ERR_BGTASK_SYS_NOT_READY;
1095 }
1096
1097 ErrCode result = ERR_OK;
1098
1099 handler_->PostSyncTask([this, &list, &result]() {
1100 result = this->GetContinuousTaskAppsInner(list);
1101 }, AppExecFwk::EventQueue::Priority::HIGH);
1102
1103 return result;
1104 }
1105
GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> & list)1106 ErrCode BgContinuousTaskMgr::GetContinuousTaskAppsInner(std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> &list)
1107 {
1108 if (continuousTaskInfosMap_.empty()) {
1109 return ERR_OK;
1110 }
1111
1112 for (auto record : continuousTaskInfosMap_) {
1113 auto appInfo = std::make_shared<ContinuousTaskCallbackInfo>(record.second->bgModeId_, record.second->uid_,
1114 record.second->pid_, record.second->abilityName_, record.second->isFromWebview_, record.second->isBatchApi_,
1115 record.second->bgModeIds_, record.second->abilityId_, record.second->fullTokenId_);
1116 list.push_back(appInfo);
1117 }
1118 return ERR_OK;
1119 }
1120
ShellDump(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1121 ErrCode BgContinuousTaskMgr::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo)
1122 {
1123 if (!isSysReady_.load()) {
1124 BGTASK_LOGW("manager is not ready");
1125 return ERR_BGTASK_SYS_NOT_READY;
1126 }
1127 ErrCode result = ERR_OK;
1128 handler_->PostSyncTask([&]() {
1129 result = ShellDumpInner(dumpOption, dumpInfo);
1130 });
1131
1132 return result;
1133 }
1134
ShellDumpInner(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)1135 ErrCode BgContinuousTaskMgr::ShellDumpInner(const std::vector<std::string> &dumpOption,
1136 std::vector<std::string> &dumpInfo)
1137 {
1138 if (dumpOption[1] == DUMP_PARAM_LIST_ALL) {
1139 DumpAllTaskInfo(dumpInfo);
1140 } else if (dumpOption[1] == DUMP_PARAM_CANCEL_ALL) {
1141 DumpCancelTask(dumpOption, true);
1142 } else if (dumpOption[1] == DUMP_PARAM_CANCEL) {
1143 DumpCancelTask(dumpOption, false);
1144 } else {
1145 BGTASK_LOGW("invalid dump param");
1146 }
1147 return ERR_OK;
1148 }
1149
DumpAllTaskInfo(std::vector<std::string> & dumpInfo)1150 void BgContinuousTaskMgr::DumpAllTaskInfo(std::vector<std::string> &dumpInfo)
1151 {
1152 std::stringstream stream;
1153 if (continuousTaskInfosMap_.empty()) {
1154 dumpInfo.emplace_back("No running continuous task\n");
1155 return;
1156 }
1157 std::unordered_map<std::string, std::shared_ptr<ContinuousTaskRecord>>::iterator iter;
1158 uint32_t index = 1;
1159 for (iter = continuousTaskInfosMap_.begin(); iter != continuousTaskInfosMap_.end(); ++iter) {
1160 stream.str("");
1161 stream.clear();
1162 stream << "No." << index;
1163 stream << "\tcontinuousTaskKey: " << iter->first << "\n";
1164 stream << "\tcontinuousTaskValue:" << "\n";
1165 stream << "\t\tbundleName: " << iter->second->GetBundleName() << "\n";
1166 stream << "\t\tabilityName: " << iter->second->GetAbilityName() << "\n";
1167 stream << "\t\tisFromWebview: " << (iter->second->IsFromWebview() ? "true" : "false") << "\n";
1168 stream << "\t\tisFromNewApi: " << (iter->second->IsNewApi() ? "true" : "false") << "\n";
1169 stream << "\t\tbackgroundMode: " << g_continuousTaskModeName[GetBgModeNameIndex(
1170 iter->second->GetBgModeId(), iter->second->IsNewApi())] << "\n";
1171 stream << "\t\tisBatchApi: " << (iter->second->isBatchApi_ ? "true" : "false") << "\n";
1172 stream << "\t\tbackgroundModes: " << iter->second->ToString(iter->second->bgModeIds_) << "\n";
1173 stream << "\t\tuid: " << iter->second->GetUid() << "\n";
1174 stream << "\t\tuserId: " << iter->second->GetUserId() << "\n";
1175 stream << "\t\tpid: " << iter->second->GetPid() << "\n";
1176 stream << "\t\tnotificationLabel: " << iter->second->GetNotificationLabel() << "\n";
1177 stream << "\t\tnotificationId: " << iter->second->GetNotificationId() << "\n";
1178 stream << "\t\tcontinuousTaskId: " << iter->second->continuousTaskId_ << "\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 handler_->PostSyncTask([this, &object]() { this->OnRemoteSubscriberDiedInner(object); });
1274 }
1275
OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> & object)1276 void BgContinuousTaskMgr::OnRemoteSubscriberDiedInner(const wptr<IRemoteObject> &object)
1277 {
1278 sptr<IRemoteObject> objectProxy = object.promote();
1279 if (!objectProxy) {
1280 BGTASK_LOGE("get remote object failed");
1281 return;
1282 }
1283 auto iter = bgTaskSubscribers_.begin();
1284 while (iter != bgTaskSubscribers_.end()) {
1285 if ((*iter)->subscriber_->AsObject() == objectProxy) {
1286 BGTASK_LOGI("OnRemoteSubscriberDiedInner erase it");
1287 iter = bgTaskSubscribers_.erase(iter);
1288 } else {
1289 iter++;
1290 }
1291 }
1292 BGTASK_LOGI("continuous subscriber die, list size is %{public}d", static_cast<int>(bgTaskSubscribers_.size()));
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
CanNotifyHap(const std::shared_ptr<SubscriberInfo> subscriberInfo,const std::shared_ptr<ContinuousTaskCallbackInfo> & callbackInfo)1361 bool BgContinuousTaskMgr::CanNotifyHap(const std::shared_ptr<SubscriberInfo> subscriberInfo,
1362 const std::shared_ptr<ContinuousTaskCallbackInfo> &callbackInfo)
1363 {
1364 if (subscriberInfo->isHap_ && subscriberInfo->uid_ == callbackInfo->GetCreatorUid() &&
1365 (callbackInfo->GetCancelReason() == REMOVE_NOTIFICATION_CANCEL ||
1366 callbackInfo->GetCancelReason() == FREEZE_CANCEL)) {
1367 return true;
1368 }
1369 return false;
1370 }
1371
NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskCallbackInfo> & continuousTaskCallbackInfo)1372 void BgContinuousTaskMgr::NotifySubscribers(ContinuousTaskEventTriggerType changeEventType,
1373 const std::shared_ptr<ContinuousTaskCallbackInfo> &continuousTaskCallbackInfo)
1374 {
1375 switch (changeEventType) {
1376 case ContinuousTaskEventTriggerType::TASK_START:
1377 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1378 BGTASK_LOGD("continuous task start callback trigger");
1379 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1380 (*iter)->subscriber_->OnContinuousTaskStart(continuousTaskCallbackInfo);
1381 }
1382 }
1383 break;
1384 case ContinuousTaskEventTriggerType::TASK_UPDATE:
1385 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1386 BGTASK_LOGD("continuous task update callback trigger");
1387 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1388 (*iter)->subscriber_->OnContinuousTaskUpdate(continuousTaskCallbackInfo);
1389 }
1390 }
1391 break;
1392 case ContinuousTaskEventTriggerType::TASK_CANCEL:
1393 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) {
1394 BGTASK_LOGD("continuous task stop callback trigger");
1395 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1396 // notify all sa
1397 (*iter)->subscriber_->OnContinuousTaskStop(continuousTaskCallbackInfo);
1398 } else if (CanNotifyHap(*iter, continuousTaskCallbackInfo) && (*iter)->subscriber_) {
1399 // notify self hap
1400 BGTASK_LOGI("uid %{public}d is hap and uid is same, need notify cancel", (*iter)->uid_);
1401 (*iter)->subscriber_->OnContinuousTaskStop(continuousTaskCallbackInfo);
1402 }
1403 }
1404 break;
1405 }
1406 }
1407
ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,const std::shared_ptr<ContinuousTaskRecord> & continuousTaskInfo)1408 void BgContinuousTaskMgr::ReportHisysEvent(ContinuousTaskEventTriggerType changeEventType,
1409 const std::shared_ptr<ContinuousTaskRecord> &continuousTaskInfo)
1410 {
1411 switch (changeEventType) {
1412 case ContinuousTaskEventTriggerType::TASK_START:
1413 case ContinuousTaskEventTriggerType::TASK_UPDATE:
1414 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_APPLY",
1415 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1416 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1417 "ABILITY", continuousTaskInfo->GetAbilityName(),
1418 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1419 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId());
1420 break;
1421 case ContinuousTaskEventTriggerType::TASK_CANCEL:
1422 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, "CONTINUOUS_TASK_CANCEL",
1423 HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", continuousTaskInfo->GetUid(),
1424 "APP_PID", continuousTaskInfo->GetPid(), "APP_NAME", continuousTaskInfo->GetBundleName(),
1425 "ABILITY", continuousTaskInfo->GetAbilityName(),
1426 "BGMODE", GetModeNumByTypeIds(continuousTaskInfo->bgModeIds_),
1427 "UIABILITY_IDENTITY", continuousTaskInfo->GetAbilityId(), "STOP_REASON", continuousTaskInfo->reason_);
1428 break;
1429 }
1430 }
1431
OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,ContinuousTaskEventTriggerType changeEventType)1432 void BgContinuousTaskMgr::OnContinuousTaskChanged(const std::shared_ptr<ContinuousTaskRecord> continuousTaskInfo,
1433 ContinuousTaskEventTriggerType changeEventType)
1434 {
1435 if (continuousTaskInfo == nullptr) {
1436 BGTASK_LOGW("ContinuousTaskRecord is null");
1437 return;
1438 }
1439
1440 if (bgTaskSubscribers_.empty()) {
1441 BGTASK_LOGI("Background Task Subscriber List is empty");
1442 return;
1443 }
1444
1445 std::shared_ptr<ContinuousTaskCallbackInfo> continuousTaskCallbackInfo
1446 = std::make_shared<ContinuousTaskCallbackInfo>(continuousTaskInfo->GetBgModeId(),
1447 continuousTaskInfo->GetUid(), continuousTaskInfo->GetPid(), continuousTaskInfo->GetAbilityName(),
1448 continuousTaskInfo->IsFromWebview(), continuousTaskInfo->isBatchApi_, continuousTaskInfo->bgModeIds_,
1449 continuousTaskInfo->abilityId_, continuousTaskInfo->fullTokenId_);
1450 BGTASK_LOGD("mode %{public}d isBatch %{public}d modes size %{public}u",
1451 continuousTaskCallbackInfo->GetTypeId(), continuousTaskCallbackInfo->IsBatchApi(),
1452 static_cast<uint32_t>(continuousTaskCallbackInfo->GetTypeIds().size()));
1453 continuousTaskCallbackInfo->SetContinuousTaskId(continuousTaskInfo->continuousTaskId_);
1454 continuousTaskCallbackInfo->SetCancelReason(continuousTaskInfo->reason_);
1455 NotifySubscribers(changeEventType, continuousTaskCallbackInfo);
1456 ReportHisysEvent(changeEventType, continuousTaskInfo);
1457 }
1458
OnBundleInfoChanged(const std::string & action,const std::string & bundleName,int32_t uid)1459 void BgContinuousTaskMgr::OnBundleInfoChanged(const std::string &action, const std::string &bundleName, int32_t uid)
1460 {
1461 if (!isSysReady_.load()) {
1462 BGTASK_LOGW("manager is not ready");
1463 return;
1464 }
1465 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED
1466 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED
1467 || action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED
1468 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED
1469 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED
1470 || action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REPLACED) {
1471 cachedBundleInfos_.erase(uid);
1472 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) {
1473 cachedBundleInfos_.erase(uid);
1474 auto iter = continuousTaskInfosMap_.begin();
1475 while (iter != continuousTaskInfosMap_.end()) {
1476 if (iter->second->GetUid() == uid) {
1477 auto record = iter->second;
1478 record->reason_ = SYSTEM_CANCEL;
1479 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1480 NotificationTools::GetInstance()->CancelNotification(
1481 record->GetNotificationLabel(), record->GetNotificationId());
1482 iter = continuousTaskInfosMap_.erase(iter);
1483 HandleAppContinuousTaskStop(uid);
1484 RefreshTaskRecord();
1485 } else {
1486 iter++;
1487 }
1488 }
1489 } else {
1490 BGTASK_LOGW("get unregister common event!");
1491 return;
1492 }
1493 }
1494
OnAccountsStateChanged(int32_t id)1495 void BgContinuousTaskMgr::OnAccountsStateChanged(int32_t id)
1496 {
1497 std::vector<int32_t> activatedOsAccountIds;
1498 #ifdef HAS_OS_ACCOUNT_PART
1499 if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds) != ERR_OK) {
1500 BGTASK_LOGE("query activated account failed");
1501 return;
1502 }
1503 #else // HAS_OS_ACCOUNT_PART
1504 activatedOsAccountIds.push_back(DEFAULT_OS_ACCOUNT_ID);
1505 BGTASK_LOGI("there is no account part, use default id.");
1506 #endif // HAS_OS_ACCOUNT_PART
1507 auto iter = continuousTaskInfosMap_.begin();
1508 while (iter != continuousTaskInfosMap_.end()) {
1509 auto idIter = find(activatedOsAccountIds.begin(), activatedOsAccountIds.end(), iter->second->GetUserId());
1510 if (idIter == activatedOsAccountIds.end()) {
1511 auto record = iter->second;
1512 record->reason_ = SYSTEM_CANCEL;
1513 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1514 NotificationTools::GetInstance()->CancelNotification(
1515 record->GetNotificationLabel(), record->GetNotificationId());
1516 iter = continuousTaskInfosMap_.erase(iter);
1517 HandleAppContinuousTaskStop(record->uid_);
1518 RefreshTaskRecord();
1519 } else {
1520 iter++;
1521 }
1522 }
1523 }
1524
HandleAppContinuousTaskStop(int32_t uid)1525 void BgContinuousTaskMgr::HandleAppContinuousTaskStop(int32_t uid)
1526 {
1527 auto findUid = [uid](const auto &target) {
1528 return uid == target.second->GetUid();
1529 };
1530 auto findUidIter = find_if(continuousTaskInfosMap_.begin(), continuousTaskInfosMap_.end(), findUid);
1531 if (findUidIter != continuousTaskInfosMap_.end()) {
1532 return;
1533 }
1534 BGTASK_LOGI("All continuous task has stopped of uid: %{public}d, so notify related subsystem", uid);
1535 for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); iter++) {
1536 if (!(*iter)->isHap_ && (*iter)->subscriber_) {
1537 (*iter)->subscriber_->OnAppContinuousTaskStop(uid);
1538 }
1539 }
1540 }
1541
RefreshTaskRecord()1542 int32_t BgContinuousTaskMgr::RefreshTaskRecord()
1543 {
1544 int32_t ret = DelayedSingleton<DataStorageHelper>::GetInstance()->RefreshTaskRecord(continuousTaskInfosMap_);
1545 if (ret != ERR_OK) {
1546 BGTASK_LOGE("refresh data failed");
1547 return ret;
1548 }
1549 return ERR_OK;
1550 }
1551
GetMainAbilityLabel(const std::string & bundleName,int32_t userId)1552 std::string BgContinuousTaskMgr::GetMainAbilityLabel(const std::string &bundleName, int32_t userId)
1553 {
1554 AppExecFwk::BundleInfo bundleInfo;
1555 if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
1556 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId)) {
1557 BGTASK_LOGE("Get %{public}s bundle info failed", bundleName.c_str());
1558 return "";
1559 }
1560 auto resourceManager = GetBundleResMgr(bundleInfo);
1561 if (resourceManager == nullptr) {
1562 BGTASK_LOGE("Get %{public}s resource manager failed", bundleName.c_str());
1563 return "";
1564 }
1565
1566 AppExecFwk::ApplicationInfo applicationInfo;
1567 if (!BundleManagerHelper::GetInstance()->GetApplicationInfo(bundleName,
1568 AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, applicationInfo)) {
1569 BGTASK_LOGE("failed to get applicationInfo from AppExecFwk, bundleName is %{public}s", bundleName.c_str());
1570 return "";
1571 }
1572
1573 std::string mainAbilityLabel {""};
1574 resourceManager->GetStringById(static_cast<uint32_t>(applicationInfo.labelId), mainAbilityLabel);
1575 BGTASK_LOGI("Get main ability label: %{public}s by labelId: %{public}d", mainAbilityLabel.c_str(),
1576 applicationInfo.labelId);
1577 mainAbilityLabel = mainAbilityLabel.empty() ? applicationInfo.label : mainAbilityLabel;
1578 return mainAbilityLabel;
1579 }
1580
OnConfigurationChanged(const AppExecFwk::Configuration & configuration)1581 void BgContinuousTaskMgr::OnConfigurationChanged(const AppExecFwk::Configuration &configuration)
1582 {
1583 if (!isSysReady_.load()) {
1584 BGTASK_LOGW("manager is not ready");
1585 return;
1586 }
1587 std::string languageChange = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
1588 if (languageChange.empty()) {
1589 return;
1590 }
1591 BGTASK_LOGI("System language config has changed");
1592 GetNotificationPrompt();
1593 cachedBundleInfos_.clear();
1594 std::map<std::string, std::pair<std::string, std::string>> newPromptInfos;
1595 auto iter = continuousTaskInfosMap_.begin();
1596 while (iter != continuousTaskInfosMap_.end()) {
1597 auto record = iter->second;
1598 if (!CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::DATA_TRANSFER)) {
1599 std::string mainAbilityLabel = GetMainAbilityLabel(record->bundleName_, record->userId_);
1600
1601 std::string notificationText {""};
1602 uint32_t index = GetBgModeNameIndex(record->bgModeId_, record->isNewApi_);
1603 if (index < BGMODE_NUMS) {
1604 notificationText = continuousTaskText_.at(index);
1605 }
1606 newPromptInfos.emplace(record->notificationLabel_, std::make_pair(mainAbilityLabel, notificationText));
1607 }
1608 iter++;
1609 }
1610 NotificationTools::GetInstance()->RefreshContinuousNotifications(newPromptInfos, bgTaskUid_);
1611 }
1612
HandleVoipTaskRemove()1613 void BgContinuousTaskMgr::HandleVoipTaskRemove()
1614 {
1615 auto iter = continuousTaskInfosMap_.begin();
1616 while (iter != continuousTaskInfosMap_.end()) {
1617 auto record = iter->second;
1618 if (record->isFromWebview_ && CommonUtils::CheckExistMode(record->bgModeIds_, BackgroundMode::VOIP)) {
1619 BGTASK_LOGI("HandleVoipTaskRemove uid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
1620 " bgModeId: %{public}d, abilityId: %{public}d", record->uid_, record->bundleName_.c_str(),
1621 record->abilityName_.c_str(), BackgroundMode::VOIP, record->abilityId_);
1622 record->reason_ = SYSTEM_CANCEL;
1623 OnContinuousTaskChanged(record, ContinuousTaskEventTriggerType::TASK_CANCEL);
1624 iter = continuousTaskInfosMap_.erase(iter);
1625 HandleAppContinuousTaskStop(record->uid_);
1626 RefreshTaskRecord();
1627 } else {
1628 iter++;
1629 }
1630 }
1631 }
1632
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)1633 void BgContinuousTaskMgr::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
1634 {
1635 if (!isSysReady_.load()) {
1636 BGTASK_LOGW("manager is not ready");
1637 return;
1638 }
1639 switch (systemAbilityId) {
1640 case SA_ID_VOIP_CALL_MANAGER:
1641 {
1642 BGTASK_LOGI("remove voip system ability, systemAbilityId: %{public}d", systemAbilityId);
1643 auto task = [this]() { this->HandleVoipTaskRemove(); };
1644 handler_->PostTask(task);
1645 }
1646 break;
1647 default:
1648 break;
1649 }
1650 }
1651 } // namespace BackgroundTaskMgr
1652 } // namespace OHOS
1653