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