199552fe9Sopenharmony_ci/* 299552fe9Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 399552fe9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 499552fe9Sopenharmony_ci * you may not use this file except in compliance with the License. 599552fe9Sopenharmony_ci * You may obtain a copy of the License at 699552fe9Sopenharmony_ci * 799552fe9Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 899552fe9Sopenharmony_ci * 999552fe9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1099552fe9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1199552fe9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1299552fe9Sopenharmony_ci * See the License for the specific language governing permissions and 1399552fe9Sopenharmony_ci * limitations under the License. 1499552fe9Sopenharmony_ci */ 1599552fe9Sopenharmony_ci 1699552fe9Sopenharmony_ci#include "sleep_state.h" 1799552fe9Sopenharmony_ci 1899552fe9Sopenharmony_ci#include <cmath> 1999552fe9Sopenharmony_ci#include "time_service_client.h" 2099552fe9Sopenharmony_ci 2199552fe9Sopenharmony_ci#include "standby_service_log.h" 2299552fe9Sopenharmony_ci#include "standby_config_manager.h" 2399552fe9Sopenharmony_ci#include "iconstraint_manager_adapter.h" 2499552fe9Sopenharmony_ci#include "istate_manager_adapter.h" 2599552fe9Sopenharmony_ci#include "time_provider.h" 2699552fe9Sopenharmony_ci#include "timed_task.h" 2799552fe9Sopenharmony_ci 2899552fe9Sopenharmony_ciusing namespace OHOS::MiscServices; 2999552fe9Sopenharmony_cinamespace OHOS { 3099552fe9Sopenharmony_cinamespace DevStandbyMgr { 3199552fe9Sopenharmony_cinamespace { 3299552fe9Sopenharmony_ci constexpr int32_t DUMP_REPEAT_DETECTION_TIMEOUT = 100; 3399552fe9Sopenharmony_ci} 3499552fe9Sopenharmony_ci 3599552fe9Sopenharmony_ciSleepState::SleepState(uint32_t curState, uint32_t curPhase, const std::shared_ptr<IStateManagerAdapter>& 3699552fe9Sopenharmony_ci stateManager, std::shared_ptr<AppExecFwk::EventHandler>& handler): BaseState(curState, 3799552fe9Sopenharmony_ci curPhase, stateManager, handler) 3899552fe9Sopenharmony_ci{ 3999552fe9Sopenharmony_ci maintInterval_ = StandbyConfigManager::GetInstance()->GetStandbyDurationList(SLEEP_MAINT_DURATOIN); 4099552fe9Sopenharmony_ci nextState_ = StandbyState::MAINTENANCE; 4199552fe9Sopenharmony_ci} 4299552fe9Sopenharmony_ci 4399552fe9Sopenharmony_ciErrCode SleepState::Init(const std::shared_ptr<BaseState>& statePtr) 4499552fe9Sopenharmony_ci{ 4599552fe9Sopenharmony_ci auto callbackTask = [statePtr]() { statePtr->StartTransitNextState(statePtr); }; 4699552fe9Sopenharmony_ci enterStandbyTimerId_ = TimedTask::CreateTimer(false, 0, true, true, callbackTask); 4799552fe9Sopenharmony_ci if (enterStandbyTimerId_ == 0) { 4899552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("%{public}s state init failed", STATE_NAME_LIST[GetCurState()].c_str()); 4999552fe9Sopenharmony_ci return ERR_STANDBY_STATE_INIT_FAILED; 5099552fe9Sopenharmony_ci } 5199552fe9Sopenharmony_ci 5299552fe9Sopenharmony_ci if (!StandbyConfigManager::GetInstance()->GetStandbySwitch(DETECT_MOTION_CONFIG)) { 5399552fe9Sopenharmony_ci return ERR_OK; 5499552fe9Sopenharmony_ci } 5599552fe9Sopenharmony_ci auto callback = [sleepState = shared_from_this()]() { sleepState->StartPeriodlyMotionDetection(); }; 5699552fe9Sopenharmony_ci repeatedDetectionTimerId_ = TimedTask::CreateTimer(true, REPEATED_MOTION_DETECTION_INTERVAL, true, false, callback); 5799552fe9Sopenharmony_ci if (repeatedDetectionTimerId_ == 0) { 5899552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("%{public}s init failed", STATE_NAME_LIST[GetCurState()].c_str()); 5999552fe9Sopenharmony_ci return ERR_STANDBY_STATE_INIT_FAILED; 6099552fe9Sopenharmony_ci } 6199552fe9Sopenharmony_ci SetTimedTask(REPEATED_MOTION_DETECTION_TASK, repeatedDetectionTimerId_); 6299552fe9Sopenharmony_ci return ERR_OK; 6399552fe9Sopenharmony_ci} 6499552fe9Sopenharmony_ci 6599552fe9Sopenharmony_civoid SleepState::StartPeriodlyMotionDetection() 6699552fe9Sopenharmony_ci{ 6799552fe9Sopenharmony_ci handler_->PostTask([sleepState = shared_from_this()]() { 6899552fe9Sopenharmony_ci sleepState->isRepeatedDetection_ = true; 6999552fe9Sopenharmony_ci ConstraintEvalParam params{sleepState->curState_, sleepState->curPhase_, 7099552fe9Sopenharmony_ci sleepState->curState_, sleepState->curPhase_}; 7199552fe9Sopenharmony_ci params.isRepeatedDetection_ = true; 7299552fe9Sopenharmony_ci auto stateManagerPtr = sleepState->stateManager_.lock(); 7399552fe9Sopenharmony_ci if (!stateManagerPtr) { 7499552fe9Sopenharmony_ci return; 7599552fe9Sopenharmony_ci } 7699552fe9Sopenharmony_ci stateManagerPtr->StartEvalCurrentState(params); 7799552fe9Sopenharmony_ci }, REPEATED_MOTION_DETECTION_TASK); 7899552fe9Sopenharmony_ci} 7999552fe9Sopenharmony_ci 8099552fe9Sopenharmony_ciErrCode SleepState::UnInit() 8199552fe9Sopenharmony_ci{ 8299552fe9Sopenharmony_ci BaseState::UnInit(); 8399552fe9Sopenharmony_ci isRepeatedDetection_ = false; 8499552fe9Sopenharmony_ci repeatedDetectionTimerId_ = 0; 8599552fe9Sopenharmony_ci return ERR_OK; 8699552fe9Sopenharmony_ci} 8799552fe9Sopenharmony_ci 8899552fe9Sopenharmony_ciErrCode SleepState::BeginState() 8999552fe9Sopenharmony_ci{ 9099552fe9Sopenharmony_ci auto stateManagerPtr = stateManager_.lock(); 9199552fe9Sopenharmony_ci if (!stateManagerPtr) { 9299552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("state manager adapter is nullptr"); 9399552fe9Sopenharmony_ci return ERR_STATE_MANAGER_IS_NULLPTR; 9499552fe9Sopenharmony_ci } 9599552fe9Sopenharmony_ci isRepeatedDetection_ = false; 9699552fe9Sopenharmony_ci int64_t maintIntervalTimeOut = 0; 9799552fe9Sopenharmony_ci if (stateManagerPtr->GetPreState() == StandbyState::MAINTENANCE) { 9899552fe9Sopenharmony_ci maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, false); 9999552fe9Sopenharmony_ci if (maintIntervalTimeOut != 0) { 10099552fe9Sopenharmony_ci STANDBYSERVICE_LOGI("from maintenance to sleep, maintIntervalTimeOut is " SPUBI64, 10199552fe9Sopenharmony_ci maintIntervalTimeOut); 10299552fe9Sopenharmony_ci StartStateTransitionTimer(maintIntervalTimeOut); 10399552fe9Sopenharmony_ci } 10499552fe9Sopenharmony_ci return ERR_OK; 10599552fe9Sopenharmony_ci } 10699552fe9Sopenharmony_ci 10799552fe9Sopenharmony_ci maintIntervalIndex_ = 0; 10899552fe9Sopenharmony_ci curPhase_ = SleepStatePhase::SYS_RES_DEEP; 10999552fe9Sopenharmony_ci maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, true); 11099552fe9Sopenharmony_ci STANDBYSERVICE_LOGI("maintIntervalTimeOut is " SPUBI64 " ms", maintIntervalTimeOut); 11199552fe9Sopenharmony_ci 11299552fe9Sopenharmony_ci handler_->PostTask([sleepState = shared_from_this()]() { 11399552fe9Sopenharmony_ci BaseState::AcquireStandbyRunningLock(); 11499552fe9Sopenharmony_ci sleepState->TransitToPhase(sleepState->curPhase_, sleepState->curPhase_ + 1); 11599552fe9Sopenharmony_ci }, TRANSIT_NEXT_PHASE_INSTANT_TASK); 11699552fe9Sopenharmony_ci StartStateTransitionTimer(maintIntervalTimeOut); 11799552fe9Sopenharmony_ci CheckScrenOffHalfHour(); 11899552fe9Sopenharmony_ci return ERR_OK; 11999552fe9Sopenharmony_ci} 12099552fe9Sopenharmony_ci 12199552fe9Sopenharmony_civoid SleepState::TryToEnterNextPhase(const std::shared_ptr<IStateManagerAdapter>& stateManagerPtr, 12299552fe9Sopenharmony_ci int32_t retryTimeOut) 12399552fe9Sopenharmony_ci{ 12499552fe9Sopenharmony_ci if (stateManagerPtr->IsEvalution()) { 12599552fe9Sopenharmony_ci STANDBYSERVICE_LOGW("state is in evalution, postpone to enter next phase"); 12699552fe9Sopenharmony_ci handler_->PostTask([sleepState = shared_from_this(), stateManagerPtr, retryTimeOut]() { 12799552fe9Sopenharmony_ci sleepState->TryToEnterNextPhase(stateManagerPtr, retryTimeOut); 12899552fe9Sopenharmony_ci }, TRANSIT_NEXT_PHASE_INSTANT_TASK, retryTimeOut); 12999552fe9Sopenharmony_ci } else if (curPhase_ < SleepStatePhase::END) { 13099552fe9Sopenharmony_ci TransitToPhase(curPhase_, curPhase_ + 1); 13199552fe9Sopenharmony_ci } 13299552fe9Sopenharmony_ci} 13399552fe9Sopenharmony_ci 13499552fe9Sopenharmony_ciErrCode SleepState::EndState() 13599552fe9Sopenharmony_ci{ 13699552fe9Sopenharmony_ci StopTimedTask(TRANSIT_NEXT_STATE_TIMED_TASK); 13799552fe9Sopenharmony_ci StopTimedTask(REPEATED_MOTION_DETECTION_TASK); 13899552fe9Sopenharmony_ci handler_->RemoveTask(TRANSIT_NEXT_STATE_TIMED_TASK); 13999552fe9Sopenharmony_ci handler_->RemoveTask(TRANSIT_NEXT_PHASE_INSTANT_TASK); 14099552fe9Sopenharmony_ci handler_->RemoveTask(REPEATED_MOTION_DETECTION_TASK); 14199552fe9Sopenharmony_ci return ERR_OK; 14299552fe9Sopenharmony_ci} 14399552fe9Sopenharmony_ci 14499552fe9Sopenharmony_cibool SleepState::CheckTransitionValid(uint32_t nextState) 14599552fe9Sopenharmony_ci{ 14699552fe9Sopenharmony_ci if (nextState == StandbyState::NAP) { 14799552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("can not transit from sleep to nap"); 14899552fe9Sopenharmony_ci return false; 14999552fe9Sopenharmony_ci } 15099552fe9Sopenharmony_ci return true; 15199552fe9Sopenharmony_ci} 15299552fe9Sopenharmony_ci 15399552fe9Sopenharmony_civoid SleepState::EndEvalCurrentState(bool evalResult) 15499552fe9Sopenharmony_ci{ 15599552fe9Sopenharmony_ci auto stateManagerPtr = stateManager_.lock(); 15699552fe9Sopenharmony_ci if (!stateManagerPtr) { 15799552fe9Sopenharmony_ci STANDBYSERVICE_LOGW("state manager is nullptr, cannot end eval sleep state"); 15899552fe9Sopenharmony_ci return; 15999552fe9Sopenharmony_ci } 16099552fe9Sopenharmony_ci if (curPhase_ < SleepStatePhase::END) { 16199552fe9Sopenharmony_ci if (evalResult) { 16299552fe9Sopenharmony_ci TransitToPhaseInner(curPhase_, curPhase_ + 1); 16399552fe9Sopenharmony_ci } 16499552fe9Sopenharmony_ci SetPhaseTransitOrRepeatedTask(); 16599552fe9Sopenharmony_ci return; 16699552fe9Sopenharmony_ci } 16799552fe9Sopenharmony_ci if (!evalResult && isRepeatedDetection_) { 16899552fe9Sopenharmony_ci stateManagerPtr->TransitToState(StandbyState::WORKING); 16999552fe9Sopenharmony_ci } 17099552fe9Sopenharmony_ci isRepeatedDetection_ = false; 17199552fe9Sopenharmony_ci} 17299552fe9Sopenharmony_ci 17399552fe9Sopenharmony_civoid SleepState::SetPhaseTransitOrRepeatedTask() 17499552fe9Sopenharmony_ci{ 17599552fe9Sopenharmony_ci curPhase_ += 1; 17699552fe9Sopenharmony_ci if (curPhase_ < SleepStatePhase::END) { 17799552fe9Sopenharmony_ci handler_->PostTask([sleepState = shared_from_this()]() { 17899552fe9Sopenharmony_ci sleepState->TransitToPhase(sleepState->curPhase_, sleepState->curPhase_ + 1); 17999552fe9Sopenharmony_ci }, TRANSIT_NEXT_PHASE_INSTANT_TASK); 18099552fe9Sopenharmony_ci } else { 18199552fe9Sopenharmony_ci BaseState::ReleaseStandbyRunningLock(); 18299552fe9Sopenharmony_ci if (repeatedDetectionTimerId_ == 0 || !MiscServices::TimeServiceClient::GetInstance()-> 18399552fe9Sopenharmony_ci StartTimer(repeatedDetectionTimerId_, MiscServices::TimeServiceClient::GetInstance()-> 18499552fe9Sopenharmony_ci GetWallTimeMs() + REPEATED_MOTION_DETECTION_INTERVAL)) { 18599552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("sleep state set periodly task failed"); 18699552fe9Sopenharmony_ci } 18799552fe9Sopenharmony_ci } 18899552fe9Sopenharmony_ci} 18999552fe9Sopenharmony_ci 19099552fe9Sopenharmony_civoid SleepState::ShellDump(const std::vector<std::string>& argsInStr, std::string& result) 19199552fe9Sopenharmony_ci{ 19299552fe9Sopenharmony_ci if (argsInStr[DUMP_FIRST_PARAM] == DUMP_SIMULATE_SENSOR) { 19399552fe9Sopenharmony_ci if (argsInStr[DUMP_SECOND_PARAM] == "--repeat") { 19499552fe9Sopenharmony_ci StartPeriodlyMotionDetection(); 19599552fe9Sopenharmony_ci handler_->PostTask([sleepState = shared_from_this()]() { 19699552fe9Sopenharmony_ci STANDBYSERVICE_LOGD("after 100ms, stop sensor"); 19799552fe9Sopenharmony_ci sleepState->stateManager_.lock()->EndEvalCurrentState(false); 19899552fe9Sopenharmony_ci }, DUMP_REPEAT_DETECTION_TIMEOUT); 19999552fe9Sopenharmony_ci result += "finished start repeated sensor\n"; 20099552fe9Sopenharmony_ci } 20199552fe9Sopenharmony_ci } 20299552fe9Sopenharmony_ci} 20399552fe9Sopenharmony_ci 20499552fe9Sopenharmony_civoid SleepState::CheckScrenOffHalfHour() 20599552fe9Sopenharmony_ci{ 20699552fe9Sopenharmony_ci auto stateManagerPtr = stateManager_.lock(); 20799552fe9Sopenharmony_ci if (!stateManagerPtr) { 20899552fe9Sopenharmony_ci STANDBYSERVICE_LOGW("state manager is nullptr, cannot begin screen off half hour"); 20999552fe9Sopenharmony_ci return; 21099552fe9Sopenharmony_ci } 21199552fe9Sopenharmony_ci if (MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() - 21299552fe9Sopenharmony_ci stateManagerPtr->GetScreenOffTimeStamp() >= HALF_HOUR) { 21399552fe9Sopenharmony_ci stateManagerPtr->OnScreenOffHalfHour(true, false); 21499552fe9Sopenharmony_ci } 21599552fe9Sopenharmony_ci} 21699552fe9Sopenharmony_ci 21799552fe9Sopenharmony_cibool SleepState::IsInFinalPhase() 21899552fe9Sopenharmony_ci{ 21999552fe9Sopenharmony_ci return curPhase_ == SleepStatePhase::END; 22099552fe9Sopenharmony_ci} 22199552fe9Sopenharmony_ci} // namespace DevStandbyMgr 22299552fe9Sopenharmony_ci} // namespace OHOS