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