1 /*
2 * Copyright (c) 2023-2024 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 "base_state.h"
17
18 #include "time_service_client.h"
19
20 #include "standby_messsage.h"
21 #include "standby_service_log.h"
22 #include "standby_config_manager.h"
23
24 #include "istate_manager_adapter.h"
25 #include "timed_task.h"
26 #include "time_provider.h"
27 #include "standby_service_impl.h"
28 #include "standby_config_manager.h"
29
30 using namespace OHOS::MiscServices;
31 namespace OHOS {
32 namespace DevStandbyMgr {
33 #ifdef STANDBY_POWER_MANAGER_ENABLE
34 std::shared_ptr<PowerMgr::RunningLock> BaseState::standbyRunningLock_ = nullptr;
35 const int32_t RUNNINGLOCK_TIMEOUT = 5000;
36 #endif
37 bool BaseState::runningLockStatus_ = false;
38
Init(const std::shared_ptr<BaseState> & statePtr)39 ErrCode BaseState::Init(const std::shared_ptr<BaseState>& statePtr)
40 {
41 auto callbackTask = [statePtr]() { statePtr->StartTransitNextState(statePtr); };
42 enterStandbyTimerId_ = TimedTask::CreateTimer(false, 0, true, false, callbackTask);
43 if (enterStandbyTimerId_ == 0) {
44 STANDBYSERVICE_LOGE("%{public}s state init failed", STATE_NAME_LIST[GetCurState()].c_str());
45 return ERR_STANDBY_STATE_INIT_FAILED;
46 }
47 return ERR_OK;
48 }
49
UnInit()50 ErrCode BaseState::UnInit()
51 {
52 DestroyAllTimedTask();
53 enterStandbyTimerId_ = 0;
54 return ERR_OK;
55 }
56
GetCurState()57 uint32_t BaseState::GetCurState()
58 {
59 return curState_;
60 }
61
GetCurInnerPhase()62 uint32_t BaseState::GetCurInnerPhase()
63 {
64 return curPhase_;
65 }
66
StartTransitNextState(const std::shared_ptr<BaseState> & statePtr)67 void BaseState::StartTransitNextState(const std::shared_ptr<BaseState>& statePtr)
68 {
69 handler_->PostTask([statePtr]() {
70 STANDBYSERVICE_LOGD("due to timeout, try to enter %{public}s state from %{public}s",
71 STATE_NAME_LIST[statePtr->nextState_].c_str(), STATE_NAME_LIST[statePtr->curState_].c_str());
72 BaseState::AcquireStandbyRunningLock();
73 auto stateManagerPtr = statePtr->stateManager_.lock();
74 if (!stateManagerPtr) {
75 STANDBYSERVICE_LOGW("state manager is nullptr, can not transit to next state");
76 BaseState::ReleaseStandbyRunningLock();
77 return;
78 }
79 if (stateManagerPtr->IsEvalution()) {
80 STANDBYSERVICE_LOGW("state is in evalution, stop evalution and enter next state");
81 stateManagerPtr->StopEvalution();
82 }
83 if (stateManagerPtr->TransitToState(statePtr->nextState_) != ERR_OK) {
84 STANDBYSERVICE_LOGW("can not transit to state %{public}d, block current state", statePtr->nextState_);
85 stateManagerPtr->BlockCurrentState();
86 BaseState::ReleaseStandbyRunningLock();
87 }
88 }, TRANSIT_NEXT_STATE_TIMED_TASK);
89 }
90
TransitToPhase(uint32_t curPhase,uint32_t nextPhase)91 void BaseState::TransitToPhase(uint32_t curPhase, uint32_t nextPhase)
92 {
93 ConstraintEvalParam params{curState_, curPhase, curState_, nextPhase};
94 stateManager_.lock()->StartEvalCurrentState(params);
95 }
96
TransitToPhaseInner(uint32_t prePhase,uint32_t curPhase)97 void BaseState::TransitToPhaseInner(uint32_t prePhase, uint32_t curPhase)
98 {
99 auto stateManagerPtr = stateManager_.lock();
100 if (!stateManagerPtr) {
101 STANDBYSERVICE_LOGW("state manager is nullptr, can not implement function to enter next phase");
102 return;
103 }
104 StandbyMessage message(StandbyMessageType::PHASE_TRANSIT);
105 message.want_ = AAFwk::Want{};
106 message.want_->SetParam(CURRENT_STATE, static_cast<int32_t>(curState_));
107 message.want_->SetParam(PREVIOUS_PHASE, static_cast<int32_t>(prePhase));
108 message.want_->SetParam(CURRENT_PHASE, static_cast<int32_t>(curPhase));
109 StandbyServiceImpl::GetInstance()->DispatchEvent(message);
110 STANDBYSERVICE_LOGI("phase transit succeed, phase form %{public}d to %{public}d",
111 static_cast<int32_t>(prePhase), static_cast<int32_t>(curPhase));
112 }
113
IsInFinalPhase()114 bool BaseState::IsInFinalPhase()
115 {
116 return true;
117 }
118
OnStateBlocked()119 void BaseState::OnStateBlocked()
120 {}
121
SetTimedTask(const std::string & timedTaskName,uint64_t timedTaskId)122 void BaseState::SetTimedTask(const std::string& timedTaskName, uint64_t timedTaskId)
123 {
124 if (auto iter = timedTaskMap_.find(timedTaskName); iter == timedTaskMap_.end()) {
125 timedTaskMap_.emplace(timedTaskName, timedTaskId);
126 } else {
127 iter->second = timedTaskId;
128 }
129 }
130
StartStateTransitionTimer(int64_t triggerTime)131 ErrCode BaseState::StartStateTransitionTimer(int64_t triggerTime)
132 {
133 if (enterStandbyTimerId_ == 0 || !MiscServices::TimeServiceClient::GetInstance()->
134 StartTimer(enterStandbyTimerId_, MiscServices::TimeServiceClient::GetInstance()->
135 GetWallTimeMs() + triggerTime)) {
136 STANDBYSERVICE_LOGE("%{public}s state set timed task failed", STATE_NAME_LIST[nextState_].c_str());
137 return ERR_STANDBY_TIMER_SERVICE_ERROR;
138 }
139
140 STANDBYSERVICE_LOGD("StartStateTransitionTimer by id=" SPUBI64 ", triggerTime=" SPUBI64,
141 enterStandbyTimerId_, triggerTime);
142 SetTimedTask(TRANSIT_NEXT_STATE_TIMED_TASK, enterStandbyTimerId_);
143 return ERR_OK;
144 }
145
StopTimedTask(const std::string & timedTaskName)146 ErrCode BaseState::StopTimedTask(const std::string& timedTaskName)
147 {
148 if (auto iter = timedTaskMap_.find(timedTaskName); iter == timedTaskMap_.end()) {
149 STANDBYSERVICE_LOGW("timedTask %{public}s not exist", timedTaskName.c_str());
150 return ERR_STANDBY_TIMERID_NOT_EXIST;
151 } else if (iter->second > 0) {
152 MiscServices::TimeServiceClient::GetInstance()->StopTimer(iter->second);
153 }
154
155 return ERR_OK;
156 }
157
DestroyAllTimedTask()158 void BaseState::DestroyAllTimedTask()
159 {
160 for (auto& [timeTaskName, timerId] : timedTaskMap_) {
161 handler_->RemoveTask(timeTaskName);
162 if (timerId > 0) {
163 TimeServiceClient::GetInstance()->StopTimer(timerId);
164 TimeServiceClient::GetInstance()->DestroyTimer(timerId);
165 }
166 }
167 timedTaskMap_.clear();
168 }
169
InitRunningLock()170 void BaseState::InitRunningLock()
171 {
172 runningLockStatus_ = false;
173 #ifdef STANDBY_POWER_MANAGER_ENABLE
174 standbyRunningLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
175 "StandbyRunningLock", PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND);
176 #endif
177 }
178
AcquireStandbyRunningLock()179 void BaseState::AcquireStandbyRunningLock()
180 {
181 if (runningLockStatus_) {
182 return;
183 }
184 #ifdef STANDBY_POWER_MANAGER_ENABLE
185 if (standbyRunningLock_ == nullptr) {
186 standbyRunningLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
187 "StandbyRunningLock", PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND);
188 }
189 if (standbyRunningLock_ != nullptr) {
190 standbyRunningLock_->Lock(RUNNINGLOCK_TIMEOUT);
191 }
192 #endif
193 runningLockStatus_ = true;
194 STANDBYSERVICE_LOGD("acquire standby running lock, status is %{public}d", runningLockStatus_);
195 }
196
ReleaseStandbyRunningLock()197 void BaseState::ReleaseStandbyRunningLock()
198 {
199 if (!runningLockStatus_) {
200 return;
201 }
202 #ifdef STANDBY_POWER_MANAGER_ENABLE
203 if (standbyRunningLock_ == nullptr) {
204 STANDBYSERVICE_LOGE("standbyRunningLock_ is nullptr");
205 } else {
206 standbyRunningLock_->UnLock();
207 }
208 #endif
209 runningLockStatus_ = false;
210 STANDBYSERVICE_LOGD("release standby running lock, status is %{public}d", runningLockStatus_);
211 }
212
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)213 void BaseState::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
214 {
215 return;
216 }
217
CalculateMaintTimeOut(const std::shared_ptr<IStateManagerAdapter> & stateManagerPtr,bool isFirstInterval)218 int64_t StateWithMaint::CalculateMaintTimeOut(const std::shared_ptr<IStateManagerAdapter>& stateManagerPtr,
219 bool isFirstInterval)
220 {
221 int64_t maintIntervalTimeOut {0};
222 auto mainIntervalSize = static_cast<int32_t>(maintInterval_.size());
223 if (mainIntervalSize <= 0) {
224 STANDBYSERVICE_LOGE("maintenance interval config error, can not enter maintence state");
225 return 0;
226 }
227 if (isFirstInterval) {
228 maintIntervalTimeOut = maintInterval_[maintIntervalIndex_];
229 } else {
230 maintIntervalIndex_ = std::min(maintIntervalIndex_ + 1, mainIntervalSize - 1);
231 maintIntervalTimeOut = maintInterval_[maintIntervalIndex_];
232 }
233 int64_t timeDiff {0};
234 if (TimeProvider::GetCondition(maintIntervalTimeOut) == ConditionType::NIGHT_STANDBY &&
235 TimeProvider::TimeDiffToDayNightSwitch(timeDiff)) {
236 maintIntervalTimeOut *= TimeConstant::MSEC_PER_SEC;
237 maintIntervalTimeOut += timeDiff;
238 return maintIntervalTimeOut;
239 }
240 maintIntervalTimeOut *= TimeConstant::MSEC_PER_SEC;
241 return maintIntervalTimeOut;
242 }
243 } // namespace DevStandbyMgr
244 } // namespace OHOS