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