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 "sleep_state.h"
1799552fe9Sopenharmony_ci
1899552fe9Sopenharmony_ci#include <cmath>
1999552fe9Sopenharmony_ci#include "time_service_client.h"
2099552fe9Sopenharmony_ci
2199552fe9Sopenharmony_ci#include "standby_service_log.h"
2299552fe9Sopenharmony_ci#include "standby_config_manager.h"
2399552fe9Sopenharmony_ci#include "iconstraint_manager_adapter.h"
2499552fe9Sopenharmony_ci#include "istate_manager_adapter.h"
2599552fe9Sopenharmony_ci#include "time_provider.h"
2699552fe9Sopenharmony_ci#include "timed_task.h"
2799552fe9Sopenharmony_ci
2899552fe9Sopenharmony_ciusing namespace OHOS::MiscServices;
2999552fe9Sopenharmony_cinamespace OHOS {
3099552fe9Sopenharmony_cinamespace DevStandbyMgr {
3199552fe9Sopenharmony_cinamespace {
3299552fe9Sopenharmony_ci    constexpr int32_t DUMP_REPEAT_DETECTION_TIMEOUT = 100;
3399552fe9Sopenharmony_ci}
3499552fe9Sopenharmony_ci
3599552fe9Sopenharmony_ciSleepState::SleepState(uint32_t curState, uint32_t curPhase, const std::shared_ptr<IStateManagerAdapter>&
3699552fe9Sopenharmony_ci    stateManager, std::shared_ptr<AppExecFwk::EventHandler>& handler): BaseState(curState,
3799552fe9Sopenharmony_ci    curPhase, stateManager, handler)
3899552fe9Sopenharmony_ci{
3999552fe9Sopenharmony_ci    maintInterval_ = StandbyConfigManager::GetInstance()->GetStandbyDurationList(SLEEP_MAINT_DURATOIN);
4099552fe9Sopenharmony_ci    nextState_ = StandbyState::MAINTENANCE;
4199552fe9Sopenharmony_ci}
4299552fe9Sopenharmony_ci
4399552fe9Sopenharmony_ciErrCode SleepState::Init(const std::shared_ptr<BaseState>& statePtr)
4499552fe9Sopenharmony_ci{
4599552fe9Sopenharmony_ci    auto callbackTask = [statePtr]() { statePtr->StartTransitNextState(statePtr); };
4699552fe9Sopenharmony_ci    enterStandbyTimerId_ = TimedTask::CreateTimer(false, 0, true, true, callbackTask);
4799552fe9Sopenharmony_ci    if (enterStandbyTimerId_ == 0) {
4899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("%{public}s state init failed", STATE_NAME_LIST[GetCurState()].c_str());
4999552fe9Sopenharmony_ci        return ERR_STANDBY_STATE_INIT_FAILED;
5099552fe9Sopenharmony_ci    }
5199552fe9Sopenharmony_ci
5299552fe9Sopenharmony_ci    if (!StandbyConfigManager::GetInstance()->GetStandbySwitch(DETECT_MOTION_CONFIG)) {
5399552fe9Sopenharmony_ci        return ERR_OK;
5499552fe9Sopenharmony_ci    }
5599552fe9Sopenharmony_ci    auto callback = [sleepState = shared_from_this()]() { sleepState->StartPeriodlyMotionDetection(); };
5699552fe9Sopenharmony_ci    repeatedDetectionTimerId_ = TimedTask::CreateTimer(true, REPEATED_MOTION_DETECTION_INTERVAL, true, false, callback);
5799552fe9Sopenharmony_ci    if (repeatedDetectionTimerId_ == 0) {
5899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("%{public}s init failed", STATE_NAME_LIST[GetCurState()].c_str());
5999552fe9Sopenharmony_ci        return ERR_STANDBY_STATE_INIT_FAILED;
6099552fe9Sopenharmony_ci    }
6199552fe9Sopenharmony_ci    SetTimedTask(REPEATED_MOTION_DETECTION_TASK, repeatedDetectionTimerId_);
6299552fe9Sopenharmony_ci    return ERR_OK;
6399552fe9Sopenharmony_ci}
6499552fe9Sopenharmony_ci
6599552fe9Sopenharmony_civoid SleepState::StartPeriodlyMotionDetection()
6699552fe9Sopenharmony_ci{
6799552fe9Sopenharmony_ci    handler_->PostTask([sleepState = shared_from_this()]() {
6899552fe9Sopenharmony_ci        sleepState->isRepeatedDetection_ = true;
6999552fe9Sopenharmony_ci        ConstraintEvalParam params{sleepState->curState_, sleepState->curPhase_,
7099552fe9Sopenharmony_ci            sleepState->curState_, sleepState->curPhase_};
7199552fe9Sopenharmony_ci        params.isRepeatedDetection_ = true;
7299552fe9Sopenharmony_ci        auto stateManagerPtr = sleepState->stateManager_.lock();
7399552fe9Sopenharmony_ci        if (!stateManagerPtr) {
7499552fe9Sopenharmony_ci            return;
7599552fe9Sopenharmony_ci        }
7699552fe9Sopenharmony_ci        stateManagerPtr->StartEvalCurrentState(params);
7799552fe9Sopenharmony_ci        }, REPEATED_MOTION_DETECTION_TASK);
7899552fe9Sopenharmony_ci}
7999552fe9Sopenharmony_ci
8099552fe9Sopenharmony_ciErrCode SleepState::UnInit()
8199552fe9Sopenharmony_ci{
8299552fe9Sopenharmony_ci    BaseState::UnInit();
8399552fe9Sopenharmony_ci    isRepeatedDetection_ = false;
8499552fe9Sopenharmony_ci    repeatedDetectionTimerId_ = 0;
8599552fe9Sopenharmony_ci    return ERR_OK;
8699552fe9Sopenharmony_ci}
8799552fe9Sopenharmony_ci
8899552fe9Sopenharmony_ciErrCode SleepState::BeginState()
8999552fe9Sopenharmony_ci{
9099552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
9199552fe9Sopenharmony_ci    if (!stateManagerPtr) {
9299552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("state manager adapter is nullptr");
9399552fe9Sopenharmony_ci        return ERR_STATE_MANAGER_IS_NULLPTR;
9499552fe9Sopenharmony_ci    }
9599552fe9Sopenharmony_ci    isRepeatedDetection_ = false;
9699552fe9Sopenharmony_ci    int64_t maintIntervalTimeOut = 0;
9799552fe9Sopenharmony_ci    if (stateManagerPtr->GetPreState() == StandbyState::MAINTENANCE) {
9899552fe9Sopenharmony_ci        maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, false);
9999552fe9Sopenharmony_ci        if (maintIntervalTimeOut != 0) {
10099552fe9Sopenharmony_ci            STANDBYSERVICE_LOGI("from maintenance to sleep, maintIntervalTimeOut is " SPUBI64,
10199552fe9Sopenharmony_ci                maintIntervalTimeOut);
10299552fe9Sopenharmony_ci            StartStateTransitionTimer(maintIntervalTimeOut);
10399552fe9Sopenharmony_ci        }
10499552fe9Sopenharmony_ci        return ERR_OK;
10599552fe9Sopenharmony_ci    }
10699552fe9Sopenharmony_ci
10799552fe9Sopenharmony_ci    maintIntervalIndex_ = 0;
10899552fe9Sopenharmony_ci    curPhase_ = SleepStatePhase::SYS_RES_DEEP;
10999552fe9Sopenharmony_ci    maintIntervalTimeOut = CalculateMaintTimeOut(stateManagerPtr, true);
11099552fe9Sopenharmony_ci    STANDBYSERVICE_LOGI("maintIntervalTimeOut is " SPUBI64 " ms", maintIntervalTimeOut);
11199552fe9Sopenharmony_ci
11299552fe9Sopenharmony_ci    handler_->PostTask([sleepState = shared_from_this()]() {
11399552fe9Sopenharmony_ci        BaseState::AcquireStandbyRunningLock();
11499552fe9Sopenharmony_ci        sleepState->TransitToPhase(sleepState->curPhase_, sleepState->curPhase_ + 1);
11599552fe9Sopenharmony_ci        }, TRANSIT_NEXT_PHASE_INSTANT_TASK);
11699552fe9Sopenharmony_ci    StartStateTransitionTimer(maintIntervalTimeOut);
11799552fe9Sopenharmony_ci    CheckScrenOffHalfHour();
11899552fe9Sopenharmony_ci    return ERR_OK;
11999552fe9Sopenharmony_ci}
12099552fe9Sopenharmony_ci
12199552fe9Sopenharmony_civoid SleepState::TryToEnterNextPhase(const std::shared_ptr<IStateManagerAdapter>& stateManagerPtr,
12299552fe9Sopenharmony_ci    int32_t retryTimeOut)
12399552fe9Sopenharmony_ci{
12499552fe9Sopenharmony_ci    if (stateManagerPtr->IsEvalution()) {
12599552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("state is in evalution, postpone to enter next phase");
12699552fe9Sopenharmony_ci        handler_->PostTask([sleepState = shared_from_this(), stateManagerPtr, retryTimeOut]() {
12799552fe9Sopenharmony_ci            sleepState->TryToEnterNextPhase(stateManagerPtr, retryTimeOut);
12899552fe9Sopenharmony_ci            }, TRANSIT_NEXT_PHASE_INSTANT_TASK, retryTimeOut);
12999552fe9Sopenharmony_ci    } else if (curPhase_ < SleepStatePhase::END) {
13099552fe9Sopenharmony_ci        TransitToPhase(curPhase_, curPhase_ + 1);
13199552fe9Sopenharmony_ci    }
13299552fe9Sopenharmony_ci}
13399552fe9Sopenharmony_ci
13499552fe9Sopenharmony_ciErrCode SleepState::EndState()
13599552fe9Sopenharmony_ci{
13699552fe9Sopenharmony_ci    StopTimedTask(TRANSIT_NEXT_STATE_TIMED_TASK);
13799552fe9Sopenharmony_ci    StopTimedTask(REPEATED_MOTION_DETECTION_TASK);
13899552fe9Sopenharmony_ci    handler_->RemoveTask(TRANSIT_NEXT_STATE_TIMED_TASK);
13999552fe9Sopenharmony_ci    handler_->RemoveTask(TRANSIT_NEXT_PHASE_INSTANT_TASK);
14099552fe9Sopenharmony_ci    handler_->RemoveTask(REPEATED_MOTION_DETECTION_TASK);
14199552fe9Sopenharmony_ci    return ERR_OK;
14299552fe9Sopenharmony_ci}
14399552fe9Sopenharmony_ci
14499552fe9Sopenharmony_cibool SleepState::CheckTransitionValid(uint32_t nextState)
14599552fe9Sopenharmony_ci{
14699552fe9Sopenharmony_ci    if (nextState == StandbyState::NAP) {
14799552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("can not transit from sleep to nap");
14899552fe9Sopenharmony_ci        return false;
14999552fe9Sopenharmony_ci    }
15099552fe9Sopenharmony_ci    return true;
15199552fe9Sopenharmony_ci}
15299552fe9Sopenharmony_ci
15399552fe9Sopenharmony_civoid SleepState::EndEvalCurrentState(bool evalResult)
15499552fe9Sopenharmony_ci{
15599552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
15699552fe9Sopenharmony_ci    if (!stateManagerPtr) {
15799552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("state manager is nullptr, cannot end eval sleep state");
15899552fe9Sopenharmony_ci        return;
15999552fe9Sopenharmony_ci    }
16099552fe9Sopenharmony_ci    if (curPhase_ < SleepStatePhase::END) {
16199552fe9Sopenharmony_ci        if (evalResult) {
16299552fe9Sopenharmony_ci            TransitToPhaseInner(curPhase_, curPhase_ + 1);
16399552fe9Sopenharmony_ci        }
16499552fe9Sopenharmony_ci        SetPhaseTransitOrRepeatedTask();
16599552fe9Sopenharmony_ci        return;
16699552fe9Sopenharmony_ci    }
16799552fe9Sopenharmony_ci    if (!evalResult && isRepeatedDetection_) {
16899552fe9Sopenharmony_ci        stateManagerPtr->TransitToState(StandbyState::WORKING);
16999552fe9Sopenharmony_ci    }
17099552fe9Sopenharmony_ci    isRepeatedDetection_ = false;
17199552fe9Sopenharmony_ci}
17299552fe9Sopenharmony_ci
17399552fe9Sopenharmony_civoid SleepState::SetPhaseTransitOrRepeatedTask()
17499552fe9Sopenharmony_ci{
17599552fe9Sopenharmony_ci    curPhase_ += 1;
17699552fe9Sopenharmony_ci    if (curPhase_ < SleepStatePhase::END) {
17799552fe9Sopenharmony_ci        handler_->PostTask([sleepState = shared_from_this()]() {
17899552fe9Sopenharmony_ci            sleepState->TransitToPhase(sleepState->curPhase_, sleepState->curPhase_ + 1);
17999552fe9Sopenharmony_ci            }, TRANSIT_NEXT_PHASE_INSTANT_TASK);
18099552fe9Sopenharmony_ci    } else {
18199552fe9Sopenharmony_ci        BaseState::ReleaseStandbyRunningLock();
18299552fe9Sopenharmony_ci        if (repeatedDetectionTimerId_ == 0 || !MiscServices::TimeServiceClient::GetInstance()->
18399552fe9Sopenharmony_ci            StartTimer(repeatedDetectionTimerId_, MiscServices::TimeServiceClient::GetInstance()->
18499552fe9Sopenharmony_ci            GetWallTimeMs() + REPEATED_MOTION_DETECTION_INTERVAL)) {
18599552fe9Sopenharmony_ci            STANDBYSERVICE_LOGE("sleep state set periodly task failed");
18699552fe9Sopenharmony_ci        }
18799552fe9Sopenharmony_ci    }
18899552fe9Sopenharmony_ci}
18999552fe9Sopenharmony_ci
19099552fe9Sopenharmony_civoid SleepState::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
19199552fe9Sopenharmony_ci{
19299552fe9Sopenharmony_ci    if (argsInStr[DUMP_FIRST_PARAM] == DUMP_SIMULATE_SENSOR) {
19399552fe9Sopenharmony_ci        if (argsInStr[DUMP_SECOND_PARAM] == "--repeat") {
19499552fe9Sopenharmony_ci            StartPeriodlyMotionDetection();
19599552fe9Sopenharmony_ci            handler_->PostTask([sleepState = shared_from_this()]() {
19699552fe9Sopenharmony_ci                STANDBYSERVICE_LOGD("after 100ms, stop sensor");
19799552fe9Sopenharmony_ci                sleepState->stateManager_.lock()->EndEvalCurrentState(false);
19899552fe9Sopenharmony_ci                }, DUMP_REPEAT_DETECTION_TIMEOUT);
19999552fe9Sopenharmony_ci            result += "finished start repeated sensor\n";
20099552fe9Sopenharmony_ci        }
20199552fe9Sopenharmony_ci    }
20299552fe9Sopenharmony_ci}
20399552fe9Sopenharmony_ci
20499552fe9Sopenharmony_civoid SleepState::CheckScrenOffHalfHour()
20599552fe9Sopenharmony_ci{
20699552fe9Sopenharmony_ci    auto stateManagerPtr = stateManager_.lock();
20799552fe9Sopenharmony_ci    if (!stateManagerPtr) {
20899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("state manager is nullptr, cannot begin screen off half hour");
20999552fe9Sopenharmony_ci        return;
21099552fe9Sopenharmony_ci    }
21199552fe9Sopenharmony_ci    if (MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() -
21299552fe9Sopenharmony_ci        stateManagerPtr->GetScreenOffTimeStamp() >= HALF_HOUR) {
21399552fe9Sopenharmony_ci        stateManagerPtr->OnScreenOffHalfHour(true, false);
21499552fe9Sopenharmony_ci    }
21599552fe9Sopenharmony_ci}
21699552fe9Sopenharmony_ci
21799552fe9Sopenharmony_cibool SleepState::IsInFinalPhase()
21899552fe9Sopenharmony_ci{
21999552fe9Sopenharmony_ci    return curPhase_ == SleepStatePhase::END;
22099552fe9Sopenharmony_ci}
22199552fe9Sopenharmony_ci}  // namespace DevStandbyMgr
22299552fe9Sopenharmony_ci}  // namespace OHOS