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