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_transient_task_mgr.h"
17
18 #include <file_ex.h>
19 #include <ipc_skeleton.h>
20 #include <sstream>
21 #include <system_ability.h>
22 #include <system_ability_definition.h>
23
24 #include "accesstoken_kit.h"
25 #include "bundle_mgr_proxy.h"
26 #include "common_event_data.h"
27 #include "common_event_manager.h"
28 #include "common_event_support.h"
29 #include "if_system_ability_manager.h"
30 #include "iservice_registry.h"
31 #include "want.h"
32
33 #include "background_task_mgr_service.h"
34 #include "bgtaskmgr_inner_errors.h"
35 #include "time_provider.h"
36 #include "transient_task_log.h"
37 #include "hitrace_meter.h"
38
39 using namespace std;
40
41 namespace OHOS {
42 namespace BackgroundTaskMgr {
43 namespace {
44 static const std::string ALL_BGTASKMGR_OPTION = "All";
45 static const std::string LOW_BATTARY_OPTION = "BATTARY_LOW";
46 static const std::string OKAY_BATTARY_OPTION = "BATTARY_OKAY";
47 static const std::string CANCEL_DUMP_OPTION = "DUMP_CANCEL";
48 static const std::string PAUSE_DUMP_OPTION = "PAUSE";
49 static const std::string START_DUMP_OPTION = "START";
50 static const int32_t DUMP_PARAM_INDEX_TWO = 2;
51
52 constexpr int32_t BG_INVALID_REMAIN_TIME = -1;
53 constexpr int32_t WATCHDOG_DELAY_TIME = 6 * MSEC_PER_SEC;
54 constexpr int32_t SERVICE_WAIT_TIME = 2000;
55
56 const std::set<std::string> SUSPEND_NATIVE_OPERATE_CALLER = {
57 "resource_schedule_service",
58 "hidumper_service",
59 };
60 }
61
62 #ifdef BGTASK_MGR_UNIT_TEST
63 #define WEAK_FUNC __attribute__((weak))
64 #else
65 #define WEAK_FUNC
66 #endif
67
BgTransientTaskMgr()68 BgTransientTaskMgr::BgTransientTaskMgr() {}
~BgTransientTaskMgr()69 BgTransientTaskMgr::~BgTransientTaskMgr() {}
70
Init(const std::shared_ptr<AppExecFwk::EventRunner> & runner)71 void BgTransientTaskMgr::Init(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
72 {
73 BGTASK_LOGI("BgTransientTaskMgr service init start");
74 if (runner == nullptr) {
75 BGTASK_LOGE("Failed to init due to create runner error");
76 return;
77 }
78 handler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
79 if (!handler_) {
80 BGTASK_LOGE("Failed to init due to create handler error");
81 }
82 callbackDeathRecipient_ = new (std::nothrow)
83 ExpiredCallbackDeathRecipient(DelayedSingleton<BackgroundTaskMgrService>::GetInstance().get());
84 susriberDeathRecipient_ = new (std::nothrow)
85 SubscriberDeathRecipient(DelayedSingleton<BackgroundTaskMgrService>::GetInstance().get());
86
87 InitNecessaryState(runner);
88 }
89
InitNecessaryState(const std::shared_ptr<AppExecFwk::EventRunner> & runner)90 void BgTransientTaskMgr::InitNecessaryState(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
91 {
92 sptr<ISystemAbilityManager> systemAbilityManager
93 = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
94 if (systemAbilityManager == nullptr
95 || systemAbilityManager->CheckSystemAbility(APP_MGR_SERVICE_ID) == nullptr
96 || systemAbilityManager->CheckSystemAbility(COMMON_EVENT_SERVICE_ID) == nullptr
97 || systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) == nullptr) {
98 isReady_.store(false);
99 BGTASK_LOGI("request system service is not ready yet!");
100 auto InitNecessaryStateFunc = [this, runner] { this->InitNecessaryState(runner); };
101 handler_->PostTask(InitNecessaryStateFunc, SERVICE_WAIT_TIME);
102 return;
103 }
104
105 deviceInfoManeger_ = make_shared<DeviceInfoManager>();
106 timerManager_ = make_shared<TimerManager>(DelayedSingleton<BackgroundTaskMgrService>::GetInstance().get(), runner);
107 decisionMaker_ = make_shared<DecisionMaker>(timerManager_, deviceInfoManeger_);
108 watchdog_ = make_shared<Watchdog>(DelayedSingleton<BackgroundTaskMgrService>::GetInstance().get(),
109 decisionMaker_, runner);
110
111 inputManager_ = make_shared<InputManager>(runner);
112 if (inputManager_ == nullptr) {
113 BGTASK_LOGE("Fail to make inputManager");
114 return;
115 }
116 inputManager_->RegisterEventHub();
117 inputManager_->RegisterEventListener(deviceInfoManeger_);
118 inputManager_->RegisterEventListener(decisionMaker_);
119 isReady_.store(true);
120 DelayedSingleton<BackgroundTaskMgrService>::GetInstance()->SetReady(ServiceReadyState::TRANSIENT_SERVICE_READY);
121 BGTASK_LOGI("SetReady TRANSIENT_SERVICE_READY");
122 }
123
GetBundleNamesForUid(int32_t uid,std::string & bundleName)124 bool BgTransientTaskMgr::GetBundleNamesForUid(int32_t uid, std::string &bundleName)
125 {
126 sptr<ISystemAbilityManager> systemMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
127 if (systemMgr == nullptr) {
128 BGTASK_LOGE("Fail to get system ability mgr");
129 return false;
130 }
131
132 sptr<IRemoteObject> remoteObject = systemMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
133 if (remoteObject == nullptr) {
134 BGTASK_LOGE("Fail to get bundle manager proxy");
135 return false;
136 }
137
138 sptr<OHOS::AppExecFwk::IBundleMgr> bundleMgrProxy = iface_cast<OHOS::AppExecFwk::IBundleMgr>(remoteObject);
139 if (bundleMgrProxy == nullptr) {
140 BGTASK_LOGE("Bundle mgr proxy is nullptr");
141 return false;
142 }
143
144 if (bundleMgrProxy->GetNameForUid(uid, bundleName) != ERR_OK) {
145 BGTASK_LOGE("Get bundle name failed");
146 return false;
147 }
148 return true;
149 }
150
IsCallingInfoLegal(int32_t uid,int32_t pid,std::string & name,const sptr<IExpiredCallback> & callback)151 ErrCode BgTransientTaskMgr::IsCallingInfoLegal(int32_t uid, int32_t pid, std::string &name,
152 const sptr<IExpiredCallback>& callback)
153 {
154 if (!VerifyCallingInfo(uid, pid)) {
155 BGTASK_LOGE("pid or uid is invalid.");
156 return ERR_BGTASK_INVALID_PID_OR_UID;
157 }
158
159 if (!GetBundleNamesForUid(uid, name)) {
160 BGTASK_LOGE("GetBundleNamesForUid fail.");
161 return ERR_BGTASK_INVALID_BUNDLE_NAME;
162 }
163
164 if (callback == nullptr) {
165 BGTASK_LOGE("callback is null.");
166 return ERR_BGTASK_INVALID_CALLBACK;
167 }
168
169 if (callback->AsObject() == nullptr) {
170 BGTASK_LOGE("remote in callback is null.");
171 return ERR_BGTASK_INVALID_CALLBACK;
172 }
173 return ERR_OK;
174 }
175
RequestSuspendDelay(const std::u16string & reason,const sptr<IExpiredCallback> & callback,std::shared_ptr<DelaySuspendInfo> & delayInfo)176 ErrCode BgTransientTaskMgr::RequestSuspendDelay(const std::u16string& reason,
177 const sptr<IExpiredCallback>& callback, std::shared_ptr<DelaySuspendInfo> &delayInfo)
178 {
179 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
180 "BackgroundTaskManager::TransientTask::Service::RequestSuspendDelay");
181
182 if (!isReady_.load()) {
183 BGTASK_LOGW("Transient task manager is not ready.");
184 return ERR_BGTASK_SYS_NOT_READY;
185 }
186 auto uid = IPCSkeleton::GetCallingUid();
187 auto pid = IPCSkeleton::GetCallingPid();
188 std::string name = "";
189 ErrCode ret = IsCallingInfoLegal(uid, pid, name, callback);
190 if (ret != ERR_OK) {
191 BGTASK_LOGI("Request suspend delay failed, calling info is illegal.");
192 return ret;
193 }
194 BGTASK_LOGD("request suspend delay pkg : %{public}s, reason : %{public}s, uid : %{public}d, pid : %{public}d",
195 name.c_str(), Str16ToStr8(reason).c_str(), uid, pid);
196
197 auto infoEx = make_shared<DelaySuspendInfoEx>(pid);
198 delayInfo = infoEx;
199 auto remote = callback->AsObject();
200 lock_guard<mutex> lock(expiredCallbackLock_);
201 auto findCallback = [&callback](const auto& callbackMap) {
202 return callback->AsObject() == callbackMap.second->AsObject();
203 };
204
205 auto callbackIter = find_if(expiredCallbackMap_.begin(), expiredCallbackMap_.end(), findCallback);
206 if (callbackIter != expiredCallbackMap_.end()) {
207 BGTASK_LOGI("%{public}s request suspend failed, callback is already exists.", name.c_str());
208 return ERR_BGTASK_CALLBACK_EXISTS;
209 }
210
211 auto keyInfo = make_shared<KeyInfo>(name, uid, pid);
212 ret = decisionMaker_->Decide(keyInfo, infoEx);
213 if (ret != ERR_OK) {
214 BGTASK_LOGI("%{public}s request suspend failed.", name.c_str());
215 return ret;
216 }
217 BGTASK_LOGI("request suspend success, pkg : %{public}s, uid : %{public}d, requestId: %{public}d,"
218 "delayTime: %{public}d", name.c_str(), uid, infoEx->GetRequestId(), infoEx->GetActualDelayTime());
219 expiredCallbackMap_[infoEx->GetRequestId()] = callback;
220 keyInfoMap_[infoEx->GetRequestId()] = keyInfo;
221 if (callbackDeathRecipient_ != nullptr) {
222 (void)remote->AddDeathRecipient(callbackDeathRecipient_);
223 }
224
225 return ERR_OK;
226 }
227
CheckProcessName()228 bool WEAK_FUNC BgTransientTaskMgr::CheckProcessName()
229 {
230 Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
231 Security::AccessToken::NativeTokenInfo callingTokenInfo;
232 Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, callingTokenInfo);
233 BGTASK_LOGD("process name: %{public}s called CheckProcessName.", callingTokenInfo.processName.c_str());
234 if (SUSPEND_NATIVE_OPERATE_CALLER.find(callingTokenInfo.processName) == SUSPEND_NATIVE_OPERATE_CALLER.end()) {
235 BGTASK_LOGE("CheckProcessName illegal access to this interface; process name: %{public}s.",
236 callingTokenInfo.processName.c_str());
237 return false;
238 }
239 return true;
240 }
241
PauseTransientTaskTimeForInner(int32_t uid)242 ErrCode BgTransientTaskMgr::PauseTransientTaskTimeForInner(int32_t uid)
243 {
244 if (!isReady_.load()) {
245 BGTASK_LOGW("Transient task manager is not ready.");
246 return ERR_BGTASK_SYS_NOT_READY;
247 }
248
249 if (!CheckProcessName()) {
250 return ERR_BGTASK_INVALID_PROCESS_NAME;
251 }
252
253 if (uid < 0) {
254 BGTASK_LOGE("PauseTransientTaskTimeForInner uid is invalid.");
255 return ERR_BGTASK_INVALID_PID_OR_UID;
256 }
257
258 std::string name = "";
259 if (!GetBundleNamesForUid(uid, name)) {
260 BGTASK_LOGE("GetBundleNamesForUid fail, uid : %{public}d.", uid);
261 return ERR_BGTASK_SERVICE_INNER_ERROR;
262 }
263
264 ErrCode ret = decisionMaker_->PauseTransientTaskTimeForInner(uid, name);
265 if (ret != ERR_OK) {
266 BGTASK_LOGE("pkgname: %{public}s, uid: %{public}d PauseTransientTaskTimeForInner fail.",
267 name.c_str(), uid);
268 return ret;
269 }
270 lock_guard<mutex> lock(transientUidLock_);
271 transientPauseUid_.insert(uid);
272 return ERR_OK;
273 }
274
StartTransientTaskTimeForInner(int32_t uid)275 ErrCode BgTransientTaskMgr::StartTransientTaskTimeForInner(int32_t uid)
276 {
277 if (!isReady_.load()) {
278 BGTASK_LOGW("Transient task manager is not ready.");
279 return ERR_BGTASK_SYS_NOT_READY;
280 }
281
282 if (!CheckProcessName()) {
283 return ERR_BGTASK_INVALID_PROCESS_NAME;
284 }
285
286 if (uid < 0) {
287 BGTASK_LOGE("StartTransientTaskTimeForInner uid is invalid.");
288 return ERR_BGTASK_INVALID_PID_OR_UID;
289 }
290
291 std::string name = "";
292 if (!GetBundleNamesForUid(uid, name)) {
293 BGTASK_LOGE("GetBundleNamesForUid fail, uid : %{public}d.", uid);
294 return ERR_BGTASK_SERVICE_INNER_ERROR;
295 }
296
297 ErrCode ret = decisionMaker_->StartTransientTaskTimeForInner(uid, name);
298 if (ret != ERR_OK) {
299 BGTASK_LOGE("pkgname: %{public}s, uid: %{public}d StartTransientTaskTimeForInner fail.",
300 name.c_str(), uid);
301 return ret;
302 }
303 lock_guard<mutex> lock(transientUidLock_);
304 transientPauseUid_.erase(uid);
305 return ERR_OK;
306 }
307
HandleTransientTaskSuscriberTask(const shared_ptr<TransientTaskAppInfo> & appInfo,const TransientTaskEventType type)308 void BgTransientTaskMgr::HandleTransientTaskSuscriberTask(const shared_ptr<TransientTaskAppInfo>& appInfo,
309 const TransientTaskEventType type)
310 {
311 if (handler_ == nullptr) {
312 BGTASK_LOGE("HandleTransientTaskSuscriberTask handler is not init.");
313 return;
314 }
315 handler_->PostTask([=]() {
316 NotifyTransientTaskSuscriber(appInfo, type);
317 });
318 }
319
NotifyTransientTaskSuscriber(const shared_ptr<TransientTaskAppInfo> & appInfo,const TransientTaskEventType type)320 void BgTransientTaskMgr::NotifyTransientTaskSuscriber(const shared_ptr<TransientTaskAppInfo>& appInfo,
321 const TransientTaskEventType type)
322 {
323 if (appInfo == nullptr) {
324 BGTASK_LOGE("NotifyTransientTaskSuscriber failed, appInfo is null.");
325 return;
326 }
327 if (subscriberList_.empty()) {
328 BGTASK_LOGI("Transient Task Subscriber List is empty");
329 return;
330 }
331 const TransientTaskAppInfo& appInfoRef = *appInfo;
332 switch (type) {
333 case TransientTaskEventType::TASK_START:
334 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
335 (*iter)->OnTransientTaskStart(appInfoRef);
336 }
337 break;
338 case TransientTaskEventType::TASK_END:
339 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
340 (*iter)->OnTransientTaskEnd(appInfoRef);
341 }
342 break;
343 case TransientTaskEventType::TASK_ERR:
344 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
345 (*iter)->OnTransientTaskErr(appInfoRef);
346 }
347 break;
348 case TransientTaskEventType::APP_TASK_START:
349 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
350 (*iter)->OnAppTransientTaskStart(appInfoRef);
351 }
352 break;
353 case TransientTaskEventType::APP_TASK_END:
354 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
355 (*iter)->OnAppTransientTaskEnd(appInfoRef);
356 }
357 break;
358 default:
359 break;
360 }
361 }
362
CancelSuspendDelay(int32_t requestId)363 ErrCode BgTransientTaskMgr::CancelSuspendDelay(int32_t requestId)
364 {
365 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
366 "BackgroundTaskManager::TransientTask::Service::CancelSuspendDelay");
367
368 if (!isReady_.load()) {
369 BGTASK_LOGE("Transient task manager is not ready.");
370 return ERR_BGTASK_SYS_NOT_READY;
371 }
372 auto uid = IPCSkeleton::GetCallingUid();
373 auto pid = IPCSkeleton::GetCallingPid();
374 if (!VerifyCallingInfo(uid, pid)) {
375 BGTASK_LOGI("cancel suspend delay failed, pid or uid is invalid.");
376 return ERR_BGTASK_INVALID_PID_OR_UID;
377 }
378
379 std::string name = "";
380 if (!GetBundleNamesForUid(uid, name)) {
381 BGTASK_LOGW("GetBundleNamesForUid fail, uid : %{public}d.", uid);
382 return ERR_BGTASK_SERVICE_INNER_ERROR;
383 }
384 BGTASK_LOGI("cancel suspend delay pkg : %{public}s, uid : %{public}d, requestId : %{public}d",
385 name.c_str(), uid, requestId);
386
387 lock_guard<mutex> lock(expiredCallbackLock_);
388 if (!VerifyRequestIdLocked(name, uid, requestId)) {
389 BGTASK_LOGI(" cancel suspend delay failed, requestId is illegal.");
390 return ERR_BGTASK_INVALID_REQUEST_ID;
391 }
392
393 return CancelSuspendDelayLocked(requestId);
394 }
395
CancelSuspendDelayLocked(int32_t requestId)396 ErrCode BgTransientTaskMgr::CancelSuspendDelayLocked(int32_t requestId)
397 {
398 watchdog_->RemoveWatchdog(requestId);
399 decisionMaker_->RemoveRequest(keyInfoMap_[requestId], requestId);
400 keyInfoMap_.erase(requestId);
401
402 auto iter = expiredCallbackMap_.find(requestId);
403 if (iter == expiredCallbackMap_.end()) {
404 BGTASK_LOGI("CancelSuspendDelayLocked Callback not found.");
405 return ERR_BGTASK_CALLBACK_NOT_EXIST;
406 }
407 auto remote = iter->second->AsObject();
408 if (remote != nullptr) {
409 remote->RemoveDeathRecipient(callbackDeathRecipient_);
410 }
411 expiredCallbackMap_.erase(iter);
412 return ERR_OK;
413 }
414
ForceCancelSuspendDelay(int32_t requestId)415 void BgTransientTaskMgr::ForceCancelSuspendDelay(int32_t requestId)
416 {
417 lock_guard<mutex> lock(expiredCallbackLock_);
418 auto keyInfoIter = keyInfoMap_.find(requestId);
419 if (keyInfoIter == keyInfoMap_.end()) {
420 BGTASK_LOGI("force cancel suspend delay failed callback not found.");
421 return;
422 }
423
424 CancelSuspendDelayLocked(requestId);
425 }
426
GetRemainingDelayTime(int32_t requestId,int32_t & delayTime)427 ErrCode BgTransientTaskMgr::GetRemainingDelayTime(int32_t requestId, int32_t &delayTime)
428 {
429 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
430 "BackgroundTaskManager::TransientTask::Service::GetRemainingDelayTime");
431
432 if (!isReady_.load()) {
433 BGTASK_LOGW("Transient task manager is not ready.");
434 return ERR_BGTASK_SYS_NOT_READY;
435 }
436 auto uid = IPCSkeleton::GetCallingUid();
437 auto pid = IPCSkeleton::GetCallingPid();
438 if (!VerifyCallingInfo(uid, pid)) {
439 BGTASK_LOGI("get remain time failed, uid or pid is invalid");
440 delayTime = BG_INVALID_REMAIN_TIME;
441 return ERR_BGTASK_INVALID_PID_OR_UID;
442 }
443
444 std::string name = "";
445 if (!GetBundleNamesForUid(uid, name)) {
446 BGTASK_LOGE("GetBundleNamesForUid fail.");
447 delayTime = BG_INVALID_REMAIN_TIME;
448 return ERR_BGTASK_SERVICE_INNER_ERROR;
449 }
450 BGTASK_LOGI("get remain time pkg : %{public}s, uid : %{public}d, requestId : %{public}d",
451 name.c_str(), uid, requestId);
452
453 lock_guard<mutex> lock(expiredCallbackLock_);
454 if (!VerifyRequestIdLocked(name, uid, requestId)) {
455 BGTASK_LOGE("get remain time failed, requestId is illegal.");
456 delayTime = BG_INVALID_REMAIN_TIME;
457 return ERR_BGTASK_INVALID_REQUEST_ID;
458 }
459
460 delayTime = decisionMaker_->GetRemainingDelayTime(keyInfoMap_[requestId], requestId);
461 return ERR_OK;
462 }
463
VerifyCallingInfo(int32_t uid,int32_t pid)464 bool BgTransientTaskMgr::VerifyCallingInfo(int32_t uid, int32_t pid)
465 {
466 return (uid >= 0) && (pid >= 0);
467 }
468
VerifyRequestIdLocked(const std::string & name,int32_t uid,int32_t requestId)469 bool BgTransientTaskMgr::VerifyRequestIdLocked(const std::string& name, int32_t uid, int32_t requestId)
470 {
471 auto keyInfoIter = keyInfoMap_.find(requestId);
472 if (keyInfoIter == keyInfoMap_.end()) {
473 return false;
474 }
475 return keyInfoIter->second->IsEqual(name, uid);
476 }
477
HandleExpiredCallbackDeath(const wptr<IRemoteObject> & remote)478 void BgTransientTaskMgr::HandleExpiredCallbackDeath(const wptr<IRemoteObject>& remote)
479 {
480 if (remote == nullptr) {
481 BGTASK_LOGE("expiredCallback death, remote in callback is null.");
482 return;
483 }
484
485 lock_guard<mutex> lock(expiredCallbackLock_);
486 auto findCallback = [&remote](const auto& callbackMap) {
487 return callbackMap.second->AsObject() == remote;
488 };
489
490 auto callbackIter = find_if(expiredCallbackMap_.begin(), expiredCallbackMap_.end(), findCallback);
491 if (callbackIter == expiredCallbackMap_.end()) {
492 BGTASK_LOGI("expiredCallback death, remote in callback not found.");
493 return;
494 }
495
496 watchdog_->RemoveWatchdog(callbackIter->first);
497 auto keyInfoIter = keyInfoMap_.find(callbackIter->first);
498 expiredCallbackMap_.erase(callbackIter);
499 if (keyInfoIter == keyInfoMap_.end()) {
500 BGTASK_LOGI("expiredCallback death, keyInfo not found.");
501 return;
502 }
503
504 BGTASK_LOGI("expiredCallback death, %{public}s, requestId : %{public}d", keyInfoIter->second->ToString().c_str(),
505 keyInfoIter->first);
506 decisionMaker_->RemoveRequest(keyInfoIter->second, keyInfoIter->first);
507 keyInfoMap_.erase(keyInfoIter);
508 }
509
HandleSubscriberDeath(const wptr<IRemoteObject> & remote)510 void BgTransientTaskMgr::HandleSubscriberDeath(const wptr<IRemoteObject>& remote)
511 {
512 if (remote == nullptr) {
513 BGTASK_LOGE("suscriber death, remote in suscriber is null.");
514 return;
515 }
516
517 handler_->PostSyncTask([&]() {
518 auto findSuscriber = [&remote](const auto& subscriberList) {
519 return remote == subscriberList->AsObject();
520 };
521 auto subscriberIter = find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
522 if (subscriberIter == subscriberList_.end()) {
523 BGTASK_LOGI("suscriber death, remote in suscriber not found.");
524 return;
525 }
526
527 subscriberList_.erase(subscriberIter);
528 BGTASK_LOGI("suscriber death, remove it.");
529 });
530 }
531
HandleRequestExpired(const int32_t requestId)532 void BgTransientTaskMgr::HandleRequestExpired(const int32_t requestId)
533 {
534 BGTASK_LOGI("request expired, id : %{public}d", requestId);
535
536 std::lock_guard<std::mutex> lock(expiredCallbackLock_);
537 auto callbackIter = expiredCallbackMap_.find(requestId);
538 if (callbackIter == expiredCallbackMap_.end()) {
539 BGTASK_LOGE("request expired, callback not found.");
540 return;
541 }
542 callbackIter->second->OnExpired();
543
544 auto keyInfoIter = keyInfoMap_.find(requestId);
545 if (keyInfoIter == keyInfoMap_.end()) {
546 BGTASK_LOGE("request expired, keyinfo not found.");
547 return;
548 }
549 watchdog_->AddWatchdog(requestId, keyInfoIter->second, WATCHDOG_DELAY_TIME);
550 }
551
SubscribeBackgroundTask(const sptr<IBackgroundTaskSubscriber> & subscriber)552 ErrCode BgTransientTaskMgr::SubscribeBackgroundTask(const sptr<IBackgroundTaskSubscriber>& subscriber)
553 {
554 if (subscriber == nullptr) {
555 BGTASK_LOGI("subscriber is null.");
556 return ERR_BGTASK_INVALID_PARAM;
557 }
558 auto remote = subscriber->AsObject();
559 if (remote == nullptr) {
560 BGTASK_LOGE("request suspend delay failed, remote in subscriber is null.");
561 return ERR_BGTASK_INVALID_PARAM;
562 }
563
564 handler_->PostSyncTask([=]() {
565 auto findSuscriber = [&remote](const auto& subscriberList) {
566 return remote == subscriberList->AsObject();
567 };
568 auto subscriberIter = find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
569 if (subscriberIter != subscriberList_.end()) {
570 BGTASK_LOGE("request subscriber is already exists.");
571 return;
572 }
573
574 if (susriberDeathRecipient_ != nullptr) {
575 remote->AddDeathRecipient(susriberDeathRecipient_);
576 }
577 subscriberList_.emplace_back(subscriber);
578 BGTASK_LOGI("subscribe transient task success.");
579 });
580 return ERR_OK;
581 }
582
UnsubscribeBackgroundTask(const sptr<IBackgroundTaskSubscriber> & subscriber)583 ErrCode BgTransientTaskMgr::UnsubscribeBackgroundTask(const sptr<IBackgroundTaskSubscriber>& subscriber)
584 {
585 if (subscriber == nullptr) {
586 BGTASK_LOGE("subscriber is null.");
587 return ERR_BGTASK_INVALID_PARAM;
588 }
589 auto remote = subscriber->AsObject();
590 if (remote == nullptr) {
591 BGTASK_LOGE("request suspend delay failed, remote in subscriber is null.");
592 return ERR_BGTASK_INVALID_PARAM;
593 }
594
595 handler_->PostSyncTask([=]() {
596 auto findSuscriber = [&remote](const auto& subscriberList) {
597 return remote == subscriberList->AsObject();
598 };
599 auto subscriberIter = find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
600 if (subscriberIter == subscriberList_.end()) {
601 BGTASK_LOGE("request subscriber is not exists.");
602 return;
603 }
604 remote->RemoveDeathRecipient(susriberDeathRecipient_);
605 subscriberList_.erase(subscriberIter);
606 BGTASK_LOGI("unsubscribe transient task success.");
607 });
608 return ERR_OK;
609 }
610
GetTransientTaskApps(std::vector<std::shared_ptr<TransientTaskAppInfo>> & list)611 ErrCode BgTransientTaskMgr::GetTransientTaskApps(std::vector<std::shared_ptr<TransientTaskAppInfo>> &list)
612 {
613 lock_guard<mutex> lock(expiredCallbackLock_);
614 if (keyInfoMap_.empty()) {
615 return ERR_OK;
616 }
617
618 for (auto record : keyInfoMap_) {
619 auto findInfo = [&record](const auto& info) {
620 return (record.second->GetPkg() == info->GetPackageName()) &&
621 (record.second->GetUid() == info->GetUid());
622 };
623 auto findInfoIter = std::find_if(list.begin(), list.end(), findInfo);
624 if (findInfoIter == list.end()) {
625 auto appInfo = make_shared<TransientTaskAppInfo>(record.second->GetPkg(),
626 record.second->GetUid());
627 list.push_back(appInfo);
628 }
629 }
630 return ERR_OK;
631 }
632
SetBgTaskConfig(const std::string & configData,int32_t sourceType)633 ErrCode BgTransientTaskMgr::SetBgTaskConfig(const std::string &configData, int32_t sourceType)
634 {
635 if (!isReady_.load()) {
636 BGTASK_LOGE("Transient task manager is not ready.");
637 return ERR_BGTASK_SYS_NOT_READY;
638 }
639 if (!CheckProcessName()) {
640 return ERR_BGTASK_INVALID_PROCESS_NAME;
641 }
642 BGTASK_LOGD("SetBgTaskConfig configData: %{public}s, sourceType: %{public}d.", configData.c_str(), sourceType);
643 bool addResult = DelayedSingleton<BgtaskConfig>::GetInstance()->AddExemptedQuatoData(configData, sourceType);
644 if (!addResult) {
645 BGTASK_LOGE("AddExemptedQuatoData fail.");
646 return ERR_PARAM_NUMBER_ERR;
647 }
648 return ERR_OK;
649 }
650
ShellDump(const std::vector<std::string> & dumpOption,std::vector<std::string> & dumpInfo)651 ErrCode BgTransientTaskMgr::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo)
652 {
653 if (!isReady_.load()) {
654 BGTASK_LOGE("Transient task manager is not ready.");
655 return ERR_BGTASK_SYS_NOT_READY;
656 }
657 bool result = false;
658 if (dumpOption[1] == ALL_BGTASKMGR_OPTION) {
659 result = DumpAllRequestId(dumpInfo);
660 } else if (dumpOption[1] == LOW_BATTARY_OPTION) {
661 deviceInfoManeger_->SetDump(true);
662 SendLowBatteryEvent(dumpInfo);
663 result = true;
664 } else if (dumpOption[1] == OKAY_BATTARY_OPTION) {
665 deviceInfoManeger_->SetDump(true);
666 SendOkayBatteryEvent(dumpInfo);
667 result = true;
668 } else if (dumpOption[1] == CANCEL_DUMP_OPTION) {
669 deviceInfoManeger_->SetDump(false);
670 result = true;
671 } else if (dumpOption[1] == PAUSE_DUMP_OPTION) {
672 DumpTaskTime(dumpOption, true, dumpInfo);
673 result = true;
674 } else if (dumpOption[1] == START_DUMP_OPTION) {
675 DumpTaskTime(dumpOption, false, dumpInfo);
676 result = true;
677 } else {
678 dumpInfo.push_back("Error transient dump command!\n");
679 }
680
681 return result ? ERR_OK : ERR_BGTASK_PERMISSION_DENIED;
682 }
683
SendLowBatteryEvent(std::vector<std::string> & dumpInfo)684 void BgTransientTaskMgr::SendLowBatteryEvent(std::vector<std::string> &dumpInfo)
685 {
686 AAFwk::Want want;
687 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_LOW);
688 EventFwk::CommonEventData data;
689 data.SetWant(want);
690 EventFwk::CommonEventPublishInfo publishInfo;
691 publishInfo.SetOrdered(true);
692
693 data.SetCode(0);
694 data.SetData("dump");
695 if (EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo)) {
696 dumpInfo.push_back("Publish COMMON_EVENT_BATTERY_LOW succeed!\n");
697 } else {
698 dumpInfo.push_back("Publish COMMON_EVENT_BATTERY_LOW failed!\n");
699 }
700 }
701
SendOkayBatteryEvent(std::vector<std::string> & dumpInfo)702 void BgTransientTaskMgr::SendOkayBatteryEvent(std::vector<std::string> &dumpInfo)
703 {
704 AAFwk::Want want;
705 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_OKAY);
706 EventFwk::CommonEventData data;
707 data.SetWant(want);
708 EventFwk::CommonEventPublishInfo publishInfo;
709 publishInfo.SetOrdered(true);
710
711 data.SetCode(0);
712 data.SetData("dump");
713 if (EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo)) {
714 dumpInfo.push_back("Publish COMMON_EVENT_BATTERY_OKAY succeed!\n");
715 } else {
716 dumpInfo.push_back("Publish COMMON_EVENT_BATTERY_OKAY failed!\n");
717 }
718 }
719
OnAppCacheStateChanged(int32_t uid,int32_t pid,const std::string & bundleName)720 void BgTransientTaskMgr::OnAppCacheStateChanged(int32_t uid, int32_t pid, const std::string &bundleName)
721 {
722 if (!isReady_.load()) {
723 BGTASK_LOGW("manager is not ready");
724 return;
725 }
726 if (!VerifyCallingInfo(uid, pid)) {
727 BGTASK_LOGE("pid or uid is invalid.");
728 return;
729 }
730 auto keyInfo = make_shared<KeyInfo>(bundleName, uid, pid);
731 vector<int32_t> requestIdList = decisionMaker_->GetRequestIdListByKey(keyInfo);
732 if (requestIdList.empty()) {
733 BGTASK_LOGE("pkgname: %{public}s, uid: %{public}d not request transient task.",
734 bundleName.c_str(), uid);
735 return;
736 }
737 for (auto &requestId : requestIdList) {
738 BGTASK_LOGI("OnAppCacheStateChanged cancel task, bundlename: %{public}s, uid: %{public}d, pid: %{public}d,"
739 " requestId: %{public}d.", bundleName.c_str(), uid, pid, requestId);
740 CancelSuspendDelayLocked(requestId);
741 }
742 }
743
DumpTaskTime(const std::vector<std::string> & dumpOption,bool pause,std::vector<std::string> & dumpInfo)744 void BgTransientTaskMgr::DumpTaskTime(const std::vector<std::string> &dumpOption, bool pause,
745 std::vector<std::string> &dumpInfo)
746 {
747 int32_t uid = std::atoi(dumpOption[DUMP_PARAM_INDEX_TWO].c_str());
748 ErrCode ret = ERR_OK;
749 if (pause) {
750 ret = PauseTransientTaskTimeForInner(uid);
751 if (ret != ERR_OK) {
752 dumpInfo.push_back("pause transient tasl fail!\n");
753 } else {
754 dumpInfo.push_back("pause transient tasl success!\n");
755 }
756 } else {
757 ret = StartTransientTaskTimeForInner(uid);
758 if (ret != ERR_OK) {
759 dumpInfo.push_back("start transient tasl fail!\n");
760 } else {
761 dumpInfo.push_back("start transient tasl success!\n");
762 }
763 }
764 }
765
DumpAllRequestId(std::vector<std::string> & dumpInfo)766 bool BgTransientTaskMgr::DumpAllRequestId(std::vector<std::string> &dumpInfo)
767 {
768 if (keyInfoMap_.empty()) {
769 dumpInfo.push_back("No Transient Task!\n");
770 return true;
771 }
772 std::stringstream stream;
773 int32_t index = 1;
774 for (auto record : keyInfoMap_) {
775 stream.clear();
776 stream.str("");
777 stream << "No." << std::to_string(index++) << "\n";
778 stream << "\tRequestId: " << record.first << "\n";
779 stream << "\tAppName: " << record.second->GetPkg() << "\n";
780 stream << "\tAppUid: " << record.second->GetUid() << "\n";
781 stream << "\tAppPid: " << record.second->GetPid() << "\n";
782 stream << "\tActualDelayTime: " << decisionMaker_->GetRemainingDelayTime(record.second, record.first) << "\n";
783 stream << "\tRemainingQuota: " << decisionMaker_->GetQuota(record.second) << "\n";
784 stream << "\n";
785 dumpInfo.push_back(stream.str());
786 }
787
788 return true;
789 }
790
ExpiredCallbackDeathRecipient(const wptr<BackgroundTaskMgrService> & service)791 ExpiredCallbackDeathRecipient::ExpiredCallbackDeathRecipient(const wptr<BackgroundTaskMgrService>& service)
792 : service_(service) {}
793
~ExpiredCallbackDeathRecipient()794 ExpiredCallbackDeathRecipient::~ExpiredCallbackDeathRecipient() {}
795
OnRemoteDied(const wptr<IRemoteObject> & remote)796 void ExpiredCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
797 {
798 auto service = service_.promote();
799 if (service == nullptr) {
800 BGTASK_LOGE("expired callback died, BackgroundTaskMgrService dead.");
801 return;
802 }
803 service->HandleExpiredCallbackDeath(remote);
804 }
805
SubscriberDeathRecipient(const wptr<BackgroundTaskMgrService> & service)806 SubscriberDeathRecipient::SubscriberDeathRecipient(const wptr<BackgroundTaskMgrService>& service)
807 : service_(service) {}
808
~SubscriberDeathRecipient()809 SubscriberDeathRecipient::~SubscriberDeathRecipient() {}
810
OnRemoteDied(const wptr<IRemoteObject> & remote)811 void SubscriberDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
812 {
813 auto service = service_.promote();
814 if (service == nullptr) {
815 BGTASK_LOGE("suscriber died, BackgroundTaskMgrService dead.");
816 return;
817 }
818 service->HandleSubscriberDeath(remote);
819 }
820
HandleSuspendManagerDie()821 void BgTransientTaskMgr::HandleSuspendManagerDie()
822 {
823 if (!transientPauseUid_.empty()) {
824 for (auto iter = transientPauseUid_.begin(); iter != transientPauseUid_.end(); iter++) {
825 int32_t uid = *iter;
826 std::string name = "";
827 if (!GetBundleNamesForUid(uid, name)) {
828 BGTASK_LOGE("GetBundleNamesForUid fail, uid : %{public}d.", uid);
829 continue;
830 }
831 ErrCode ret = decisionMaker_->StartTransientTaskTimeForInner(uid, name);
832 if (ret != ERR_OK) {
833 BGTASK_LOGE("transient task uid: %{public}d, restart fail.", uid);
834 }
835 }
836 lock_guard<mutex> lock(transientUidLock_);
837 transientPauseUid_.clear();
838 }
839 }
840
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)841 void BgTransientTaskMgr::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
842 {
843 if (!isReady_.load()) {
844 BGTASK_LOGE("Transient task manager is not ready.");
845 return;
846 }
847 switch (systemAbilityId) {
848 case SUSPEND_MANAGER_SYSTEM_ABILITY_ID:
849 {
850 BGTASK_LOGI("remove suspend manager system ability, systemAbilityId: %{public}d", systemAbilityId);
851 auto task = [this]() { this->HandleSuspendManagerDie(); };
852 handler_->PostTask(task);
853 }
854 break;
855 default:
856 break;
857 }
858 }
859
GetTransientPauseUid()860 std::set<int32_t>& BgTransientTaskMgr::GetTransientPauseUid()
861 {
862 return transientPauseUid_;
863 }
864 } // namespace BackgroundTaskMgr
865 } // namespace OHOS