199552fe9Sopenharmony_ci/*
299552fe9Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
399552fe9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
499552fe9Sopenharmony_ci * you may not use this file except in compliance with the License.
599552fe9Sopenharmony_ci * You may obtain a copy of the License at
699552fe9Sopenharmony_ci *
799552fe9Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
899552fe9Sopenharmony_ci *
999552fe9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1099552fe9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1199552fe9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1299552fe9Sopenharmony_ci * See the License for the specific language governing permissions and
1399552fe9Sopenharmony_ci * limitations under the License.
1499552fe9Sopenharmony_ci */
1599552fe9Sopenharmony_ci
1699552fe9Sopenharmony_ci#include "base_state.h"
1799552fe9Sopenharmony_ci
1899552fe9Sopenharmony_ci#include "time_service_client.h"
1999552fe9Sopenharmony_ci
2099552fe9Sopenharmony_ci#include "standby_messsage.h"
2199552fe9Sopenharmony_ci#include "standby_service_log.h"
2299552fe9Sopenharmony_ci#include "standby_config_manager.h"
2399552fe9Sopenharmony_ci
2499552fe9Sopenharmony_ci#include "istate_manager_adapter.h"
2599552fe9Sopenharmony_ci#include "timed_task.h"
2699552fe9Sopenharmony_ci#include "time_provider.h"
2799552fe9Sopenharmony_ci#include "standby_service_impl.h"
2899552fe9Sopenharmony_ci#include "standby_config_manager.h"
2999552fe9Sopenharmony_ci
3099552fe9Sopenharmony_ciusing namespace OHOS::MiscServices;
3199552fe9Sopenharmony_cinamespace OHOS {
3299552fe9Sopenharmony_cinamespace DevStandbyMgr {
3399552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE
3499552fe9Sopenharmony_cistd::shared_ptr<PowerMgr::RunningLock> BaseState::standbyRunningLock_ = nullptr;
3599552fe9Sopenharmony_ciconst int32_t RUNNINGLOCK_TIMEOUT = 5000;
3699552fe9Sopenharmony_ci#endif
3799552fe9Sopenharmony_cibool BaseState::runningLockStatus_ = false;
3899552fe9Sopenharmony_ci
3999552fe9Sopenharmony_ciErrCode BaseState::Init(const std::shared_ptr<BaseState>& statePtr)
4099552fe9Sopenharmony_ci{
4199552fe9Sopenharmony_ci    auto callbackTask = [statePtr]() { statePtr->StartTransitNextState(statePtr); };
4299552fe9Sopenharmony_ci    enterStandbyTimerId_ = TimedTask::CreateTimer(false, 0, true, false, callbackTask);
4399552fe9Sopenharmony_ci    if (enterStandbyTimerId_ == 0) {
4499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("%{public}s state init failed", STATE_NAME_LIST[GetCurState()].c_str());
4599552fe9Sopenharmony_ci        return ERR_STANDBY_STATE_INIT_FAILED;
4699552fe9Sopenharmony_ci    }
4799552fe9Sopenharmony_ci    return ERR_OK;
4899552fe9Sopenharmony_ci}
4999552fe9Sopenharmony_ci
5099552fe9Sopenharmony_ciErrCode BaseState::UnInit()
5199552fe9Sopenharmony_ci{
5299552fe9Sopenharmony_ci    DestroyAllTimedTask();
5399552fe9Sopenharmony_ci    enterStandbyTimerId_ = 0;
5499552fe9Sopenharmony_ci    return ERR_OK;
5599552fe9Sopenharmony_ci}
5699552fe9Sopenharmony_ci
5799552fe9Sopenharmony_ciuint32_t BaseState::GetCurState()
5899552fe9Sopenharmony_ci{
5999552fe9Sopenharmony_ci    return curState_;
6099552fe9Sopenharmony_ci}
6199552fe9Sopenharmony_ci
6299552fe9Sopenharmony_ciuint32_t BaseState::GetCurInnerPhase()
6399552fe9Sopenharmony_ci{
6499552fe9Sopenharmony_ci    return curPhase_;
6599552fe9Sopenharmony_ci}
6699552fe9Sopenharmony_ci
6799552fe9Sopenharmony_civoid BaseState::StartTransitNextState(const std::shared_ptr<BaseState>& statePtr)
6899552fe9Sopenharmony_ci{
6999552fe9Sopenharmony_ci    handler_->PostTask([statePtr]() {
7099552fe9Sopenharmony_ci        STANDBYSERVICE_LOGD("due to timeout, try to enter %{public}s state from %{public}s",
7199552fe9Sopenharmony_ci            STATE_NAME_LIST[statePtr->nextState_].c_str(), STATE_NAME_LIST[statePtr->curState_].c_str());
7299552fe9Sopenharmony_ci        BaseState::AcquireStandbyRunningLock();
7399552fe9Sopenharmony_ci        auto stateManagerPtr = statePtr->stateManager_.lock();
7499552fe9Sopenharmony_ci        if (!stateManagerPtr) {
7599552fe9Sopenharmony_ci            STANDBYSERVICE_LOGW("state manager is nullptr, can not transit to next state");
7699552fe9Sopenharmony_ci            BaseState::ReleaseStandbyRunningLock();
7799552fe9Sopenharmony_ci            return;
7899552fe9Sopenharmony_ci        }
7999552fe9Sopenharmony_ci        if (stateManagerPtr->IsEvalution()) {
8099552fe9Sopenharmony_ci            STANDBYSERVICE_LOGW("state is in evalution, stop evalution and enter next state");
8199552fe9Sopenharmony_ci            stateManagerPtr->StopEvalution();
8299552fe9Sopenharmony_ci        }
8399552fe9Sopenharmony_ci        if (stateManagerPtr->TransitToState(statePtr->nextState_) != ERR_OK) {
8499552fe9Sopenharmony_ci            STANDBYSERVICE_LOGW("can not transit to state %{public}d, block current state", statePtr->nextState_);
8599552fe9Sopenharmony_ci            stateManagerPtr->BlockCurrentState();
8699552fe9Sopenharmony_ci            BaseState::ReleaseStandbyRunningLock();
8799552fe9Sopenharmony_ci        }
8899552fe9Sopenharmony_ci        }, TRANSIT_NEXT_STATE_TIMED_TASK);
8999552fe9Sopenharmony_ci}
9099552fe9Sopenharmony_ci
9199552fe9Sopenharmony_civoid BaseState::TransitToPhase(uint32_t curPhase, uint32_t nextPhase)
9299552fe9Sopenharmony_ci{
9399552fe9Sopenharmony_ci    ConstraintEvalParam params{curState_, curPhase, curState_, nextPhase};
9499552fe9Sopenharmony_ci    stateManager_.lock()->StartEvalCurrentState(params);
9599552fe9Sopenharmony_ci}
9699552fe9Sopenharmony_ci
9799552fe9Sopenharmony_civoid BaseState::TransitToPhaseInner(uint32_t prePhase, uint32_t curPhase)
9899552fe9Sopenharmony_ci{
9999552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
10099552fe9Sopenharmony_ci    if (!stateManagerPtr) {
10199552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("state manager is nullptr, can not implement function to enter next phase");
10299552fe9Sopenharmony_ci        return;
10399552fe9Sopenharmony_ci    }
10499552fe9Sopenharmony_ci    StandbyMessage message(StandbyMessageType::PHASE_TRANSIT);
10599552fe9Sopenharmony_ci    message.want_ = AAFwk::Want{};
10699552fe9Sopenharmony_ci    message.want_->SetParam(CURRENT_STATE, static_cast<int32_t>(curState_));
10799552fe9Sopenharmony_ci    message.want_->SetParam(PREVIOUS_PHASE, static_cast<int32_t>(prePhase));
10899552fe9Sopenharmony_ci    message.want_->SetParam(CURRENT_PHASE, static_cast<int32_t>(curPhase));
10999552fe9Sopenharmony_ci    StandbyServiceImpl::GetInstance()->DispatchEvent(message);
11099552fe9Sopenharmony_ci    STANDBYSERVICE_LOGI("phase transit succeed, phase form %{public}d to %{public}d",
11199552fe9Sopenharmony_ci        static_cast<int32_t>(prePhase), static_cast<int32_t>(curPhase));
11299552fe9Sopenharmony_ci}
11399552fe9Sopenharmony_ci
11499552fe9Sopenharmony_cibool BaseState::IsInFinalPhase()
11599552fe9Sopenharmony_ci{
11699552fe9Sopenharmony_ci    return true;
11799552fe9Sopenharmony_ci}
11899552fe9Sopenharmony_ci
11999552fe9Sopenharmony_civoid BaseState::OnStateBlocked()
12099552fe9Sopenharmony_ci{}
12199552fe9Sopenharmony_ci
12299552fe9Sopenharmony_civoid BaseState::SetTimedTask(const std::string& timedTaskName, uint64_t timedTaskId)
12399552fe9Sopenharmony_ci{
12499552fe9Sopenharmony_ci    if (auto iter = timedTaskMap_.find(timedTaskName); iter == timedTaskMap_.end()) {
12599552fe9Sopenharmony_ci        timedTaskMap_.emplace(timedTaskName, timedTaskId);
12699552fe9Sopenharmony_ci    } else {
12799552fe9Sopenharmony_ci        iter->second = timedTaskId;
12899552fe9Sopenharmony_ci    }
12999552fe9Sopenharmony_ci}
13099552fe9Sopenharmony_ci
13199552fe9Sopenharmony_ciErrCode BaseState::StartStateTransitionTimer(int64_t triggerTime)
13299552fe9Sopenharmony_ci{
13399552fe9Sopenharmony_ci    if (enterStandbyTimerId_ == 0 || !MiscServices::TimeServiceClient::GetInstance()->
13499552fe9Sopenharmony_ci        StartTimer(enterStandbyTimerId_, MiscServices::TimeServiceClient::GetInstance()->
13599552fe9Sopenharmony_ci        GetWallTimeMs() + triggerTime)) {
13699552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("%{public}s state set timed task failed", STATE_NAME_LIST[nextState_].c_str());
13799552fe9Sopenharmony_ci        return ERR_STANDBY_TIMER_SERVICE_ERROR;
13899552fe9Sopenharmony_ci    }
13999552fe9Sopenharmony_ci
14099552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("StartStateTransitionTimer by id=" SPUBI64 ", triggerTime=" SPUBI64,
14199552fe9Sopenharmony_ci        enterStandbyTimerId_, triggerTime);
14299552fe9Sopenharmony_ci    SetTimedTask(TRANSIT_NEXT_STATE_TIMED_TASK, enterStandbyTimerId_);
14399552fe9Sopenharmony_ci    return ERR_OK;
14499552fe9Sopenharmony_ci}
14599552fe9Sopenharmony_ci
14699552fe9Sopenharmony_ciErrCode BaseState::StopTimedTask(const std::string& timedTaskName)
14799552fe9Sopenharmony_ci{
14899552fe9Sopenharmony_ci    if (auto iter = timedTaskMap_.find(timedTaskName); iter == timedTaskMap_.end()) {
14999552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("timedTask %{public}s not exist", timedTaskName.c_str());
15099552fe9Sopenharmony_ci        return ERR_STANDBY_TIMERID_NOT_EXIST;
15199552fe9Sopenharmony_ci    } else if (iter->second > 0) {
15299552fe9Sopenharmony_ci        MiscServices::TimeServiceClient::GetInstance()->StopTimer(iter->second);
15399552fe9Sopenharmony_ci    }
15499552fe9Sopenharmony_ci
15599552fe9Sopenharmony_ci    return ERR_OK;
15699552fe9Sopenharmony_ci}
15799552fe9Sopenharmony_ci
15899552fe9Sopenharmony_civoid BaseState::DestroyAllTimedTask()
15999552fe9Sopenharmony_ci{
16099552fe9Sopenharmony_ci    for (auto& [timeTaskName, timerId] : timedTaskMap_) {
16199552fe9Sopenharmony_ci        handler_->RemoveTask(timeTaskName);
16299552fe9Sopenharmony_ci        if (timerId > 0) {
16399552fe9Sopenharmony_ci            TimeServiceClient::GetInstance()->StopTimer(timerId);
16499552fe9Sopenharmony_ci            TimeServiceClient::GetInstance()->DestroyTimer(timerId);
16599552fe9Sopenharmony_ci        }
16699552fe9Sopenharmony_ci    }
16799552fe9Sopenharmony_ci    timedTaskMap_.clear();
16899552fe9Sopenharmony_ci}
16999552fe9Sopenharmony_ci
17099552fe9Sopenharmony_civoid BaseState::InitRunningLock()
17199552fe9Sopenharmony_ci{
17299552fe9Sopenharmony_ci    runningLockStatus_ = false;
17399552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE
17499552fe9Sopenharmony_ci    standbyRunningLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
17599552fe9Sopenharmony_ci        "StandbyRunningLock", PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND);
17699552fe9Sopenharmony_ci#endif
17799552fe9Sopenharmony_ci}
17899552fe9Sopenharmony_ci
17999552fe9Sopenharmony_civoid BaseState::AcquireStandbyRunningLock()
18099552fe9Sopenharmony_ci{
18199552fe9Sopenharmony_ci    if (runningLockStatus_) {
18299552fe9Sopenharmony_ci        return;
18399552fe9Sopenharmony_ci    }
18499552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE
18599552fe9Sopenharmony_ci    if (standbyRunningLock_ == nullptr) {
18699552fe9Sopenharmony_ci        standbyRunningLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
18799552fe9Sopenharmony_ci            "StandbyRunningLock", PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND);
18899552fe9Sopenharmony_ci    }
18999552fe9Sopenharmony_ci    if (standbyRunningLock_ != nullptr) {
19099552fe9Sopenharmony_ci        standbyRunningLock_->Lock(RUNNINGLOCK_TIMEOUT);
19199552fe9Sopenharmony_ci    }
19299552fe9Sopenharmony_ci#endif
19399552fe9Sopenharmony_ci    runningLockStatus_ = true;
19499552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("acquire standby running lock, status is %{public}d", runningLockStatus_);
19599552fe9Sopenharmony_ci}
19699552fe9Sopenharmony_ci
19799552fe9Sopenharmony_civoid BaseState::ReleaseStandbyRunningLock()
19899552fe9Sopenharmony_ci{
19999552fe9Sopenharmony_ci    if (!runningLockStatus_) {
20099552fe9Sopenharmony_ci        return;
20199552fe9Sopenharmony_ci    }
20299552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE
20399552fe9Sopenharmony_ci    if (standbyRunningLock_ == nullptr) {
20499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("standbyRunningLock_ is nullptr");
20599552fe9Sopenharmony_ci    } else {
20699552fe9Sopenharmony_ci        standbyRunningLock_->UnLock();
20799552fe9Sopenharmony_ci    }
20899552fe9Sopenharmony_ci#endif
20999552fe9Sopenharmony_ci    runningLockStatus_ = false;
21099552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("release standby running lock, status is %{public}d", runningLockStatus_);
21199552fe9Sopenharmony_ci}
21299552fe9Sopenharmony_ci
21399552fe9Sopenharmony_civoid BaseState::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
21499552fe9Sopenharmony_ci{
21599552fe9Sopenharmony_ci    return;
21699552fe9Sopenharmony_ci}
21799552fe9Sopenharmony_ci
21899552fe9Sopenharmony_ciint64_t StateWithMaint::CalculateMaintTimeOut(const std::shared_ptr<IStateManagerAdapter>& stateManagerPtr,
21999552fe9Sopenharmony_ci    bool isFirstInterval)
22099552fe9Sopenharmony_ci{
22199552fe9Sopenharmony_ci    int64_t maintIntervalTimeOut {0};
22299552fe9Sopenharmony_ci    auto mainIntervalSize = static_cast<int32_t>(maintInterval_.size());
22399552fe9Sopenharmony_ci    if (mainIntervalSize <= 0) {
22499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("maintenance interval config error, can not enter maintence state");
22599552fe9Sopenharmony_ci        return 0;
22699552fe9Sopenharmony_ci    }
22799552fe9Sopenharmony_ci    if (isFirstInterval) {
22899552fe9Sopenharmony_ci        maintIntervalTimeOut = maintInterval_[maintIntervalIndex_];
22999552fe9Sopenharmony_ci    } else {
23099552fe9Sopenharmony_ci        maintIntervalIndex_ = std::min(maintIntervalIndex_ + 1, mainIntervalSize - 1);
23199552fe9Sopenharmony_ci        maintIntervalTimeOut =  maintInterval_[maintIntervalIndex_];
23299552fe9Sopenharmony_ci    }
23399552fe9Sopenharmony_ci    int64_t timeDiff {0};
23499552fe9Sopenharmony_ci    if (TimeProvider::GetCondition(maintIntervalTimeOut) == ConditionType::NIGHT_STANDBY &&
23599552fe9Sopenharmony_ci        TimeProvider::TimeDiffToDayNightSwitch(timeDiff)) {
23699552fe9Sopenharmony_ci        maintIntervalTimeOut *= TimeConstant::MSEC_PER_SEC;
23799552fe9Sopenharmony_ci        maintIntervalTimeOut += timeDiff;
23899552fe9Sopenharmony_ci        return maintIntervalTimeOut;
23999552fe9Sopenharmony_ci    }
24099552fe9Sopenharmony_ci    maintIntervalTimeOut *= TimeConstant::MSEC_PER_SEC;
24199552fe9Sopenharmony_ci    return maintIntervalTimeOut;
24299552fe9Sopenharmony_ci}
24399552fe9Sopenharmony_ci}  // namespace DevStandbyMgr
24499552fe9Sopenharmony_ci}  // namespace OHOS