• 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 "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