• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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