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