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