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