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