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 "time_provider.h" 1799552fe9Sopenharmony_ci 1899552fe9Sopenharmony_ci#include <random> 1999552fe9Sopenharmony_ci#include "time_service_client.h" 2099552fe9Sopenharmony_ci#include "timed_task.h" 2199552fe9Sopenharmony_ci#include "standby_service_log.h" 2299552fe9Sopenharmony_ci#include "standby_config_manager.h" 2399552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE 2499552fe9Sopenharmony_ci#include "power_mode_info.h" 2599552fe9Sopenharmony_ci#include "power_mgr_client.h" 2699552fe9Sopenharmony_ci#endif 2799552fe9Sopenharmony_ci 2899552fe9Sopenharmony_cinamespace OHOS { 2999552fe9Sopenharmony_cinamespace DevStandbyMgr { 3099552fe9Sopenharmony_cinamespace { 3199552fe9Sopenharmony_ci constexpr int32_t NIGHT_ENTRANCE_HOUR = 23; 3299552fe9Sopenharmony_ci constexpr int32_t NIGHT_ENTRANCE_MIN = 45; 3399552fe9Sopenharmony_ci constexpr int32_t DAY_ENTRANCE_HOUR = 6; 3499552fe9Sopenharmony_ci constexpr int32_t DAY_ENTRANCE_MIN = 0; 3599552fe9Sopenharmony_ci constexpr int32_t TWENTY_MIN_ENTRANCE_MIN = 20; 3699552fe9Sopenharmony_ci constexpr int32_t QUARTER_MIN_ENTRANCE_MIN = 15; 3799552fe9Sopenharmony_ci constexpr int32_t TEN_MIN_ENTRANCE_MIN = 10; 3899552fe9Sopenharmony_ci constexpr int32_t NIGHT_TWENTY_TWO_CLOCK = 22; 3999552fe9Sopenharmony_ci constexpr int32_t NIGHT_TWENTY_THREE_CLOCK = 23; 4099552fe9Sopenharmony_ci constexpr int32_t NIGHT_FIVE_CLOCK = 5; 4199552fe9Sopenharmony_ci constexpr int32_t THREE_QUARTERS = 45; 4299552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE 4399552fe9Sopenharmony_ci constexpr int32_t SAVE_MODE_ENTRANCE_MIN = 1; 4499552fe9Sopenharmony_ci#endif 4599552fe9Sopenharmony_ci} 4699552fe9Sopenharmony_ci 4799552fe9Sopenharmony_cibool TimeProvider::ConvertTimeStampToLocalTime(int64_t curTimeStamp, struct tm& curLocalTime) 4899552fe9Sopenharmony_ci{ 4999552fe9Sopenharmony_ci auto res = localtime_r(&curTimeStamp, &curLocalTime); 5099552fe9Sopenharmony_ci if (res == nullptr) { 5199552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("localtime_r failed, can not get valid local time"); 5299552fe9Sopenharmony_ci return false; 5399552fe9Sopenharmony_ci } 5499552fe9Sopenharmony_ci return true; 5599552fe9Sopenharmony_ci} 5699552fe9Sopenharmony_ci 5799552fe9Sopenharmony_ciuint32_t TimeProvider::GetCondition(int64_t afterNextSeconds) 5899552fe9Sopenharmony_ci{ 5999552fe9Sopenharmony_ci int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC; 6099552fe9Sopenharmony_ci struct tm curLocalTime {}; 6199552fe9Sopenharmony_ci curSecTimeStamp += afterNextSeconds; 6299552fe9Sopenharmony_ci if (!ConvertTimeStampToLocalTime(curSecTimeStamp, curLocalTime)) { 6399552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("convert time stamp to local time failed"); 6499552fe9Sopenharmony_ci return ConditionType::DAY_STANDBY; 6599552fe9Sopenharmony_ci } 6699552fe9Sopenharmony_ci STANDBYSERVICE_LOGD("current local time info: %{public}02d:%{public}02d:%{public}02d", curLocalTime.tm_hour, 6799552fe9Sopenharmony_ci curLocalTime.tm_min, curLocalTime.tm_sec); 6899552fe9Sopenharmony_ci if ((curLocalTime.tm_hour < NIGHT_ENTRANCE_HOUR || curLocalTime.tm_min < NIGHT_ENTRANCE_MIN) && 6999552fe9Sopenharmony_ci (curLocalTime.tm_hour >= DAY_ENTRANCE_HOUR)) { 7099552fe9Sopenharmony_ci return ConditionType::DAY_STANDBY; 7199552fe9Sopenharmony_ci } 7299552fe9Sopenharmony_ci return ConditionType::NIGHT_STANDBY; 7399552fe9Sopenharmony_ci} 7499552fe9Sopenharmony_ci 7599552fe9Sopenharmony_cibool TimeProvider::TimeDiffToDayNightSwitch(int64_t& timeDiff) 7699552fe9Sopenharmony_ci{ 7799552fe9Sopenharmony_ci int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC; 7899552fe9Sopenharmony_ci bool res {false}; 7999552fe9Sopenharmony_ci STANDBYSERVICE_LOGD("condition is %{public}u", GetCondition()); 8099552fe9Sopenharmony_ci if (GetCondition() == ConditionType::NIGHT_STANDBY) { 8199552fe9Sopenharmony_ci res = DiffToFixedClock(curSecTimeStamp, DAY_ENTRANCE_HOUR, DAY_ENTRANCE_MIN, timeDiff); 8299552fe9Sopenharmony_ci } else { 8399552fe9Sopenharmony_ci res = DiffToFixedClock(curSecTimeStamp, NIGHT_ENTRANCE_HOUR, NIGHT_ENTRANCE_MIN, timeDiff); 8499552fe9Sopenharmony_ci } 8599552fe9Sopenharmony_ci return res; 8699552fe9Sopenharmony_ci} 8799552fe9Sopenharmony_ci 8899552fe9Sopenharmony_cibool TimeProvider::DiffToFixedClock(int64_t curTimeStamp, int32_t tmHour, int32_t tmMin, int64_t& timeDiff) 8999552fe9Sopenharmony_ci{ 9099552fe9Sopenharmony_ci struct tm curUTCTime {}; 9199552fe9Sopenharmony_ci auto res = gmtime_r(&curTimeStamp, &curUTCTime); 9299552fe9Sopenharmony_ci if (res == nullptr) { 9399552fe9Sopenharmony_ci STANDBYSERVICE_LOGE("gmtime_r failed, can not get valid utc time"); 9499552fe9Sopenharmony_ci return false; 9599552fe9Sopenharmony_ci } 9699552fe9Sopenharmony_ci STANDBYSERVICE_LOGD("current utc time info: %{public}02d:%{public}02d:%{public}02d", curUTCTime.tm_hour, 9799552fe9Sopenharmony_ci curUTCTime.tm_min, curUTCTime.tm_sec); 9899552fe9Sopenharmony_ci struct tm targetUTCTime = curUTCTime; 9999552fe9Sopenharmony_ci targetUTCTime.tm_hour = tmHour; 10099552fe9Sopenharmony_ci targetUTCTime.tm_min = tmMin; 10199552fe9Sopenharmony_ci targetUTCTime.tm_sec = 0; 10299552fe9Sopenharmony_ci STANDBYSERVICE_LOGD("target utc time info: %{public}02d:%{public}02d:%{public}02d", targetUTCTime.tm_hour, 10399552fe9Sopenharmony_ci targetUTCTime.tm_min, targetUTCTime.tm_sec); 10499552fe9Sopenharmony_ci timeDiff = std::mktime(&targetUTCTime) - curTimeStamp; 10599552fe9Sopenharmony_ci if (timeDiff < 0) { 10699552fe9Sopenharmony_ci timeDiff += SEC_PER_DAY; 10799552fe9Sopenharmony_ci } 10899552fe9Sopenharmony_ci timeDiff = timeDiff * MSEC_PER_SEC; 10999552fe9Sopenharmony_ci return true; 11099552fe9Sopenharmony_ci} 11199552fe9Sopenharmony_ci 11299552fe9Sopenharmony_ciint64_t TimeProvider::GetNapTimeOut() 11399552fe9Sopenharmony_ci{ 11499552fe9Sopenharmony_ci int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC; 11599552fe9Sopenharmony_ci int32_t napTimeOut = TWENTY_MIN_ENTRANCE_MIN; 11699552fe9Sopenharmony_ci struct tm curLocalTime {}; 11799552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE 11899552fe9Sopenharmony_ci if (IsPowerSaveMode()) { 11999552fe9Sopenharmony_ci return SAVE_MODE_ENTRANCE_MIN * MSEC_PER_MIN; 12099552fe9Sopenharmony_ci } 12199552fe9Sopenharmony_ci#endif 12299552fe9Sopenharmony_ci if (!ConvertTimeStampToLocalTime(curSecTimeStamp, curLocalTime)) { 12399552fe9Sopenharmony_ci return napTimeOut * MSEC_PER_MIN; 12499552fe9Sopenharmony_ci } 12599552fe9Sopenharmony_ci if (curLocalTime.tm_hour == NIGHT_TWENTY_TWO_CLOCK) { 12699552fe9Sopenharmony_ci napTimeOut = QUARTER_MIN_ENTRANCE_MIN; 12799552fe9Sopenharmony_ci } else if (curLocalTime.tm_hour == NIGHT_TWENTY_THREE_CLOCK && curLocalTime.tm_min < THREE_QUARTERS) { 12899552fe9Sopenharmony_ci napTimeOut = QUARTER_MIN_ENTRANCE_MIN; 12999552fe9Sopenharmony_ci } else if (curLocalTime.tm_hour >= NIGHT_TWENTY_THREE_CLOCK || curLocalTime.tm_hour < NIGHT_FIVE_CLOCK || 13099552fe9Sopenharmony_ci (curLocalTime.tm_hour == NIGHT_FIVE_CLOCK && curLocalTime.tm_min < THREE_QUARTERS)) { 13199552fe9Sopenharmony_ci napTimeOut = TEN_MIN_ENTRANCE_MIN; 13299552fe9Sopenharmony_ci } 13399552fe9Sopenharmony_ci return napTimeOut * MSEC_PER_MIN; 13499552fe9Sopenharmony_ci} 13599552fe9Sopenharmony_ci 13699552fe9Sopenharmony_ci#ifdef STANDBY_POWER_MANAGER_ENABLE 13799552fe9Sopenharmony_cibool TimeProvider::IsPowerSaveMode() 13899552fe9Sopenharmony_ci{ 13999552fe9Sopenharmony_ci PowerMgr::PowerMode mode = PowerMgr::PowerMgrClient::GetInstance().GetDeviceMode(); 14099552fe9Sopenharmony_ci return (mode == PowerMgr::PowerMode::POWER_SAVE_MODE || mode == PowerMgr::PowerMode::EXTREME_POWER_SAVE_MODE); 14199552fe9Sopenharmony_ci} 14299552fe9Sopenharmony_ci#endif 14399552fe9Sopenharmony_ci 14499552fe9Sopenharmony_ciint32_t TimeProvider::GetRandomDelay(int32_t low, int32_t high) 14599552fe9Sopenharmony_ci{ 14699552fe9Sopenharmony_ci std::random_device rd; 14799552fe9Sopenharmony_ci std::mt19937 gen(rd()); 14899552fe9Sopenharmony_ci std::uniform_int_distribution<> dist(low, high); 14999552fe9Sopenharmony_ci return dist(gen); 15099552fe9Sopenharmony_ci} 15199552fe9Sopenharmony_ci} // namespace DevStandbyMgr 15299552fe9Sopenharmony_ci} // namespace OHOS 15399552fe9Sopenharmony_ci 154