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 "state_manager_adapter.h"
17 #ifdef STANDBY_POWER_MANAGER_ENABLE
18 #include "power_mgr_client.h"
19 #endif
20 #include "base_state.h"
21 #include "common_event_support.h"
22 #include "dark_state.h"
23 #include "maintenance_state.h"
24 #include "nap_state.h"
25 #include "sleep_state.h"
26 #include "standby_config_manager.h"
27 #include "standby_service_impl.h"
28 #include "standby_service_log.h"
29 #include "standby_state_subscriber.h"
30 #include "working_state.h"
31 
32 namespace OHOS {
33 namespace DevStandbyMgr {
Init()34 bool StateManagerAdapter::Init()
35 {
36     auto StandbyServiceImpl = StandbyServiceImpl::GetInstance();
37     handler_ = StandbyServiceImpl->GetHandler();
38     constraintManager_ = StandbyServiceImpl->GetConstraintManager();
39     strategyManager_ = StandbyServiceImpl->GetStrategyManager();
40     auto stateManager = StandbyServiceImpl->GetStateManager();
41     BaseState::InitRunningLock();
42     workingStatePtr_ = std::make_shared<WorkingState>(StandbyState::WORKING, 0, stateManager, handler_);
43     darkStatePtr_ = std::make_shared<DarkState>(StandbyState::DARK, 0, stateManager, handler_);
44     napStatePtr_ = std::make_shared<NapState>(StandbyState::NAP, 0, stateManager, handler_);
45     maintStatePtr_ = std::make_shared<MaintenanceState>(StandbyState::MAINTENANCE, 0, stateManager, handler_);
46     sleepStatePtr_ = std::make_shared<SleepState>(StandbyState::SLEEP, 0, stateManager, handler_);
47     indexToState_ = {
48         workingStatePtr_, darkStatePtr_, napStatePtr_, maintStatePtr_, sleepStatePtr_
49     };
50     auto callbackTask = [this]() { this->OnScreenOffHalfHour(true, false); };
51     scrOffHalfHourTimerId_ = TimedTask::CreateTimer(false, 0, true, false, callbackTask);
52     if (scrOffHalfHourTimerId_ == 0) {
53         STANDBYSERVICE_LOGE("timer of screen off half hour is nullptr");
54     }
55     for (const auto& statePtr : indexToState_) {
56         if (statePtr->Init(statePtr) != ERR_OK) {
57             return false;
58         }
59     }
60     curStatePtr_ = workingStatePtr_;
61     preStatePtr_ = curStatePtr_;
62     #ifdef STANDBY_POWER_MANAGER_ENABLE
63     isScreenOn_ = PowerMgr::PowerMgrClient::GetInstance().IsScreenOn();
64     #endif
65     if (curStatePtr_->BeginState() != ERR_OK) {
66         return false;
67     }
68     SendNotification(preStatePtr_->GetCurState(), true);
69     STANDBYSERVICE_LOGI("state manager plugin initialization succeed");
70     return true;
71 }
72 
UnInit()73 bool StateManagerAdapter::UnInit()
74 {
75     TransitToState(StandbyState::WORKING);
76     curStatePtr_->EndState();
77     for (auto& statePtr : indexToState_) {
78         statePtr->UnInit();
79         statePtr.reset();
80     }
81     if (scrOffHalfHourTimerId_ > 0) {
82         MiscServices::TimeServiceClient::GetInstance()->StopTimer(scrOffHalfHourTimerId_);
83         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(scrOffHalfHourTimerId_);
84     }
85     BaseState::ReleaseStandbyRunningLock();
86     return true;
87 }
88 
HandleEvent(const StandbyMessage & message)89 void StateManagerAdapter::HandleEvent(const StandbyMessage& message)
90 {
91     if (message.eventId_ == StandbyMessageType::COMMON_EVENT) {
92         HandleCommonEvent(message);
93     } else if (message.eventId_ == StandbyMessageType::RES_CTRL_CONDITION_CHANGED) {
94         SendNotification(curStatePtr_->GetCurState(), false);
95     }
96 }
97 
HandleCommonEvent(const StandbyMessage & message)98 void StateManagerAdapter::HandleCommonEvent(const StandbyMessage& message)
99 {
100     HandleScrOffHalfHour(message);
101     HandleOpenCloseLid(message);
102     HandleScreenStatus(message);
103     if (message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON ||
104         message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING ||
105         message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED) {
106         TransitToState(StandbyState::WORKING);
107     }
108     if (curStatePtr_->GetCurState() != StandbyState::WORKING) {
109         return;
110     }
111     if (CheckEnterDarkState(message)) {
112         TransitToState(StandbyState::DARK);
113     }
114 }
115 
HandleScreenStatus(const StandbyMessage & message)116 void StateManagerAdapter::HandleScreenStatus(const StandbyMessage& message)
117 {
118     if (message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
119         isScreenOn_ = true;
120     } else if (message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
121         isScreenOn_ = false;
122     }
123 }
124 
CheckEnterDarkState(const StandbyMessage & message)125 bool StateManagerAdapter::CheckEnterDarkState(const StandbyMessage& message)
126 {
127     if (isScreenOn_) {
128         return false;
129     }
130     if (message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF ||
131         message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING ||
132         message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED) {
133         return true;
134     }
135     return true;
136 }
137 
HandleScrOffHalfHour(const StandbyMessage & message)138 void StateManagerAdapter::HandleScrOffHalfHour(const StandbyMessage& message)
139 {
140     if (scrOffHalfHourTimerId_ == 0) {
141         return;
142     }
143     if (message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
144         isScreenOn_ = false;
145         screenOffTimeStamp_ = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs();
146         MiscServices::TimeServiceClient::GetInstance()->StartTimer(scrOffHalfHourTimerId_,
147             screenOffTimeStamp_ + HALF_HOUR);
148     } else if (message.action_ == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
149         isScreenOn_ = true;
150         MiscServices::TimeServiceClient::GetInstance()->StopTimer(scrOffHalfHourTimerId_);
151     }
152 }
153 
HandleOpenCloseLid(const StandbyMessage & message)154 void StateManagerAdapter::HandleOpenCloseLid(const StandbyMessage& message)
155 {
156     if (message.action_ == LID_OPEN) {
157         TransitToState(StandbyState::WORKING);
158     } else if (message.action_ == LID_CLOSE && (curStatePtr_->GetCurState() != StandbyState::SLEEP &&
159         curStatePtr_->GetCurState() != StandbyState::MAINTENANCE)) {
160         UnblockCurrentState();
161         TransitToStateInner(StandbyState::SLEEP);
162     }
163 }
164 
GetCurState()165 uint32_t StateManagerAdapter::GetCurState()
166 {
167     return curStatePtr_->GetCurState();
168 }
169 
GetPreState()170 uint32_t StateManagerAdapter::GetPreState()
171 {
172     return preStatePtr_->GetCurState();
173 }
174 
StartEvalCurrentState(const ConstraintEvalParam & params)175 ErrCode StateManagerAdapter::StartEvalCurrentState(const ConstraintEvalParam& params)
176 {
177     STANDBYSERVICE_LOGI("start evalution current state, current: %{public}u, %{public}u, next:"\
178         " %{public}u, %{public}u", params.curState_, params.curPhase_, params.nextState_,
179         params.nextPhase_);
180     isEvalution_ = true;
181     constraintManager_->StartEvalution(params);
182     return ERR_OK;
183 }
184 
EndEvalCurrentState(bool evalResult)185 ErrCode StateManagerAdapter::EndEvalCurrentState(bool evalResult)
186 {
187     if (!isEvalution_) {
188         STANDBYSERVICE_LOGE("can not end evalution before start evalution");
189         return ERR_STANDBY_STATE_TIMING_SEQ_ERROR;
190     }
191     STANDBYSERVICE_LOGD("end evalution current state, result is %{public}d", evalResult);
192     isEvalution_ = false;
193     constraintManager_->StopEvalution();
194     curStatePtr_->EndEvalCurrentState(evalResult);
195     return ERR_OK;
196 }
197 
BlockCurrentState()198 void StateManagerAdapter::BlockCurrentState()
199 {
200     isBlocked_ = true;
201     curStatePtr_->OnStateBlocked();
202 }
203 
UnblockCurrentState()204 void StateManagerAdapter::UnblockCurrentState()
205 {
206     isBlocked_ = false;
207 }
208 
TransitToState(uint32_t nextState)209 ErrCode StateManagerAdapter::TransitToState(uint32_t nextState)
210 {
211     uint32_t curState = curStatePtr_->GetCurState();
212     if (!CheckTransitionValid(curState, nextState)) {
213         return ERR_STANDBY_STATE_TRANSITION_FAILED;
214     }
215     if (curState == nextState) {
216         UnblockCurrentState();
217     } else if (nextState == StandbyState::MAINTENANCE ||
218         curState == StandbyState::MAINTENANCE) {
219         return TransitWithMaint(nextState);
220     } else if (curState < nextState) {
221         return EnterStandby(nextState);
222     } else {
223         return ExitStandby(nextState);
224     }
225     return ERR_OK;
226 }
227 
ExitStandby(uint32_t nextState)228 ErrCode StateManagerAdapter::ExitStandby(uint32_t nextState)
229 {
230     if (isEvalution_) {
231         constraintManager_->StopEvalution();
232         isEvalution_ = false;
233     }
234     UnblockCurrentState();
235     if (scrOffHalfHourCtrl_) {
236         OnScreenOffHalfHour(false, false);
237     }
238     TransitToStateInner(nextState);
239     return ERR_OK;
240 }
241 
CheckTransitionValid(uint32_t curState,uint32_t nextState)242 bool StateManagerAdapter::CheckTransitionValid(uint32_t curState, uint32_t nextState)
243 {
244     bool ret = curStatePtr_->CheckTransitionValid(nextState);
245     if (!ret) {
246         STANDBYSERVICE_LOGE("can not transitting from now %{public}s to next %{public}s",
247             STATE_NAME_LIST[curState].c_str(), STATE_NAME_LIST[nextState].c_str());
248     }
249     return ret;
250 }
251 
EnterStandby(uint32_t nextState)252 ErrCode StateManagerAdapter::EnterStandby(uint32_t nextState)
253 {
254     if (isBlocked_) {
255         STANDBYSERVICE_LOGE("current standby state is blocked due to the previous failure of constraint");
256         return ERR_STANDBY_STATAE_BLOCKED;
257     }
258     ConstraintEvalParam params{curStatePtr_->GetCurState(), curStatePtr_->GetCurInnerPhase(), nextState, 0};
259     StartEvalCurrentState(params);
260     return ERR_OK;
261 }
262 
TransitWithMaint(uint32_t nextState)263 ErrCode StateManagerAdapter::TransitWithMaint(uint32_t nextState)
264 {
265     return TransitToStateInner(nextState);
266 }
267 
TransitToStateInner(uint32_t nextState)268 ErrCode StateManagerAdapter::TransitToStateInner(uint32_t nextState)
269 {
270     curStatePtr_->EndState();
271     preStatePtr_ = curStatePtr_;
272     curStatePtr_ = indexToState_[nextState];
273     curStatePtr_->BeginState();
274 
275     RecordStateTransition();
276     SendNotification(preStatePtr_->GetCurState(), true);
277     BaseState::ReleaseStandbyRunningLock();
278     return ERR_OK;
279 }
280 
RecordStateTransition()281 void StateManagerAdapter::RecordStateTransition()
282 {
283     auto curTimeStampMs = MiscServices::TimeServiceClient::GetInstance()->GetMonotonicTimeMs();
284     stateRecordList_.emplace_back(std::make_pair(preStatePtr_->GetCurState(),
285         curTimeStampMs));
286     if (stateRecordList_.size() > MAX_RECORD_SIZE) {
287         stateRecordList_.pop_front();
288     }
289 }
290 
StopEvalution()291 void StateManagerAdapter::StopEvalution()
292 {
293     if (isEvalution_) {
294         constraintManager_->StopEvalution();
295         isEvalution_ = false;
296     }
297 }
298 
OnScreenOffHalfHour(bool scrOffHalfHourCtrl,bool repeated)299 void StateManagerAdapter::OnScreenOffHalfHour(bool scrOffHalfHourCtrl, bool repeated)
300 {
301     handler_->PostSyncTask([this, scrOffHalfHourCtrl, repeated]() {
302         OnScreenOffHalfHourInner(scrOffHalfHourCtrl, repeated);
303         }, AppExecFwk::EventQueue::Priority::HIGH);
304 }
305 
OnScreenOffHalfHourInner(bool scrOffHalfHourCtrl,bool repeated)306 void StateManagerAdapter::OnScreenOffHalfHourInner(bool scrOffHalfHourCtrl, bool repeated)
307 {
308     uint32_t curState = curStatePtr_->GetCurState();
309     uint32_t preState = preStatePtr_->GetCurState();
310     STANDBYSERVICE_LOGD("screen off half hour, cur state is %{public}s, pre state is %{public}s",
311         STATE_NAME_LIST[curState].c_str(), STATE_NAME_LIST[preState].c_str());
312     if (scrOffHalfHourCtrl && !(curState == StandbyState::SLEEP || (preState == StandbyState::SLEEP &&
313         curState == StandbyState::MAINTENANCE))) {
314         return;
315     }
316     if (!repeated && scrOffHalfHourCtrl_ == scrOffHalfHourCtrl) {
317         return;
318     }
319     STANDBYSERVICE_LOGD("half hour ctrl status from %{public}d to %{public}d", scrOffHalfHourCtrl_, scrOffHalfHourCtrl);
320     scrOffHalfHourCtrl_ = scrOffHalfHourCtrl;
321     StandbyMessage message(StandbyMessageType::SCREEN_OFF_HALF_HOUR);
322     message.want_ = AAFwk::Want{};
323     message.want_->SetParam(SCR_OFF_HALF_HOUR_STATUS, scrOffHalfHourCtrl_);
324     StandbyServiceImpl::GetInstance()->DispatchEvent(message);
325 }
326 
SendNotification(uint32_t preState,bool needDispatchEvent)327 void StateManagerAdapter::SendNotification(uint32_t preState, bool needDispatchEvent)
328 {
329     uint32_t curState = curStatePtr_->GetCurState();
330     STANDBYSERVICE_LOGI("state transit succeed, previous is %{public}s, current is %{public}s",
331         STATE_NAME_LIST[preState].c_str(), STATE_NAME_LIST[curState].c_str());
332     if (needDispatchEvent) {
333         StandbyMessage message(StandbyMessageType::STATE_TRANSIT);
334         message.want_ = AAFwk::Want{};
335         message.want_->SetParam(PREVIOUS_STATE, static_cast<int32_t>(preState));
336         message.want_->SetParam(CURRENT_STATE, static_cast<int32_t>(curState));
337         StandbyServiceImpl::GetInstance()->DispatchEvent(message);
338     }
339     StandbyStateSubscriber::GetInstance()->ReportStandbyState(curState);
340 }
341 
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)342 void StateManagerAdapter::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
343 {
344     if (argsInStr[DUMP_FIRST_PARAM] == DUMP_DETAIL_INFO) {
345         DumpShowDetailInfo(argsInStr, result);
346         if (argsInStr[DUMP_SECOND_PARAM] == DUMP_RESET_STATE) {
347             DumpResetState(argsInStr, result);
348         }
349     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_ENTER_STATE) {
350         DumpEnterSpecifiedState(argsInStr, result);
351     } else if (argsInStr[DUMP_FIRST_PARAM] == DUMP_SIMULATE_SENSOR) {
352         DumpActivateMotion(argsInStr, result);
353     }
354     curStatePtr_->ShellDump(argsInStr, result);
355 }
356 
DumpShowDetailInfo(const std::vector<std::string> & argsInStr,std::string & result)357 void StateManagerAdapter::DumpShowDetailInfo(const std::vector<std::string>& argsInStr, std::string& result)
358 {
359     result += "isEvalution: " + std::to_string(isEvalution_) + ", isBlocking: " +
360         std::to_string(isBlocked_) + ", current state: " + STATE_NAME_LIST[
361         curStatePtr_->GetCurState()] + ", current phase: " + std::to_string(curStatePtr_->
362         GetCurInnerPhase()) + ", previous state: " + STATE_NAME_LIST[preStatePtr_->GetCurState()] +
363         ", scrOffHalfHourCtrl: " + std::to_string(scrOffHalfHourCtrl_) +
364         ", isScreenOn: " + std::to_string(isScreenOn_) + "\n";
365 
366     if (stateRecordList_.empty()) {
367         result += "\nstate record is empty\n";
368     } else {
369         result += "\nstate transition record:\n";
370     }
371 
372     for (const auto &[stateIndex, timeStamp] : stateRecordList_) {
373         result += STATE_NAME_LIST[stateIndex] + "\t" + std::to_string(timeStamp) + "\n";
374     }
375 }
376 
DumpResetState(const std::vector<std::string> & argsInStr,std::string & result)377 void StateManagerAdapter::DumpResetState(const std::vector<std::string>& argsInStr, std::string& result)
378 {
379     UnInit();
380     Init();
381     result += "\nreset state and validate debug parameter\n";
382 }
383 
DumpEnterSpecifiedState(const std::vector<std::string> & argsInStr,std::string & result)384 void StateManagerAdapter::DumpEnterSpecifiedState(const std::vector<std::string>& argsInStr, std::string& result)
385 {
386     isBlocked_ = false;
387     if (argsInStr[DUMP_THIRD_PARAM] == "false") {
388         curStatePtr_->StartTransitNextState(curStatePtr_);
389     } else {
390         auto iter =  std::find(STATE_NAME_LIST.begin(), STATE_NAME_LIST.end(), argsInStr[DUMP_SECOND_PARAM]);
391         if (iter == STATE_NAME_LIST.end()) {
392             result += "state name is not correct";
393             return;
394         }
395         TransitToStateInner(iter - STATE_NAME_LIST.begin());
396     }
397 }
398 
DumpActivateMotion(const std::vector<std::string> & argsInStr,std::string & result)399 void StateManagerAdapter::DumpActivateMotion(const std::vector<std::string>& argsInStr, std::string& result)
400 {
401     if (argsInStr[DUMP_SECOND_PARAM] == "--motion") {
402         curStatePtr_->StartTransitNextState(curStatePtr_);
403         handler_->PostTask([this]() {
404             STANDBYSERVICE_LOGD("after 3000ms, stop sensor");
405             this->EndEvalCurrentState(false);
406             }, MOTION_DETECTION_TIMEOUT);
407         result += "finished start periodly sensor\n";
408     } else if (argsInStr[DUMP_SECOND_PARAM] == "--blocked") {
409         BlockCurrentState();
410     } else if (argsInStr[DUMP_SECOND_PARAM] == "--halfhour") {
411         OnScreenOffHalfHourInner(true, true);
412     }
413 }
414 }  // namespace DevStandbyMgr
415 }  // namespace OHOS