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