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