199552fe9Sopenharmony_ci/*
299552fe9Sopenharmony_ci * Copyright (c) 2023 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 "nap_state.h"
1799552fe9Sopenharmony_ci
1899552fe9Sopenharmony_ci#include "time_service_client.h"
1999552fe9Sopenharmony_ci
2099552fe9Sopenharmony_ci#include "standby_service_log.h"
2199552fe9Sopenharmony_ci#include "standby_config_manager.h"
2299552fe9Sopenharmony_ci#include "iconstraint_manager_adapter.h"
2399552fe9Sopenharmony_ci#include "istate_manager_adapter.h"
2499552fe9Sopenharmony_ci#include "time_provider.h"
2599552fe9Sopenharmony_ci
2699552fe9Sopenharmony_cinamespace OHOS {
2799552fe9Sopenharmony_cinamespace DevStandbyMgr {
2899552fe9Sopenharmony_ciNapState::NapState(uint32_t curState, uint32_t curPhase, const std::shared_ptr<IStateManagerAdapter>&
2999552fe9Sopenharmony_ci    stateManager, std::shared_ptr<AppExecFwk::EventHandler>& handler): BaseState(curState, curPhase,
3099552fe9Sopenharmony_ci    stateManager, handler)
3199552fe9Sopenharmony_ci{
3299552fe9Sopenharmony_ci    maintInterval_ = StandbyConfigManager::GetInstance()->GetStandbyDurationList(NAP_MAINT_DURATION);
3399552fe9Sopenharmony_ci    nextState_ = StandbyState::NAP;
3499552fe9Sopenharmony_ci}
3599552fe9Sopenharmony_ci
3699552fe9Sopenharmony_ciErrCode NapState::BeginState()
3799552fe9Sopenharmony_ci{
3899552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
3999552fe9Sopenharmony_ci    if (!stateManagerPtr) {
4099552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("state manager adapter is nullptr");
4199552fe9Sopenharmony_ci        return ERR_STATE_MANAGER_IS_NULLPTR;
4299552fe9Sopenharmony_ci    }
4399552fe9Sopenharmony_ci
4499552fe9Sopenharmony_ci    if (stateManagerPtr->GetPreState() == StandbyState::MAINTENANCE) {
4599552fe9Sopenharmony_ci        nextState_ = StandbyState::MAINTENANCE;
4699552fe9Sopenharmony_ci        int64_t maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, false);
4799552fe9Sopenharmony_ci        STANDBYSERVICE_LOGI("after " SPUBI64 " ms, enter maintenance state", maintIntervalTimeOut);
4899552fe9Sopenharmony_ci
4999552fe9Sopenharmony_ci        if (maintIntervalTimeOut != 0) {
5099552fe9Sopenharmony_ci            StartStateTransitionTimer(maintIntervalTimeOut);
5199552fe9Sopenharmony_ci        }
5299552fe9Sopenharmony_ci        return ERR_OK;
5399552fe9Sopenharmony_ci    }
5499552fe9Sopenharmony_ci
5599552fe9Sopenharmony_ci    maintIntervalIndex_ = 0;
5699552fe9Sopenharmony_ci    curPhase_ = NapStatePhase::CONNECTION;
5799552fe9Sopenharmony_ci    if (StandbyConfigManager::GetInstance()->GetStandbySwitch(SLEEP_SWITCH)) {
5899552fe9Sopenharmony_ci        nextState_ = StandbyState::SLEEP;
5999552fe9Sopenharmony_ci        int64_t napTimeOut = std::min(TimeConstant::MSEC_PER_SEC * StandbyConfigManager::GetInstance()->
6099552fe9Sopenharmony_ci            GetStandbyParam(NAP_TIMEOUT), TimeProvider::GetNapTimeOut());
6199552fe9Sopenharmony_ci        STANDBYSERVICE_LOGI("napTimeOut is " SPUBI64 " ms", napTimeOut);
6299552fe9Sopenharmony_ci        StartStateTransitionTimer(napTimeOut);
6399552fe9Sopenharmony_ci    }
6499552fe9Sopenharmony_ci    handler_->PostTask([napState = shared_from_this()]() {
6599552fe9Sopenharmony_ci        BaseState::AcquireStandbyRunningLock();
6699552fe9Sopenharmony_ci        napState->TransitToPhase(napState->curPhase_, napState->curPhase_ + 1);
6799552fe9Sopenharmony_ci        }, TRANSIT_NEXT_PHASE_INSTANT_TASK);
6899552fe9Sopenharmony_ci    return ERR_OK;
6999552fe9Sopenharmony_ci}
7099552fe9Sopenharmony_ci
7199552fe9Sopenharmony_ciErrCode NapState::EndState()
7299552fe9Sopenharmony_ci{
7399552fe9Sopenharmony_ci    StopTimedTask(TRANSIT_NEXT_STATE_TIMED_TASK);
7499552fe9Sopenharmony_ci    handler_->RemoveTask(TRANSIT_NEXT_STATE_TIMED_TASK);
7599552fe9Sopenharmony_ci    handler_->RemoveTask(TRANSIT_NEXT_PHASE_INSTANT_TASK);
7699552fe9Sopenharmony_ci    return ERR_OK;
7799552fe9Sopenharmony_ci}
7899552fe9Sopenharmony_ci
7999552fe9Sopenharmony_cibool NapState::CheckTransitionValid(uint32_t nextState)
8099552fe9Sopenharmony_ci{
8199552fe9Sopenharmony_ci    return true;
8299552fe9Sopenharmony_ci}
8399552fe9Sopenharmony_ci
8499552fe9Sopenharmony_civoid NapState::EndEvalCurrentState(bool evalResult)
8599552fe9Sopenharmony_ci{
8699552fe9Sopenharmony_ci    if (curPhase_ == NapStatePhase::END) {
8799552fe9Sopenharmony_ci        HandleEvalResToSleepState(evalResult);
8899552fe9Sopenharmony_ci        return;
8999552fe9Sopenharmony_ci    }
9099552fe9Sopenharmony_ci    SetPhaseTransitTask(evalResult);
9199552fe9Sopenharmony_ci}
9299552fe9Sopenharmony_ci
9399552fe9Sopenharmony_civoid NapState::SetPhaseTransitTask(bool evalResult)
9499552fe9Sopenharmony_ci{
9599552fe9Sopenharmony_ci    if (evalResult) {
9699552fe9Sopenharmony_ci        TransitToPhaseInner(curPhase_, curPhase_ + 1);
9799552fe9Sopenharmony_ci    }
9899552fe9Sopenharmony_ci    curPhase_ += 1;
9999552fe9Sopenharmony_ci    if (curPhase_ < NapStatePhase::END) {
10099552fe9Sopenharmony_ci        handler_->PostTask([napState = shared_from_this()]() {
10199552fe9Sopenharmony_ci            napState->TransitToPhase(napState->curPhase_, napState->curPhase_ + 1);
10299552fe9Sopenharmony_ci            }, TRANSIT_NEXT_PHASE_INSTANT_TASK);
10399552fe9Sopenharmony_ci    } else {
10499552fe9Sopenharmony_ci        BaseState::ReleaseStandbyRunningLock();
10599552fe9Sopenharmony_ci    }
10699552fe9Sopenharmony_ci}
10799552fe9Sopenharmony_ci
10899552fe9Sopenharmony_civoid NapState::HandleEvalResToSleepState(bool evalResult)
10999552fe9Sopenharmony_ci{
11099552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
11199552fe9Sopenharmony_ci    if (!stateManagerPtr) {
11299552fe9Sopenharmony_ci        return;
11399552fe9Sopenharmony_ci    }
11499552fe9Sopenharmony_ci    if (!evalResult) {
11599552fe9Sopenharmony_ci        stateManagerPtr->TransitToState(StandbyState::WORKING);
11699552fe9Sopenharmony_ci    } else if (nextState_ != StandbyState::NAP) {
11799552fe9Sopenharmony_ci        stateManagerPtr->TransitToStateInner(StandbyState::SLEEP);
11899552fe9Sopenharmony_ci    }
11999552fe9Sopenharmony_ci}
12099552fe9Sopenharmony_ci
12199552fe9Sopenharmony_civoid NapState::OnStateBlocked()
12299552fe9Sopenharmony_ci{
12399552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("constraint evalution failed, block current state");
12499552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
12599552fe9Sopenharmony_ci    if (!stateManagerPtr) {
12699552fe9Sopenharmony_ci        return;
12799552fe9Sopenharmony_ci    }
12899552fe9Sopenharmony_ci    int64_t maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, true);
12999552fe9Sopenharmony_ci    if (maintIntervalTimeOut > 0) {
13099552fe9Sopenharmony_ci        nextState_ = StandbyState::MAINTENANCE;
13199552fe9Sopenharmony_ci        StartStateTransitionTimer(maintIntervalTimeOut);
13299552fe9Sopenharmony_ci    }
13399552fe9Sopenharmony_ci    BaseState::ReleaseStandbyRunningLock();
13499552fe9Sopenharmony_ci}
13599552fe9Sopenharmony_ci
13699552fe9Sopenharmony_cibool NapState::IsInFinalPhase()
13799552fe9Sopenharmony_ci{
13899552fe9Sopenharmony_ci    return curPhase_ == NapStatePhase::END;
13999552fe9Sopenharmony_ci}
14099552fe9Sopenharmony_ci}  // namespace DevStandbyMgr
14199552fe9Sopenharmony_ci}  // namespace OHOS