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