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