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