• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "standby_service_impl.h"
17 
18 #include <set>
19 #include <algorithm>
20 #include <vector>
21 #include <string>
22 #include <functional>
23 #include <sstream>
24 
25 #include <dlfcn.h>
26 
27 #include "event_runner.h"
28 #include "system_ability_definition.h"
29 #include "iservice_registry.h"
30 #include "tokenid_kit.h"
31 #include "accesstoken_kit.h"
32 #include "access_token.h"
33 #include "time_service_client.h"
34 #include "common_event_support.h"
35 
36 #include "json_utils.h"
37 #include "timed_task.h"
38 #include "time_provider.h"
39 #include "istandby_service.h"
40 #include "device_standby_switch.h"
41 #include "standby_config_manager.h"
42 #include "allow_type.h"
43 #include "app_mgr_helper.h"
44 #include "ability_manager_helper.h"
45 #include "bundle_manager_helper.h"
46 #include "common_event_observer.h"
47 #include "standby_service.h"
48 
49 namespace OHOS {
50 namespace DevStandbyMgr {
51 namespace {
52 const std::string ALLOW_RECORD_FILE_PATH = "/data/service/el1/public/device_standby/allow_record";
53 const std::string STANDBY_MSG_HANDLER = "StandbyMsgHandler";
54 const std::string ON_PLUGIN_REGISTER = "OnPluginRegister";
55 #ifdef __LP64__
56 const std::string SYSTEM_SO_PATH = "/system/lib64/";
57 #else
58 const std::string SYSTEM_SO_PATH = "/system/lib/";
59 #endif
60 const std::string STANDBY_EXEMPTION_PERMISSION = "ohos.permission.DEVICE_STANDBY_EXEMPTION";
61 }
62 
63 IMPLEMENT_SINGLE_INSTANCE(StandbyServiceImpl);
64 
StandbyServiceImpl()65 StandbyServiceImpl::StandbyServiceImpl() {}
66 
~StandbyServiceImpl()67 StandbyServiceImpl::~StandbyServiceImpl() {}
68 
Init()69 bool StandbyServiceImpl::Init()
70 {
71     auto runner = AppExecFwk::EventRunner::Create(STANDBY_MSG_HANDLER);
72     if (runner == nullptr) {
73         STANDBYSERVICE_LOGE("dev standby service runner create failed");
74         return false;
75     }
76     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
77     if (!handler_) {
78         STANDBYSERVICE_LOGE("standby msg handler create failed");
79         return false;
80     }
81     if (StandbyConfigManager::GetInstance()->Init() != ERR_OK) {
82         STANDBYSERVICE_LOGE("failed to init device standby config manager");
83         return false;
84     }
85     if (RegisterPlugin(StandbyConfigManager::GetInstance()->GetPluginName()) != ERR_OK
86         && RegisterPlugin(DEFAULT_PLUGIN_NAME) != ERR_OK) {
87         STANDBYSERVICE_LOGE("register plugin failed");
88         return false;
89     }
90     STANDBYSERVICE_LOGI("register plugin secceed, dev standby service implement finish Init");
91     return true;
92 }
93 
InitReadyState()94 void StandbyServiceImpl::InitReadyState()
95 {
96     STANDBYSERVICE_LOGI("start init necessary plugin");
97     handler_->PostTask([this]() {
98         if (isServiceReady_.load()) {
99             STANDBYSERVICE_LOGW("standby service is already ready, do not need repeat");
100             return;
101         }
102         if (!standbyStateManager_->Init()) {
103             STANDBYSERVICE_LOGE("standby state manager init failed");
104             return;
105         }
106         if (!strategyManager_->Init()) {
107             STANDBYSERVICE_LOGE("strategy plugin init failed");
108             return;
109         }
110         if (!constraintManager_->Init()) {
111             STANDBYSERVICE_LOGE("constraint plugin init failed");
112             return;
113         }
114         if (!listenerManager_->Init() || listenerManager_->StartListener() != ERR_OK) {
115             STANDBYSERVICE_LOGE("listener plugin init failed");
116             return;
117         }
118 
119         RegisterTimeObserver();
120         ParsePersistentData();
121         isServiceReady_.store(true);
122 
123         StandbyService::GetInstance()->AddPluginSysAbilityListener(BACKGROUND_TASK_MANAGER_SERVICE_ID);
124         StandbyService::GetInstance()->AddPluginSysAbilityListener(WORK_SCHEDULE_SERVICE_ID);
125         }, AppExecFwk::EventQueue::Priority::HIGH);
126 }
127 
RegisterCommEventObserver()128 ErrCode StandbyServiceImpl::RegisterCommEventObserver()
129 {
130     STANDBYSERVICE_LOGI("register common event observer");
131     std::lock_guard<std::mutex> lock(eventObserverMutex_);
132     if (commonEventObserver_) {
133         return ERR_STANDBY_OBSERVER_ALREADY_EXIST;
134     }
135     commonEventObserver_ = CommonEventObserver::CreateCommonEventObserver(handler_);
136     if (!commonEventObserver_) {
137         STANDBYSERVICE_LOGE("register common event observer failed");
138         return ERR_STANDBY_OBSERVER_INIT_FAILED;
139     }
140     if (!commonEventObserver_->Subscribe()) {
141         STANDBYSERVICE_LOGE("SubscribeCommonEvent failed");
142         return ERR_STANDBY_OBSERVER_INIT_FAILED;
143     }
144     return ERR_OK;
145 }
146 
RegisterAppStateObserver()147 ErrCode StandbyServiceImpl::RegisterAppStateObserver()
148 {
149     std::lock_guard<std::mutex> lock(appStateObserverMutex_);
150     if (appStateObserver_) {
151         return ERR_STANDBY_OBSERVER_ALREADY_EXIST;
152     }
153     appStateObserver_ = new (std::nothrow) AppStateObserver(handler_);
154     if (!appStateObserver_) {
155         STANDBYSERVICE_LOGE("malloc appStateObserver failed");
156         return ERR_STANDBY_OBSERVER_INIT_FAILED;
157     }
158     if (!AppMgrHelper::GetInstance()->SubscribeObserver(appStateObserver_)) {
159         STANDBYSERVICE_LOGE("subscribe appStateObserver failed");
160         return ERR_STANDBY_OBSERVER_INIT_FAILED;
161     }
162     return ERR_OK;
163 }
164 
UnregisterAppStateObserver()165 ErrCode StandbyServiceImpl::UnregisterAppStateObserver()
166 {
167     STANDBYSERVICE_LOGI("unregister app state observer");
168     std::lock_guard<std::mutex> lock(appStateObserverMutex_);
169     if (appStateObserver_) {
170         AppMgrHelper::GetInstance()->UnsubscribeObserver(appStateObserver_);
171         appStateObserver_ = nullptr;
172     }
173     return ERR_OK;
174 }
175 
DayNightSwitchCallback()176 void StandbyServiceImpl::DayNightSwitchCallback()
177 {
178     handler_->PostTask([standbyImpl = shared_from_this()]() {
179         STANDBYSERVICE_LOGD("start day and night switch");
180         if (!standbyImpl->isServiceReady_.load()) {
181             STANDBYSERVICE_LOGW("standby service is not ready");
182             if (!TimedTask::StartDayNightSwitchTimer(standbyImpl->dayNightSwitchTimerId_)) {
183                 standbyImpl->ResetTimeObserver();
184             }
185             return;
186         }
187         auto curState = standbyImpl->standbyStateManager_->GetCurState();
188         if (curState == StandbyState::SLEEP) {
189             StandbyMessage standbyMessage {StandbyMessageType::RES_CTRL_CONDITION_CHANGED};
190             standbyMessage.want_ = AAFwk::Want {};
191             uint32_t condition = TimeProvider::GetCondition();
192             standbyMessage.want_->SetParam(RES_CTRL_CONDITION, static_cast<int32_t>(condition));
193             standbyImpl->DispatchEvent(standbyMessage);
194         }
195         if (!TimedTask::StartDayNightSwitchTimer(standbyImpl->dayNightSwitchTimerId_)) {
196             STANDBYSERVICE_LOGE("start day and night switch timer failed");
197             standbyImpl->ResetTimeObserver();
198         }
199     });
200 }
201 
RegisterTimeObserver()202 ErrCode StandbyServiceImpl::RegisterTimeObserver()
203 {
204     STANDBYSERVICE_LOGI("register time observer");
205     std::lock_guard<std::recursive_mutex> lock(timerObserverMutex_);
206     if (dayNightSwitchTimerId_ > 0) {
207         return ERR_STANDBY_OBSERVER_ALREADY_EXIST;
208     }
209     auto callBack = [standbyImpl = shared_from_this()]() {
210         standbyImpl->DayNightSwitchCallback();
211     };
212     if (!TimedTask::RegisterDayNightSwitchTimer(dayNightSwitchTimerId_, false, 0, callBack)) {
213         STANDBYSERVICE_LOGE("RegisterTimer failed");
214         return ERR_STANDBY_OBSERVER_INIT_FAILED;
215     }
216     return ERR_OK;
217 }
218 
UnregisterCommEventObserver()219 ErrCode StandbyServiceImpl::UnregisterCommEventObserver()
220 {
221     STANDBYSERVICE_LOGI("unregister common event observer");
222     std::lock_guard<std::mutex> lock(eventObserverMutex_);
223     if (commonEventObserver_) {
224         commonEventObserver_->Unsubscribe();
225         commonEventObserver_.reset();
226     }
227     return ERR_OK;
228 }
229 
UnregisterTimeObserver()230 ErrCode StandbyServiceImpl::UnregisterTimeObserver()
231 {
232     STANDBYSERVICE_LOGI("unregister time observer");
233     std::lock_guard<std::recursive_mutex> lock(timerObserverMutex_);
234     if (!MiscServices::TimeServiceClient::GetInstance()->StopTimer(dayNightSwitchTimerId_)) {
235         STANDBYSERVICE_LOGE("day and night switch observer stop failed");
236     }
237     if (!MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(dayNightSwitchTimerId_)) {
238         STANDBYSERVICE_LOGE("day and night switch observer destroy failed");
239     }
240     dayNightSwitchTimerId_ = 0;
241     return ERR_OK;
242 }
243 
ResetTimeObserver()244 ErrCode StandbyServiceImpl::ResetTimeObserver()
245 {
246     STANDBYSERVICE_LOGI("reset time observer");
247     std::lock_guard<std::recursive_mutex> lock(timerObserverMutex_);
248     if (UnregisterTimeObserver() != ERR_OK || RegisterTimeObserver() != ERR_OK) {
249         STANDBYSERVICE_LOGE("day and night switch observer reset failed");
250         return ERR_STANDBY_OBSERVER_RESET_FAILED;
251     }
252     return ERR_OK;
253 }
254 
255 
RegisterPlugin(const std::string & pluginName)256 ErrCode StandbyServiceImpl::RegisterPlugin(const std::string& pluginName)
257 {
258     STANDBYSERVICE_LOGI("start register plugin %{public}s", pluginName.c_str());
259     std::string realPluginName {""};
260     if (!JsonUtils::GetRealPath(SYSTEM_SO_PATH + pluginName, realPluginName)) {
261         STANDBYSERVICE_LOGW("failed to get valid plugin path");
262         return ERR_STANDBY_PLUGIN_NOT_EXIST;
263     }
264     if (strncmp(realPluginName.c_str(), SYSTEM_SO_PATH.c_str(), SYSTEM_SO_PATH.size()) != 0) {
265         STANDBYSERVICE_LOGW("plugin must in system directory");
266         return ERR_STANDBY_PLUGIN_NOT_EXIST;
267     }
268     registerPlugin_ = dlopen(realPluginName.c_str(), RTLD_NOW);
269     if (!registerPlugin_) {
270         dlclose(registerPlugin_);
271         STANDBYSERVICE_LOGE("failed to open plugin %{public}s", realPluginName.c_str());
272         return ERR_STANDBY_PLUGIN_NOT_EXIST;
273     }
274     void* pluginFunc = dlsym(registerPlugin_, ON_PLUGIN_REGISTER.c_str());
275     if (!pluginFunc) {
276         dlclose(registerPlugin_);
277         STANDBYSERVICE_LOGE("failed to find extern func of plugin %{public}s", realPluginName.c_str());
278         return ERR_STANDBY_PLUGIN_NOT_EXIST;
279     }
280     auto onPluginInitFunc = reinterpret_cast<bool (*)()>(pluginFunc);
281     if (!onPluginInitFunc()) {
282         dlclose(registerPlugin_);
283         return ERR_STANDBY_PLUGIN_NOT_AVAILABLE;
284     }
285     return ERR_OK;
286 }
287 
RegisterPluginInner(IConstraintManagerAdapter * constraintManager,IListenerManagerAdapter * listenerManager,IStrategyManagerAdapter * strategyManager,IStateManagerAdapter * stateManager)288 void StandbyServiceImpl::RegisterPluginInner(IConstraintManagerAdapter* constraintManager,
289     IListenerManagerAdapter* listenerManager,
290     IStrategyManagerAdapter* strategyManager,
291     IStateManagerAdapter* stateManager)
292 {
293     constraintManager_ = std::shared_ptr<IConstraintManagerAdapter>(constraintManager);
294     listenerManager_ = std::shared_ptr<IListenerManagerAdapter>(listenerManager);
295     strategyManager_ = std::shared_ptr<IStrategyManagerAdapter>(strategyManager);
296     standbyStateManager_ = std::shared_ptr<IStateManagerAdapter>(stateManager);
297 }
298 
GetHandler()299 std::shared_ptr<AppExecFwk::EventHandler>& StandbyServiceImpl::GetHandler()
300 {
301     return handler_;
302 }
303 
GetConstraintManager()304 std::shared_ptr<IConstraintManagerAdapter>& StandbyServiceImpl::GetConstraintManager()
305 {
306     return constraintManager_;
307 }
308 
GetListenerManager()309 std::shared_ptr<IListenerManagerAdapter>& StandbyServiceImpl::GetListenerManager()
310 {
311     return listenerManager_;
312 }
313 
GetStrategyManager()314 std::shared_ptr<IStrategyManagerAdapter>& StandbyServiceImpl::GetStrategyManager()
315 {
316     return strategyManager_;
317 }
318 
GetStateManager()319 std::shared_ptr<IStateManagerAdapter>& StandbyServiceImpl::GetStateManager()
320 {
321     return standbyStateManager_;
322 }
323 
UninitReadyState()324 void StandbyServiceImpl::UninitReadyState()
325 {
326     handler_->PostSyncTask([this]() {
327         if (!isServiceReady_.load()) {
328             STANDBYSERVICE_LOGW("standby service is already not ready, do not need uninit");
329             return;
330         }
331         STANDBYSERVICE_LOGE("start uninit necessary observer");
332         listenerManager_->UnInit();
333         constraintManager_->UnInit();
334         strategyManager_->UnInit();
335         standbyStateManager_->UnInit();
336         isServiceReady_.store(false);
337         }, AppExecFwk::EventQueue::Priority::HIGH);
338 }
339 
ParsePersistentData()340 bool StandbyServiceImpl::ParsePersistentData()
341 {
342     STANDBYSERVICE_LOGD("service start, parse persistent data");
343     std::unordered_map<int32_t, std::string> pidNameMap {};
344     GetPidAndProcName(pidNameMap);
345     if (pidNameMap.empty()) {
346         return false;
347     }
348     nlohmann::json root;
349     if (!JsonUtils::LoadJsonValueFromFile(root, ALLOW_RECORD_FILE_PATH)) {
350         STANDBYSERVICE_LOGE("failed to load allow record from file");
351         return false;
352     }
353 
354     std::lock_guard<std::mutex> allowRecordLock(allowRecordMutex_);
355     for (auto iter = root.begin(); iter != root.end(); ++iter) {
356         std::shared_ptr<AllowRecord> recordPtr = std::make_shared<AllowRecord>();
357         if (recordPtr->ParseFromJson(iter.value())) {
358             allowInfoMap_.emplace(iter.key(), recordPtr);
359         }
360     }
361     for (auto iter = allowInfoMap_.begin(); iter != allowInfoMap_.end();) {
362         auto pidNameIter = pidNameMap.find(iter->second->pid_);
363         if (pidNameIter == pidNameMap.end() || pidNameIter->second != iter->second->name_) {
364             allowInfoMap_.erase(iter++);
365         } else {
366             iter++;
367         }
368     }
369 
370     STANDBYSERVICE_LOGI("after reboot, allowInfoMap_ size is %{public}d", static_cast<int32_t>(allowInfoMap_.size()));
371     RecoverTimeLimitedTask();
372     DumpPersistantData();
373     return true;
374 }
375 
GetPidAndProcName(std::unordered_map<int32_t,std::string> & pidNameMap)376 void StandbyServiceImpl::GetPidAndProcName(std::unordered_map<int32_t, std::string>& pidNameMap)
377 {
378     std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos {};
379     if (!AppMgrHelper::GetInstance()->GetAllRunningProcesses(allAppProcessInfos)) {
380         STANDBYSERVICE_LOGE("connect to app manager service failed");
381         return;
382     }
383     STANDBYSERVICE_LOGD("GetAllRunningProcesses result size is %{public}d",
384         static_cast<int32_t>(allAppProcessInfos.size()));
385     for (const auto& info : allAppProcessInfos) {
386         pidNameMap.emplace(info.pid_, info.processName_);
387     }
388     std::list<SystemProcessInfo> systemProcessInfos {};
389     if (!AbilityManagerHelper::GetInstance()->GetRunningSystemProcess(systemProcessInfos)) {
390         STANDBYSERVICE_LOGE("connect to app ability service failed");
391         return;
392     }
393     STANDBYSERVICE_LOGD("GetRunningSystemProcess result size is %{public}d",
394         static_cast<int32_t>(systemProcessInfos.size()));
395     for (const auto& info : systemProcessInfos) {
396         pidNameMap.emplace(info.pid, info.processName);
397     }
398 }
399 
RecoverTimeLimitedTask()400 void StandbyServiceImpl::RecoverTimeLimitedTask()
401 {
402     STANDBYSERVICE_LOGD("start to recovery delayed task");
403     const auto &mgr = shared_from_this();
404     for (auto iter = allowInfoMap_.begin(); iter != allowInfoMap_.end(); ++iter) {
405         auto &allowTimeList = iter->second->allowTimeList_;
406         for (auto allowTimeIter = allowTimeList.begin(); allowTimeIter != allowTimeList.end(); ++allowTimeIter) {
407             auto task = [mgr, uid = iter->second->uid_, name = iter->second->name_] () {
408                 mgr->UnapplyAllowResInner(uid, name, MAX_ALLOW_TYPE_NUMBER, false);
409             };
410             int32_t timeOut = static_cast<int32_t>(allowTimeIter->endTime_ -
411                 MiscServices::TimeServiceClient::GetInstance()->GetMonotonicTimeMs());
412             handler_->PostTask(task, std::max(0, timeOut));
413         }
414     }
415 }
416 
DumpPersistantData()417 void StandbyServiceImpl::DumpPersistantData()
418 {
419     nlohmann::json root;
420     STANDBYSERVICE_LOGD("dump persistant data");
421     for (auto& [uid, allowInfo] : allowInfoMap_) {
422         root[uid] = allowInfo->ParseToJson();
423     }
424     JsonUtils::DumpJsonValueToFile(root, ALLOW_RECORD_FILE_PATH);
425 }
426 
UnInit()427 void StandbyServiceImpl::UnInit()
428 {
429     if (!registerPlugin_) {
430         dlclose(registerPlugin_);
431         registerPlugin_ = nullptr;
432     }
433     STANDBYSERVICE_LOGI("succeed to clear stawndby service implement");
434 }
435 
CheckAllowTypeInfo(uint32_t allowType)436 bool StandbyServiceImpl::CheckAllowTypeInfo(uint32_t allowType)
437 {
438     return allowType > 0 && allowType <= MAX_ALLOW_TYPE_NUMBER;
439 }
440 
RemoveAppAllowRecord(int32_t uid,const std::string & bundleName,bool resetAll)441 ErrCode StandbyServiceImpl::RemoveAppAllowRecord(int32_t uid, const std::string &bundleName, bool resetAll)
442 {
443     if (!isServiceReady_.load()) {
444         STANDBYSERVICE_LOGD("standby service is not ready");
445         return ERR_STANDBY_SYS_NOT_READY;
446     }
447     STANDBYSERVICE_LOGD("app died, uid: %{public}d, bundleName: %{public}s", uid, bundleName.c_str());
448     int allowType = resetAll ? MAX_ALLOW_TYPE_NUMBER : (MAX_ALLOW_TYPE_NUMBER ^ AllowType::TIMER ^
449         AllowType::WORK_SCHEDULER);
450     this->UnapplyAllowResInner(uid, bundleName, allowType, true);
451     return ERR_OK;
452 }
453 
CheckCallerPermission(uint32_t reasonCode)454 ErrCode StandbyServiceImpl::CheckCallerPermission(uint32_t reasonCode)
455 {
456     int32_t uid = IPCSkeleton::GetCallingUid();
457     STANDBYSERVICE_LOGI("check caller permission, uid of caller is %{public}d", uid);
458     Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
459     if (Security::AccessToken::AccessTokenKit::GetTokenType(tokenId)
460         == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
461         return IsSystemAppWithPermission(uid, tokenId, reasonCode);
462     }
463     return CheckNativePermission(tokenId);
464 }
465 
IsSystemAppWithPermission(int32_t uid,Security::AccessToken::AccessTokenID tokenId,uint32_t reasonCode)466 ErrCode StandbyServiceImpl::IsSystemAppWithPermission(int32_t uid,
467     Security::AccessToken::AccessTokenID tokenId, uint32_t reasonCode)
468 {
469     Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
470     if (Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, STANDBY_EXEMPTION_PERMISSION)
471         != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
472         STANDBYSERVICE_LOGE("CheckPermission: ohos.permission.DEVICE_STANDBY_EXEMPTION failed");
473         return ERR_STANDBY_PERMISSION_DENIED;
474     }
475 
476     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
477     bool isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
478     if (!isSystemApp) {
479         STANDBYSERVICE_LOGE("uid %{public}d is not system app", uid);
480         return ERR_STANDBY_NOT_SYSTEM_APP;
481     }
482     if (reasonCode != ReasonCodeEnum::REASON_APP_API) {
483         STANDBYSERVICE_LOGE("reasonCode error, uid %{public}d  must be app api", uid);
484         return ERR_STANDBY_PERMISSION_DENIED;
485     }
486     auto bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
487     return CheckRunningResourcesApply(uid, bundleName);
488 }
489 
CheckNativePermission(Security::AccessToken::AccessTokenID tokenId)490 ErrCode StandbyServiceImpl::CheckNativePermission(Security::AccessToken::AccessTokenID tokenId)
491 {
492     auto tokenFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
493     if (tokenFlag == Security::AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) {
494         return ERR_OK;
495     }
496     if (tokenFlag == Security::AccessToken::TypeATokenTypeEnum::TOKEN_SHELL) {
497         return ERR_OK;
498     }
499     return ERR_STANDBY_PERMISSION_DENIED;
500 }
501 
CheckRunningResourcesApply(const int32_t uid,const std::string & bundleName)502 ErrCode StandbyServiceImpl::CheckRunningResourcesApply(const int32_t uid, const std::string &bundleName)
503 {
504     AppExecFwk::ApplicationInfo applicationInfo;
505     if (!BundleManagerHelper::GetInstance()->GetApplicationInfo(bundleName,
506         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, GetUserIdByUid(uid), applicationInfo)) {
507         STANDBYSERVICE_LOGE("failed to get applicationInfo, bundleName is %{public}s", bundleName.c_str());
508         return ERR_STANDBY_PERMISSION_DENIED;
509     }
510     STANDBYSERVICE_LOGD("applicationInfo.runningResourcesApply is %{public}d", applicationInfo.runningResourcesApply);
511     if (!applicationInfo.runningResourcesApply) {
512         return ERR_STANDBY_PERMISSION_DENIED;
513     }
514     return ERR_OK;
515 }
516 
GetUserIdByUid(int32_t uid)517 int32_t StandbyServiceImpl::GetUserIdByUid(int32_t uid)
518 {
519     const int32_t BASE_USER_RANGE = 200000;
520     return uid / BASE_USER_RANGE;
521 }
522 
SubscribeStandbyCallback(const sptr<IStandbyServiceSubscriber> & subscriber)523 ErrCode StandbyServiceImpl::SubscribeStandbyCallback(const sptr<IStandbyServiceSubscriber>& subscriber)
524 {
525     STANDBYSERVICE_LOGI("add %{public}s subscriber to stanby service", subscriber->GetSubscriberName().c_str());
526     if (CheckNativePermission(OHOS::IPCSkeleton::GetCallingTokenID()) != ERR_OK) {
527         STANDBYSERVICE_LOGW("invoker is unpermitted due to not native process or shell");
528         return ERR_STANDBY_PERMISSION_DENIED;
529     }
530     const auto& strategyConfigList = StandbyConfigManager::GetInstance()->GetStrategyConfigList();
531     auto item = std::find(strategyConfigList.begin(), strategyConfigList.end(), subscriber->GetSubscriberName());
532     if (item == strategyConfigList.end()) {
533         STANDBYSERVICE_LOGI("%{public}s is not exist in StrategyConfigList", subscriber->GetSubscriberName().c_str());
534         return ERR_STANDBY_STRATEGY_NOT_DEPLOY;
535     }
536     return StandbyStateSubscriber::GetInstance()->AddSubscriber(subscriber);
537 }
538 
UnsubscribeStandbyCallback(const sptr<IStandbyServiceSubscriber> & subscriber)539 ErrCode StandbyServiceImpl::UnsubscribeStandbyCallback(const sptr<IStandbyServiceSubscriber>& subscriber)
540 {
541     STANDBYSERVICE_LOGI("add subscriber to stanby service succeed");
542     if (CheckNativePermission(OHOS::IPCSkeleton::GetCallingTokenID()) != ERR_OK) {
543         STANDBYSERVICE_LOGW("invoker is unpermitted due to not native process or shell");
544         return ERR_STANDBY_PERMISSION_DENIED;
545     }
546     return StandbyStateSubscriber::GetInstance()->RemoveSubscriber(subscriber);
547 }
548 
ApplyAllowResource(const sptr<ResourceRequest> & resourceRequest)549 ErrCode StandbyServiceImpl::ApplyAllowResource(const sptr<ResourceRequest>& resourceRequest)
550 {
551     if (!isServiceReady_.load()) {
552         STANDBYSERVICE_LOGD("standby service is not ready");
553         return ERR_STANDBY_SYS_NOT_READY;
554     }
555     STANDBYSERVICE_LOGD("start AddAllowList");
556     if (auto checkRet = CheckCallerPermission(resourceRequest->GetReasonCode()); checkRet != ERR_OK) {
557         return checkRet;
558     }
559     if (!CheckAllowTypeInfo(resourceRequest->GetAllowType()) || resourceRequest->GetUid() < 0) {
560         STANDBYSERVICE_LOGE("resourceRequest param is invalid");
561         return ERR_RESOURCE_TYPES_INVALID;
562     }
563     if (resourceRequest->GetDuration() < 0) {
564         STANDBYSERVICE_LOGE("duration param is invalid");
565         return ERR_DURATION_INVALID;
566     }
567     int32_t pid = IPCSkeleton::GetCallingPid();
568     ApplyAllowResInner(resourceRequest, pid);
569     return ERR_OK;
570 }
571 
ApplyAllowResInner(const sptr<ResourceRequest> & resourceRequest,int32_t pid)572 void StandbyServiceImpl::ApplyAllowResInner(const sptr<ResourceRequest>& resourceRequest, int32_t pid)
573 {
574     STANDBYSERVICE_LOGI("apply res inner, uid: %{public}d, name: %{public}s, allowType: %{public}u,"\
575         " duration: %{public}d, reason: %{public}s", resourceRequest->GetUid(),
576         resourceRequest->GetName().c_str(), resourceRequest->GetAllowType(),
577         resourceRequest->GetDuration(), resourceRequest->GetReason().c_str());
578 
579     int32_t uid = resourceRequest->GetUid();
580     const std::string& name = resourceRequest->GetName();
581     std::string keyStr = std::to_string(uid) + "_" + name;
582     uint32_t preAllowType = 0;
583 
584     std::lock_guard<std::mutex> allowRecordLock(allowRecordMutex_);
585     auto iter = allowInfoMap_.find(keyStr);
586     if (iter == allowInfoMap_.end()) {
587         std::tie(iter, std::ignore) =
588             allowInfoMap_.emplace(keyStr, std::make_shared<AllowRecord>(uid, pid, name, 0));
589         iter->second->reasonCode_ = resourceRequest->GetReasonCode();
590     } else {
591         preAllowType = iter->second->allowType_;
592         iter->second->pid_ = pid;
593     }
594     UpdateRecord(iter->second, resourceRequest);
595     if (preAllowType != iter->second->allowType_) {
596         uint32_t alowTypeDiff = iter->second->allowType_ ^ (preAllowType &
597             iter->second->allowType_);
598         STANDBYSERVICE_LOGD("after update record, there is added exemption type: %{public}d",
599             alowTypeDiff);
600         StandbyStateSubscriber::GetInstance()->ReportAllowListChanged(uid, name, alowTypeDiff, true);
601         NotifyAllowListChanged(uid, name, alowTypeDiff, true);
602     }
603     if (iter->second->allowType_ == 0) {
604         STANDBYSERVICE_LOGD("%{public}s does not have valid record, delete record", keyStr.c_str());
605         allowInfoMap_.erase(iter);
606     }
607     DumpPersistantData();
608 }
609 
UpdateRecord(std::shared_ptr<AllowRecord> & allowRecord,const sptr<ResourceRequest> & resourceRequest)610 void StandbyServiceImpl::UpdateRecord(std::shared_ptr<AllowRecord>& allowRecord,
611     const sptr<ResourceRequest>& resourceRequest)
612 {
613     STANDBYSERVICE_LOGD("start UpdateRecord");
614     int32_t uid = resourceRequest->GetUid();
615     const std::string& name = resourceRequest->GetName();
616     uint32_t allowType = resourceRequest->GetAllowType();
617     bool isApp = (resourceRequest->GetReasonCode() == ReasonCodeEnum::REASON_APP_API);
618     int64_t curTime = MiscServices::TimeServiceClient::GetInstance()->GetMonotonicTimeMs();
619     int64_t endTime {0};
620     uint32_t condition = TimeProvider::GetCondition();
621     for (uint32_t allowTypeIndex = 0; allowTypeIndex < MAX_ALLOW_TYPE_NUM; ++allowTypeIndex) {
622         uint32_t allowNumber = allowType & (1 << allowTypeIndex);
623         if (allowNumber == 0) {
624             continue;
625         }
626         int64_t maxDuration = 0;
627         if (allowNumber != AllowType::WORK_SCHEDULER) {
628             maxDuration = std::min(resourceRequest->GetDuration(), StandbyConfigManager::GetInstance()->
629                 GetMaxDuration(name, AllowTypeName[allowTypeIndex], condition, isApp)) * TimeConstant::MSEC_PER_SEC;
630         } else {
631             maxDuration = resourceRequest->GetDuration() * TimeConstant::MSEC_PER_SEC;
632         }
633         if (maxDuration <= 0) {
634             continue;
635         }
636         endTime = curTime + maxDuration;
637         auto& allowTimeList = allowRecord->allowTimeList_;
638         auto findRecordTask = [allowTypeIndex](const auto& it) { return it.allowTypeIndex_ == allowTypeIndex; };
639         auto it = std::find_if(allowTimeList.begin(), allowTimeList.end(), findRecordTask);
640         if (it == allowTimeList.end()) {
641             allowTimeList.emplace_back(AllowTime {allowTypeIndex, endTime, resourceRequest->GetReason()});
642         } else {
643             it->reason_ = resourceRequest->GetReason();
644             it->endTime_ = std::max(it->endTime_, endTime);
645         }
646         allowRecord->allowType_ = (allowRecord->allowType_ | allowNumber);
647         auto task = [this, uid, name, allowType] () {
648             this->UnapplyAllowResInner(uid, name, allowType, false);
649         };
650         handler_->PostTask(task, maxDuration);
651     }
652     STANDBYSERVICE_LOGE("update end time of allow list");
653 }
654 
UnapplyAllowResource(const sptr<ResourceRequest> & resourceRequest)655 ErrCode StandbyServiceImpl::UnapplyAllowResource(const sptr<ResourceRequest>& resourceRequest)
656 {
657     if (!isServiceReady_.load()) {
658         STANDBYSERVICE_LOGD("standby service is not ready");
659         return ERR_STANDBY_SYS_NOT_READY;
660     }
661     STANDBYSERVICE_LOGD("start UnapplyAllowResource");
662     if (auto checkRet = CheckCallerPermission(resourceRequest->GetReasonCode()); checkRet != ERR_OK) {
663         return checkRet;
664     }
665     if (!CheckAllowTypeInfo(resourceRequest->GetAllowType()) || resourceRequest->GetUid() < 0) {
666         STANDBYSERVICE_LOGE("param of resourceRequest is invalid");
667         return ERR_RESOURCE_TYPES_INVALID;
668     }
669     UnapplyAllowResInner(resourceRequest->GetUid(), resourceRequest->GetName(), resourceRequest->GetAllowType(), true);
670     return ERR_OK;
671 }
672 
UnapplyAllowResInner(int32_t uid,const std::string & name,uint32_t allowType,bool removeAll)673 void StandbyServiceImpl::UnapplyAllowResInner(int32_t uid, const std::string& name,
674     uint32_t allowType, bool removeAll)
675 {
676     STANDBYSERVICE_LOGD("start UnapplyAllowResInner, uid is %{public}d, allowType is %{public}d, removeAll is "\
677         "%{public}d", uid, allowType, removeAll);
678     std::string keyStr = std::to_string(uid) + "_" + name;
679 
680     std::lock_guard<std::mutex> allowRecordLock(allowRecordMutex_);
681     auto iter = allowInfoMap_.find(keyStr);
682     if (iter == allowInfoMap_.end()) {
683         STANDBYSERVICE_LOGW("uid has no corresponding allow list");
684         return;
685     }
686     if ((allowType & iter->second->allowType_) == 0) {
687         STANDBYSERVICE_LOGW("allow list has no corresponding allow type");
688         return;
689     }
690     auto& allowRecordPtr = iter->second;
691     auto& allowTimeList = allowRecordPtr->allowTimeList_;
692     uint32_t removedNumber = 0;
693     int64_t curTime = MiscServices::TimeServiceClient::GetInstance()->GetMonotonicTimeMs();
694     for (auto it = allowTimeList.begin(); it != allowTimeList.end();) {
695         uint32_t allowNumber = allowType & (1 << it->allowTypeIndex_);
696         if (allowNumber != 0 && (removeAll || curTime >= it->endTime_)) {
697             it = allowTimeList.erase(it);
698             removedNumber |= allowNumber;
699         } else {
700             ++it;
701         }
702     }
703     STANDBYSERVICE_LOGD("remove allow list, uid: %{public}d, type: %{public}u", uid, removedNumber);
704     if (removedNumber == 0) {
705         STANDBYSERVICE_LOGW("none member of the allow list should be removed");
706         return;
707     }
708     if (removedNumber == allowRecordPtr->allowType_) {
709         allowInfoMap_.erase(keyStr);
710         STANDBYSERVICE_LOGI("allow list has been delete");
711     }
712     allowRecordPtr->allowType_ = allowRecordPtr->allowType_ - removedNumber;
713     StandbyStateSubscriber::GetInstance()->ReportAllowListChanged(uid, name, removedNumber, false);
714     NotifyAllowListChanged(uid, name, removedNumber, false);
715     DumpPersistantData();
716 }
717 
OnProcessStatusChanged(int32_t uid,int32_t pid,const std::string & bundleName,bool isCreated)718 void StandbyServiceImpl::OnProcessStatusChanged(int32_t uid, int32_t pid, const std::string& bundleName, bool isCreated)
719 {
720     if (!isServiceReady_.load()) {
721         STANDBYSERVICE_LOGD("standby service is not ready");
722         return;
723     }
724     STANDBYSERVICE_LOGD("process status change, uid: %{piblic}d, pid: %{piblic}d, name: %{piblic}s, alive: %{piblic}d",
725         uid, pid, bundleName.c_str(), isCreated);
726     StandbyMessage standbyMessage {StandbyMessageType::PROCESS_STATE_CHANGED};
727     standbyMessage.want_ = AAFwk::Want {};
728     standbyMessage.want_->SetParam("uid", uid);
729     standbyMessage.want_->SetParam("pid", pid);
730     standbyMessage.want_->SetParam("name", bundleName);
731     standbyMessage.want_->SetParam("isCreated", isCreated);
732     DispatchEvent(standbyMessage);
733 }
734 
NotifyAllowListChanged(int32_t uid,const std::string & name,uint32_t allowType,bool added)735 void StandbyServiceImpl::NotifyAllowListChanged(int32_t uid, const std::string& name,
736     uint32_t allowType, bool added)
737 {
738     StandbyMessage standbyMessage {StandbyMessageType::ALLOW_LIST_CHANGED};
739     standbyMessage.want_ = AAFwk::Want {};
740     standbyMessage.want_->SetParam("uid", uid);
741     standbyMessage.want_->SetParam("name", name);
742     standbyMessage.want_->SetParam("allowType", static_cast<int>(allowType));
743     standbyMessage.want_->SetParam("added", added);
744     DispatchEvent(standbyMessage);
745 }
746 
GetAllowList(uint32_t allowType,std::vector<AllowInfo> & allowInfoList,uint32_t reasonCode)747 ErrCode StandbyServiceImpl::GetAllowList(uint32_t allowType, std::vector<AllowInfo>& allowInfoList,
748     uint32_t reasonCode)
749 {
750     if (!isServiceReady_.load()) {
751         STANDBYSERVICE_LOGD("standby service is not ready");
752         return ERR_STANDBY_SYS_NOT_READY;
753     }
754     STANDBYSERVICE_LOGD("start GetAllowList");
755     if (auto checkRet = CheckCallerPermission(reasonCode); checkRet != ERR_OK) {
756         return checkRet;
757     }
758     if (!CheckAllowTypeInfo(allowType)) {
759         STANDBYSERVICE_LOGE("allowtype param is invalid");
760         return ERR_RESOURCE_TYPES_INVALID;
761     }
762     GetAllowListInner(allowType, allowInfoList, reasonCode);
763     return ERR_OK;
764 }
765 
GetAllowListInner(uint32_t allowType,std::vector<AllowInfo> & allowInfoList,uint32_t reasonCode)766 void StandbyServiceImpl::GetAllowListInner(uint32_t allowType, std::vector<AllowInfo>& allowInfoList,
767     uint32_t reasonCode)
768 {
769     STANDBYSERVICE_LOGD("start GetAllowListInner, allowType is %{public}d", allowType);
770 
771     std::lock_guard<std::mutex> allowRecordLock(allowRecordMutex_);
772     for (uint32_t allowTypeIndex = 0; allowTypeIndex < MAX_ALLOW_TYPE_NUM; ++allowTypeIndex) {
773         uint32_t allowNumber = allowType & (1 << allowTypeIndex);
774         if (allowNumber == 0) {
775             continue;
776         }
777         GetTemporaryAllowList(allowTypeIndex, allowInfoList, reasonCode);
778         bool isApp = (reasonCode == ReasonCodeEnum::REASON_APP_API);
779         GetPersistAllowList(allowTypeIndex, allowInfoList, true, isApp);
780     }
781 }
782 
GetTemporaryAllowList(uint32_t allowTypeIndex,std::vector<AllowInfo> & allowInfoList,uint32_t reasonCode)783 void StandbyServiceImpl::GetTemporaryAllowList(uint32_t allowTypeIndex, std::vector<AllowInfo>&
784     allowInfoList, uint32_t reasonCode)
785 {
786     int32_t curTime = MiscServices::TimeServiceClient::GetInstance()->GetMonotonicTimeMs();
787     auto findRecordTask = [allowTypeIndex](const auto& it) { return it.allowTypeIndex_ == allowTypeIndex; };
788     for (auto& [key, allowRecordPtr] : allowInfoMap_) {
789         if ((allowRecordPtr->allowType_ & (1 << allowTypeIndex)) == 0) {
790             continue;
791         }
792         if (allowRecordPtr->reasonCode_ != reasonCode) {
793             continue;
794         }
795         auto& allowTimeList = allowRecordPtr->allowTimeList_;
796         auto it = std::find_if(allowTimeList.begin(), allowTimeList.end(), findRecordTask);
797         if (it == allowTimeList.end()) {
798             continue;
799         }
800         allowInfoList.emplace_back((1 << allowTypeIndex), allowRecordPtr->name_,
801             std::max(static_cast<long>(it->endTime_ - curTime), 0L));
802     }
803 }
804 
GetPersistAllowList(uint32_t allowTypeIndex,std::vector<AllowInfo> & allowInfoList,bool isAllow,bool isApp)805 void StandbyServiceImpl::GetPersistAllowList(uint32_t allowTypeIndex, std::vector<AllowInfo>& allowInfoList,
806     bool isAllow, bool isApp)
807 {
808     uint32_t condition = TimeProvider::GetCondition();
809     std::set<std::string> psersistAllowList;
810     if (isApp) {
811         psersistAllowList = StandbyConfigManager::GetInstance()->GetEligiblePersistAllowConfig(
812             AllowTypeName[allowTypeIndex], condition, isAllow, true);
813     } else {
814         psersistAllowList = StandbyConfigManager::GetInstance()->GetEligiblePersistAllowConfig(
815             AllowTypeName[allowTypeIndex], condition, isAllow, false);
816     }
817     for (const auto& allowName : psersistAllowList) {
818         allowInfoList.emplace_back((1 << allowTypeIndex), allowName, -1);
819     }
820 }
821 
IsDeviceInStandby(bool & isStandby)822 ErrCode StandbyServiceImpl::IsDeviceInStandby(bool& isStandby)
823 {
824     if (!isServiceReady_.load()) {
825         STANDBYSERVICE_LOGD("standby service is not ready");
826         return ERR_STANDBY_SYS_NOT_READY;
827     }
828     handler_->PostSyncTask([this, &isStandby]() {
829         auto curState = standbyStateManager_->GetCurState();
830         isStandby = (curState == StandbyState::SLEEP);
831         }, AppExecFwk::EventQueue::Priority::HIGH);
832     return ERR_OK;
833 }
834 
GetEligiableRestrictSet(uint32_t allowType,const std::string & strategyName,uint32_t resonCode,std::set<std::string> & restrictSet)835 ErrCode StandbyServiceImpl::GetEligiableRestrictSet(uint32_t allowType, const std::string& strategyName,
836     uint32_t resonCode, std::set<std::string>& restrictSet)
837 {
838     uint32_t condition = TimeProvider::GetCondition();
839     std::set<std::string> originRestrictSet = StandbyConfigManager::GetInstance()->GetEligiblePersistAllowConfig(
840         strategyName, condition, false, resonCode == ReasonCodeEnum::REASON_APP_API);
841     std::vector<AllowInfo> allowInfoList;
842     GetAllowListInner(allowType, allowInfoList, resonCode);
843     std::set<std::string> allowSet;
844     for_each(allowInfoList.begin(), allowInfoList.end(),
845         [&allowSet](AllowInfo& allowInfo) { allowSet.insert(allowInfo.GetName()); });
846 
847     std::set_difference(originRestrictSet.begin(), originRestrictSet.end(), allowSet.begin(),
848         allowSet.end(), std::inserter(restrictSet, restrictSet.begin()));
849     STANDBYSERVICE_LOGD("origin restrict size is %{public}d, restrictSet size is %{public}d, "\
850         "restrictSet size is %{public}d", static_cast<int32_t>(originRestrictSet.size()),
851         static_cast<int32_t>(allowInfoList.size()), static_cast<int32_t>(restrictSet.size()));
852     return ERR_OK;
853 }
854 
ReportWorkSchedulerStatus(bool started,int32_t uid,const std::string & bundleName)855 ErrCode StandbyServiceImpl::ReportWorkSchedulerStatus(bool started, int32_t uid, const std::string& bundleName)
856 {
857     if (!isServiceReady_.load()) {
858         return ERR_STANDBY_SYS_NOT_READY;
859     }
860     STANDBYSERVICE_LOGI("work scheduler status changed, isstarted: %{public}d, uid: %{public}d, bundleName: %{public}s",
861         started, uid, bundleName.c_str());
862     Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
863     if (CheckNativePermission(tokenId) != ERR_OK) {
864         STANDBYSERVICE_LOGW("invoker is unpermitted due to not native process or shell");
865         return ERR_STANDBY_PERMISSION_DENIED;
866     }
867     StandbyMessage standbyMessage {StandbyMessageType::BG_TASK_STATUS_CHANGE};
868     standbyMessage.want_ = AAFwk::Want {};
869     standbyMessage.want_->SetParam(BG_TASK_TYPE, WORK_SCHEDULER);
870     standbyMessage.want_->SetParam(BG_TASK_STATUS, started);
871     standbyMessage.want_->SetParam(BG_TASK_UID, uid);
872     DispatchEvent(standbyMessage);
873     return ERR_OK;
874 }
875 
GetRestrictList(uint32_t restrictType,std::vector<AllowInfo> & restrictInfoList,uint32_t reasonCode)876 ErrCode StandbyServiceImpl::GetRestrictList(uint32_t restrictType, std::vector<AllowInfo>& restrictInfoList,
877     uint32_t reasonCode)
878 {
879     if (!isServiceReady_.load()) {
880         STANDBYSERVICE_LOGD("standby service is not ready");
881         return ERR_STANDBY_SYS_NOT_READY;
882     }
883     STANDBYSERVICE_LOGD("start GetRestrictList");
884     if (CheckNativePermission(OHOS::IPCSkeleton::GetCallingTokenID()) != ERR_OK) {
885         STANDBYSERVICE_LOGW("invoker is unpermitted due to not native process or shell");
886         return ERR_STANDBY_PERMISSION_DENIED;
887     }
888     if (!CheckAllowTypeInfo(restrictType)) {
889         STANDBYSERVICE_LOGE("restrictType param is invalid");
890         return ERR_RESOURCE_TYPES_INVALID;
891     }
892     GetRestrictListInner(restrictType, restrictInfoList, reasonCode);
893     return ERR_OK;
894 }
895 
GetRestrictListInner(uint32_t restrictType,std::vector<AllowInfo> & restrictInfoList,uint32_t reasonCode)896 void StandbyServiceImpl::GetRestrictListInner(uint32_t restrictType, std::vector<AllowInfo>& restrictInfoList,
897     uint32_t reasonCode)
898 {
899     STANDBYSERVICE_LOGD("start GetRestrictListInner, restrictType is %{public}d", restrictType);
900     for (uint32_t restrictTypeIndex = 0; restrictTypeIndex < MAX_ALLOW_TYPE_NUM; ++restrictTypeIndex) {
901         uint32_t restrictNumber = restrictType & (1 << restrictTypeIndex);
902         if (restrictNumber == 0) {
903             continue;
904         }
905         bool isApp = (reasonCode == ReasonCodeEnum::REASON_APP_API);
906         GetPersistAllowList(restrictTypeIndex, restrictInfoList, false, isApp);
907     }
908 }
909 
IsStrategyEnabled(const std::string & strategyName,bool & isStandby)910 ErrCode StandbyServiceImpl::IsStrategyEnabled(const std::string& strategyName, bool& isStandby)
911 {
912     if (!isServiceReady_.load()) {
913         STANDBYSERVICE_LOGD("standby service is not ready");
914         return ERR_STANDBY_SYS_NOT_READY;
915     }
916     STANDBYSERVICE_LOGD("start IsStrategyEnabled");
917     if (CheckNativePermission(OHOS::IPCSkeleton::GetCallingTokenID()) != ERR_OK) {
918         STANDBYSERVICE_LOGW("invoker is unpermitted due to not native process or shell");
919         return ERR_STANDBY_PERMISSION_DENIED;
920     }
921     const auto& strategyConfigList = StandbyConfigManager::GetInstance()->GetStrategyConfigList();
922     auto item = std::find(strategyConfigList.begin(), strategyConfigList.end(), strategyName);
923     isStandby = item != strategyConfigList.end();
924     return ERR_OK;
925 }
926 
ReportDeviceStateChanged(DeviceStateType type,bool enabled)927 ErrCode StandbyServiceImpl::ReportDeviceStateChanged(DeviceStateType type, bool enabled)
928 {
929     if (!isServiceReady_.load()) {
930         return ERR_STANDBY_SYS_NOT_READY;
931     }
932     STANDBYSERVICE_LOGI("device state changed, state type: %{public}d, enabled: %{public}d",
933         static_cast<int32_t>(type), enabled);
934     if (CheckNativePermission(OHOS::IPCSkeleton::GetCallingTokenID()) != ERR_OK) {
935         STANDBYSERVICE_LOGE("dump user is unpermitted due to not native process or shell");
936         return ERR_STANDBY_PERMISSION_DENIED;
937     }
938     DeviceStateCache::GetInstance()->SetDeviceState(static_cast<int32_t>(type), enabled);
939     if (!enabled) {
940         return ERR_OK;
941     }
942     StandbyMessage standbyMessage {StandbyMessageType::DEVICE_STATE_CHANGED};
943     standbyMessage.want_ = AAFwk::Want {};
944     standbyMessage.want_->SetParam("DIS_COMP_STATE", enabled);
945     DispatchEvent(standbyMessage);
946     return ERR_OK;
947 }
948 
DispatchEvent(const StandbyMessage & message)949 void StandbyServiceImpl::DispatchEvent(const StandbyMessage& message)
950 {
951     if (!isServiceReady_.load()) {
952         STANDBYSERVICE_LOGW("standby service is not ready");
953         return;
954     }
955 
956     auto dispatchEventFunc = [this, message]() {
957         STANDBYSERVICE_LOGD("standby service implement dispatch message %{public}d", message.eventId_);
958         if (!listenerManager_ || !standbyStateManager_ || !strategyManager_) {
959             STANDBYSERVICE_LOGE("can not dispatch event, state manager or strategy manager is nullptr");
960             return;
961         };
962         listenerManager_->HandleEvent(message);
963         standbyStateManager_->HandleEvent(message);
964         strategyManager_->HandleEvent(message);
965     };
966 
967     handler_->PostTask(dispatchEventFunc);
968 }
969 
IsDebugMode()970 bool StandbyServiceImpl::IsDebugMode()
971 {
972     return debugMode_;
973 }
974 
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)975 void StandbyServiceImpl::ShellDump(const std::vector<std::string>& argsInStr,
976     std::string& result)
977 {
978     if (!isServiceReady_.load()) {
979         result += "standby service manager is not ready";
980         return;
981     }
982     Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
983     if (CheckNativePermission(tokenId) != ERR_OK) {
984         STANDBYSERVICE_LOGE("dump user is unpermitted due to not native process or shell");
985         result += "please using root identity\n";
986         return;
987     }
988     handler_->PostSyncTask([this, &argsInStr, &result]() {
989         this->ShellDumpInner(argsInStr, result);
990         }, AppExecFwk::EventQueue::Priority::HIGH);
991 }
992 
ShellDumpInner(const std::vector<std::string> & argsInStr,std::string & result)993 void StandbyServiceImpl::ShellDumpInner(const std::vector<std::string>& argsInStr,
994     std::string& result)
995 {
996     auto argc = argsInStr.size();
997     if (argc == NO_DUMP_PARAM_NUMS || argsInStr[DUMP_FIRST_PARAM] == "-h") {
998         DumpUsage(result);
999     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_DETAIL_INFO) {
1000         DumpShowDetailInfo(argsInStr, result);
1001     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_ENTER_STATE) {
1002         DumpEnterSpecifiedState(argsInStr, result);
1003     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_APPLY_ALLOW_RECORD) {
1004         DumpModifyAllowList(argsInStr, result);
1005     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_SIMULATE_SENSOR) {
1006         DumpActivateMotion(argsInStr, result);
1007     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_SUBSCRIBER_OBSERVER) {
1008         DumpSubScriberObserver(argsInStr, result);
1009     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_TURN_ON_OFF_SWITCH) {
1010         DumpTurnOnOffSwitch(argsInStr, result);
1011     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_CHANGE_STATE_TIMEOUT) {
1012         DumpChangeConfigParam(argsInStr, result);
1013     } else {
1014         result += "Error params.\n";
1015     }
1016 }
1017 
DumpUsage(std::string & result)1018 void StandbyServiceImpl::DumpUsage(std::string& result)
1019 {
1020     std::string dumpHelpMsg =
1021     "usage: dev standby service dump [<options>]\n"
1022     "options list:\n"
1023     "    -h                                                 help menu\n"
1024     "    -D                                                 show detail information\n"
1025     "        --config                                            show all info, including config\n"
1026     "        --reset_state                                       reset parameter, validate debug parameter\n"
1027     "        --strategy                                          dump strategy info\n"
1028     "    -E                                                 enter the specified state:\n"
1029     "        {id of state} {whether skip evalution}         enter the specified state, 0-4 represent respectively\n"
1030     "                                                            woking, dark, nap, maintenance, sleep\n"
1031     "    -A                                                 modify the allow list:\n"
1032     "        --apply {uid} {name} {type} {duration} {reasoncode} apply the type of the uid to allow list\n"
1033     "        --unapply {uid} {name} {type}                  delete the type of the uid from allow list\n"
1034     "        --get {type} {isApp}                                get allow list info\n"
1035     "    -S                                                 simulately activate the sensor:\n"
1036     "        {--motion or --repeat or --blocked or --halfhour} simulately activate the motion sensor\n"
1037     "        {--poweroff}                                      power off strategy\n"
1038     "    -T  {switch name} {on or off}                      turn on or turn off some switches, switch can be debug,\n"
1039     "                                                            nap_switch, sleep_switch, detect_motion, other\n"
1040     "                                                            switch only be used after open debug switch\n"
1041     "    -C  {parameter name} {parameter value}             change config parameter, only can be used when debug\n";
1042 
1043     result.append(dumpHelpMsg);
1044 }
1045 
DumpShowDetailInfo(const std::vector<std::string> & argsInStr,std::string & result)1046 void StandbyServiceImpl::DumpShowDetailInfo(const std::vector<std::string>& argsInStr,
1047     std::string& result)
1048 {
1049     DumpAllowListInfo(result);
1050     standbyStateManager_->ShellDump(argsInStr, result);
1051     if (argsInStr.size() < DUMP_DETAILED_INFO_MAX_NUMS) {
1052         return;
1053     }
1054     if (argsInStr[DUMP_SECOND_PARAM] == DUMP_DETAIL_CONFIG) {
1055         DumpStandbyConfigInfo(result);
1056     } else if (argsInStr[DUMP_SECOND_PARAM] == DUMP_STRATGY_DETAIL) {
1057         strategyManager_->ShellDump(argsInStr, result);
1058     } else if (argsInStr[DUMP_SECOND_PARAM] == DUMP_RESET_STATE) {
1059         standbyStateManager_->UnInit();
1060         standbyStateManager_->Init();
1061         result += "validate debug parameter\n";
1062     }
1063 }
1064 
DumpAllowListInfo(std::string & result)1065 void StandbyServiceImpl::DumpAllowListInfo(std::string& result)
1066 {
1067     std::lock_guard<std::mutex> allowRecordLock(allowRecordMutex_);
1068     if (allowInfoMap_.empty()) {
1069         result += "allow resources record is empty\n";
1070         return;
1071     }
1072 
1073     std::stringstream stream;
1074     uint32_t index = 1;
1075     for (auto iter = allowInfoMap_.begin(); iter != allowInfoMap_.end(); iter++) {
1076         stream << "No." << index << "\n";
1077         stream << "\tuid: " << iter->first << "\n";
1078         stream << "\tallow record: " << "\n";
1079         stream << "\t\tname: " << iter->second->name_ << "\n";
1080         stream << "\t\tpid: " << iter->second->pid_ << "\n";
1081         stream << "\t\tallow type: " << iter->second->allowType_ << "\n";
1082         stream << "\t\treason code: " << iter->second->reasonCode_ << "\n";
1083         int64_t curTime = MiscServices::TimeServiceClient::GetInstance()->GetMonotonicTimeMs();
1084         auto &allowTimeList = iter->second->allowTimeList_;
1085         for (auto unitIter = allowTimeList.begin();
1086             unitIter != allowTimeList.end(); ++unitIter) {
1087             stream << "\t\t\tallow type: " << AllowTypeName[unitIter->allowTypeIndex_] << "\n";
1088             stream << "\t\t\tremainTime: " << unitIter->endTime_ - curTime << "\n";
1089             stream << "\t\t\treason: " << unitIter->reason_ << "\n";
1090         }
1091         stream << "\n";
1092         result += stream.str();
1093         stream.str("");
1094         stream.clear();
1095         index++;
1096     }
1097 }
1098 
DumpStandbyConfigInfo(std::string & result)1099 void StandbyServiceImpl::DumpStandbyConfigInfo(std::string& result)
1100 {
1101     result += (debugMode_ ? "debugMode: true\n" : "debugMode: false\n");
1102     StandbyConfigManager::GetInstance()->DumpStandbyConfigInfo(result);
1103 }
1104 
DumpEnterSpecifiedState(const std::vector<std::string> & argsInStr,std::string & result)1105 void StandbyServiceImpl::DumpEnterSpecifiedState(const std::vector<std::string>& argsInStr,
1106     std::string& result)
1107 {
1108     if (argsInStr.size() < DUMP_SLEEP_ENTER_STATE_NUMS) {
1109         result += "not enough parameter for changing sleep mode\n";
1110         return;
1111     } else {
1112         standbyStateManager_->ShellDump(argsInStr, result);
1113     }
1114 }
1115 
DumpModifyAllowList(const std::vector<std::string> & argsInStr,std::string & result)1116 void StandbyServiceImpl::DumpModifyAllowList(const std::vector<std::string>& argsInStr,
1117     std::string& result)
1118 {
1119     if (argsInStr.size() < DUMP_SLEEP_ALLOW_LIST_NUMS || (argsInStr[DUMP_SECOND_PARAM] != "--get" &&
1120         argsInStr.size() < DUMP_SLEEP_APPLY_ALLOW_LIST_NUMS)) {
1121         result += "not enough parameter for changing allow list\n";
1122         return;
1123     }
1124     int32_t uid = std::atoi(argsInStr[DUMP_THIRD_PARAM].c_str());
1125     std::string name = argsInStr[DUMP_FOURTH_PARAM];
1126     if (argsInStr[DUMP_SECOND_PARAM] == "--apply") {
1127         uint32_t allowType = static_cast<uint32_t>(std::atoi(argsInStr[DUMP_FIFTH_PARAM].c_str()));
1128         int32_t duration = std::atoi(argsInStr[DUMP_SIXTH_PARAM].c_str());
1129         sptr<ResourceRequest> resourceRequest = new (std::nothrow) ResourceRequest(allowType,
1130             uid, name, duration, "dump", std::atoi(argsInStr[DUMP_SEVENTH_PARAM].c_str()));
1131         ApplyAllowResource(resourceRequest);
1132         result += "add one object to allow list\n";
1133     } else if (argsInStr[DUMP_SECOND_PARAM] == "--unapply") {
1134         uint32_t allowType = static_cast<uint32_t>(std::atoi(argsInStr[DUMP_FIFTH_PARAM].c_str()));
1135         sptr<ResourceRequest> resourceRequest = new (std::nothrow) ResourceRequest(allowType,
1136             uid, name, 0, "dump", std::atoi(argsInStr[DUMP_SEVENTH_PARAM].c_str()));
1137         UnapplyAllowResource(resourceRequest);
1138         result += "remove one object to allow list\n";
1139     } else if (argsInStr[DUMP_SECOND_PARAM] == "--get") {
1140         uint32_t allowType = static_cast<uint32_t>(std::atoi(argsInStr[DUMP_THIRD_PARAM].c_str()));
1141         bool isApp = (std::atoi(argsInStr[DUMP_FOURTH_PARAM].c_str()) == 0);
1142         std::vector<AllowInfo> allowInfoList;
1143         GetAllowListInner(allowType, allowInfoList, isApp);
1144         for (const auto& allowInfo : allowInfoList) {
1145             result += "allowType: " + std::to_string(allowInfo.GetAllowType()) + "\n" +
1146             "name: " + allowInfo.GetName() + "\n" +
1147             "duration: " + std::to_string(allowInfo.GetDuration()) + "\n";
1148         }
1149         allowInfoList.clear();
1150         GetRestrictListInner(allowType, allowInfoList, isApp);
1151         for (const auto& allowInfo : allowInfoList) {
1152             result += "restrictType: " + std::to_string(allowInfo.GetAllowType()) + "\n" +
1153             "name: " + allowInfo.GetName() + "\n";
1154         }
1155     }
1156 }
1157 
DumpTurnOnOffSwitch(const std::vector<std::string> & argsInStr,std::string & result)1158 void StandbyServiceImpl::DumpTurnOnOffSwitch(const std::vector<std::string>& argsInStr, std::string& result)
1159 {
1160     if (argsInStr.size() != DUMP_SWITCH_PARAM_NUMS) {
1161         result += "not correct parameter number for turn on or turn off switch\n";
1162         return;
1163     }
1164     bool switchStatus {false};
1165     if (argsInStr[DUMP_THIRD_PARAM] == DUMP_ON) {
1166         switchStatus = true;
1167     } else if (argsInStr[DUMP_THIRD_PARAM] == DUMP_OFF) {
1168         switchStatus = false;
1169     } else {
1170         result += "not correct parameter for turn on or turn off switch\n";
1171         return;
1172     }
1173     const std::string& switchName = argsInStr[DUMP_SECOND_PARAM];
1174     if (switchName == DUMP_DEBUG_SWITCH) {
1175         debugMode_ = switchStatus;
1176         StandbyConfigManager::GetInstance()->DumpSetDebugMode(debugMode_);
1177         result += (debugMode_ ? "debugMode: true\n" : "debugMode: false\n");
1178         return;
1179     } else if (!debugMode_) {
1180         result += "other switch can be changed only in debug mode\n";
1181         return;
1182     }
1183     StandbyConfigManager::GetInstance()->DumpSetSwitch(switchName, switchStatus, result);
1184 }
1185 
DumpChangeConfigParam(const std::vector<std::string> & argsInStr,std::string & result)1186 void StandbyServiceImpl::DumpChangeConfigParam(const std::vector<std::string>& argsInStr, std::string& result)
1187 {
1188     if (argsInStr.size() != DUMP_STATE_TIMEOUT_PARAM_NUMS) {
1189         result += "not correct parameter number for change state timeout\n";
1190         return;
1191     }
1192     if (!debugMode_) {
1193         result += "current is not in debug mode, can not change timeout\n";
1194         return;
1195     }
1196     StandbyConfigManager::GetInstance()->DumpSetParameter(argsInStr[DUMP_SECOND_PARAM],
1197         std::atoi(argsInStr[DUMP_THIRD_PARAM].c_str()), result);
1198 }
1199 
DumpActivateMotion(const std::vector<std::string> & argsInStr,std::string & result)1200 void StandbyServiceImpl::DumpActivateMotion(const std::vector<std::string>& argsInStr,
1201     std::string& result)
1202 {
1203     standbyStateManager_->ShellDump(argsInStr, result);
1204     constraintManager_->ShellDump(argsInStr, result);
1205 }
1206 
DumpSubScriberObserver(const std::vector<std::string> & argsInStr,std::string & result)1207 void StandbyServiceImpl::DumpSubScriberObserver(const std::vector<std::string>& argsInStr, std::string& result)
1208 {
1209     StandbyStateSubscriber::GetInstance()->ShellDump(argsInStr, result);
1210 }
1211 
1212 IMPLEMENT_SINGLE_INSTANCE(DeviceStateCache);
1213 
DeviceStateCache()1214 DeviceStateCache::DeviceStateCache()
1215 {
1216     deviceState_ = {false, false, false};
1217 }
1218 
~DeviceStateCache()1219 DeviceStateCache::~DeviceStateCache() {}
1220 
SetDeviceState(int32_t type,bool enabled)1221 bool DeviceStateCache::SetDeviceState(int32_t type, bool enabled)
1222 {
1223     STANDBYSERVICE_LOGD("set device state %{public}d, enabled is %{public}d", type, enabled);
1224     if (type < 0 || type >= DEVICE_STATE_NUM) {
1225         return false;
1226     }
1227     std::lock_guard<std::mutex> lock(mutex_);
1228     if (deviceState_[type] == enabled) {
1229         return false;
1230     }
1231     deviceState_[type] = enabled;
1232     return true;
1233 }
1234 
GetDeviceState(int32_t type)1235 bool DeviceStateCache::GetDeviceState(int32_t type)
1236 {
1237     if (type < 0 || type >= DEVICE_STATE_NUM) {
1238         return false;
1239     }
1240     STANDBYSERVICE_LOGD("get device state %{public}d, enabled is %{public}d", type, deviceState_[type]);
1241     return deviceState_[type];
1242 }
1243 }  // namespace DevStandbyMgr
1244 }  // namespace OHOS
1245