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 "sleep_state.h"
17
18 #include <cmath>
19 #include "time_service_client.h"
20
21 #include "standby_service_log.h"
22 #include "standby_config_manager.h"
23 #include "iconstraint_manager_adapter.h"
24 #include "istate_manager_adapter.h"
25 #include "time_provider.h"
26 #include "timed_task.h"
27
28 using namespace OHOS::MiscServices;
29 namespace OHOS {
30 namespace DevStandbyMgr {
31 namespace {
32 constexpr int32_t DUMP_REPEAT_DETECTION_TIMEOUT = 100;
33 }
34
SleepState(uint32_t curState,uint32_t curPhase,const std::shared_ptr<IStateManagerAdapter> & stateManager,std::shared_ptr<AppExecFwk::EventHandler> & handler)35 SleepState::SleepState(uint32_t curState, uint32_t curPhase, const std::shared_ptr<IStateManagerAdapter>&
36 stateManager, std::shared_ptr<AppExecFwk::EventHandler>& handler): BaseState(curState,
37 curPhase, stateManager, handler)
38 {
39 maintInterval_ = StandbyConfigManager::GetInstance()->GetStandbyDurationList(SLEEP_MAINT_DURATOIN);
40 nextState_ = StandbyState::MAINTENANCE;
41 }
42
Init(const std::shared_ptr<BaseState> & statePtr)43 ErrCode SleepState::Init(const std::shared_ptr<BaseState>& statePtr)
44 {
45 auto callbackTask = [statePtr]() { statePtr->StartTransitNextState(statePtr); };
46 enterStandbyTimerId_ = TimedTask::CreateTimer(false, 0, true, true, callbackTask);
47 if (enterStandbyTimerId_ == 0) {
48 STANDBYSERVICE_LOGE("%{public}s state init failed", STATE_NAME_LIST[GetCurState()].c_str());
49 return ERR_STANDBY_STATE_INIT_FAILED;
50 }
51
52 if (!StandbyConfigManager::GetInstance()->GetStandbySwitch(DETECT_MOTION_CONFIG)) {
53 return ERR_OK;
54 }
55 auto callback = [sleepState = shared_from_this()]() { sleepState->StartPeriodlyMotionDetection(); };
56 repeatedDetectionTimerId_ = TimedTask::CreateTimer(true, REPEATED_MOTION_DETECTION_INTERVAL, true, false, callback);
57 if (repeatedDetectionTimerId_ == 0) {
58 STANDBYSERVICE_LOGE("%{public}s init failed", STATE_NAME_LIST[GetCurState()].c_str());
59 return ERR_STANDBY_STATE_INIT_FAILED;
60 }
61 SetTimedTask(REPEATED_MOTION_DETECTION_TASK, repeatedDetectionTimerId_);
62 return ERR_OK;
63 }
64
StartPeriodlyMotionDetection()65 void SleepState::StartPeriodlyMotionDetection()
66 {
67 handler_->PostTask([sleepState = shared_from_this()]() {
68 sleepState->isRepeatedDetection_ = true;
69 ConstraintEvalParam params{sleepState->curState_, sleepState->curPhase_,
70 sleepState->curState_, sleepState->curPhase_};
71 params.isRepeatedDetection_ = true;
72 auto stateManagerPtr = sleepState->stateManager_.lock();
73 if (!stateManagerPtr) {
74 return;
75 }
76 stateManagerPtr->StartEvalCurrentState(params);
77 }, REPEATED_MOTION_DETECTION_TASK);
78 }
79
UnInit()80 ErrCode SleepState::UnInit()
81 {
82 BaseState::UnInit();
83 isRepeatedDetection_ = false;
84 repeatedDetectionTimerId_ = 0;
85 return ERR_OK;
86 }
87
BeginState()88 ErrCode SleepState::BeginState()
89 {
90 auto stateManagerPtr = stateManager_.lock();
91 if (!stateManagerPtr) {
92 STANDBYSERVICE_LOGE("state manager adapter is nullptr");
93 return ERR_STATE_MANAGER_IS_NULLPTR;
94 }
95 isRepeatedDetection_ = false;
96 int64_t maintIntervalTimeOut = 0;
97 if (stateManagerPtr->GetPreState() == StandbyState::MAINTENANCE) {
98 maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, false);
99 if (maintIntervalTimeOut != 0) {
100 STANDBYSERVICE_LOGI("from maintenance to sleep, maintIntervalTimeOut is " SPUBI64,
101 maintIntervalTimeOut);
102 StartStateTransitionTimer(maintIntervalTimeOut);
103 }
104 return ERR_OK;
105 }
106
107 maintIntervalIndex_ = 0;
108 curPhase_ = SleepStatePhase::SYS_RES_DEEP;
109 maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, true);
110 STANDBYSERVICE_LOGI("maintIntervalTimeOut is " SPUBI64 " ms", maintIntervalTimeOut);
111
112 handler_->PostTask([sleepState = shared_from_this()]() {
113 BaseState::AcquireStandbyRunningLock();
114 sleepState->TransitToPhase(sleepState->curPhase_, sleepState->curPhase_ + 1);
115 }, TRANSIT_NEXT_PHASE_INSTANT_TASK);
116 StartStateTransitionTimer(maintIntervalTimeOut);
117 CheckScrenOffHalfHour();
118 return ERR_OK;
119 }
120
TryToEnterNextPhase(const std::shared_ptr<IStateManagerAdapter> & stateManagerPtr,int32_t retryTimeOut)121 void SleepState::TryToEnterNextPhase(const std::shared_ptr<IStateManagerAdapter>& stateManagerPtr,
122 int32_t retryTimeOut)
123 {
124 if (stateManagerPtr->IsEvalution()) {
125 STANDBYSERVICE_LOGW("state is in evalution, postpone to enter next phase");
126 handler_->PostTask([sleepState = shared_from_this(), stateManagerPtr, retryTimeOut]() {
127 sleepState->TryToEnterNextPhase(stateManagerPtr, retryTimeOut);
128 }, TRANSIT_NEXT_PHASE_INSTANT_TASK, retryTimeOut);
129 } else if (curPhase_ < SleepStatePhase::END) {
130 TransitToPhase(curPhase_, curPhase_ + 1);
131 }
132 }
133
EndState()134 ErrCode SleepState::EndState()
135 {
136 StopTimedTask(TRANSIT_NEXT_STATE_TIMED_TASK);
137 StopTimedTask(REPEATED_MOTION_DETECTION_TASK);
138 handler_->RemoveTask(TRANSIT_NEXT_STATE_TIMED_TASK);
139 handler_->RemoveTask(TRANSIT_NEXT_PHASE_INSTANT_TASK);
140 handler_->RemoveTask(REPEATED_MOTION_DETECTION_TASK);
141 return ERR_OK;
142 }
143
CheckTransitionValid(uint32_t nextState)144 bool SleepState::CheckTransitionValid(uint32_t nextState)
145 {
146 if (nextState == StandbyState::NAP) {
147 STANDBYSERVICE_LOGE("can not transit from sleep to nap");
148 return false;
149 }
150 return true;
151 }
152
EndEvalCurrentState(bool evalResult)153 void SleepState::EndEvalCurrentState(bool evalResult)
154 {
155 auto stateManagerPtr = stateManager_.lock();
156 if (!stateManagerPtr) {
157 STANDBYSERVICE_LOGW("state manager is nullptr, cannot end eval sleep state");
158 return;
159 }
160 if (curPhase_ < SleepStatePhase::END) {
161 if (evalResult) {
162 TransitToPhaseInner(curPhase_, curPhase_ + 1);
163 }
164 SetPhaseTransitOrRepeatedTask();
165 return;
166 }
167 if (!evalResult && isRepeatedDetection_) {
168 stateManagerPtr->TransitToState(StandbyState::WORKING);
169 }
170 isRepeatedDetection_ = false;
171 }
172
SetPhaseTransitOrRepeatedTask()173 void SleepState::SetPhaseTransitOrRepeatedTask()
174 {
175 curPhase_ += 1;
176 if (curPhase_ < SleepStatePhase::END) {
177 handler_->PostTask([sleepState = shared_from_this()]() {
178 sleepState->TransitToPhase(sleepState->curPhase_, sleepState->curPhase_ + 1);
179 }, TRANSIT_NEXT_PHASE_INSTANT_TASK);
180 } else {
181 BaseState::ReleaseStandbyRunningLock();
182 if (repeatedDetectionTimerId_ == 0 || !MiscServices::TimeServiceClient::GetInstance()->
183 StartTimer(repeatedDetectionTimerId_, MiscServices::TimeServiceClient::GetInstance()->
184 GetWallTimeMs() + REPEATED_MOTION_DETECTION_INTERVAL)) {
185 STANDBYSERVICE_LOGE("sleep state set periodly task failed");
186 }
187 }
188 }
189
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)190 void SleepState::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
191 {
192 if (argsInStr[DUMP_FIRST_PARAM] == DUMP_SIMULATE_SENSOR) {
193 if (argsInStr[DUMP_SECOND_PARAM] == "--repeat") {
194 StartPeriodlyMotionDetection();
195 handler_->PostTask([sleepState = shared_from_this()]() {
196 STANDBYSERVICE_LOGD("after 100ms, stop sensor");
197 sleepState->stateManager_.lock()->EndEvalCurrentState(false);
198 }, DUMP_REPEAT_DETECTION_TIMEOUT);
199 result += "finished start repeated sensor\n";
200 }
201 }
202 }
203
CheckScrenOffHalfHour()204 void SleepState::CheckScrenOffHalfHour()
205 {
206 auto stateManagerPtr = stateManager_.lock();
207 if (!stateManagerPtr) {
208 STANDBYSERVICE_LOGW("state manager is nullptr, cannot begin screen off half hour");
209 return;
210 }
211 if (MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() -
212 stateManagerPtr->GetScreenOffTimeStamp() >= HALF_HOUR) {
213 stateManagerPtr->OnScreenOffHalfHour(true, false);
214 }
215 }
216
IsInFinalPhase()217 bool SleepState::IsInFinalPhase()
218 {
219 return curPhase_ == SleepStatePhase::END;
220 }
221 } // namespace DevStandbyMgr
222 } // namespace OHOS