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