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