1/* 2 * Copyright (c) 2023 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 "time_provider.h" 17 18#include <random> 19#include "time_service_client.h" 20#include "timed_task.h" 21#include "standby_service_log.h" 22#include "standby_config_manager.h" 23#ifdef STANDBY_POWER_MANAGER_ENABLE 24#include "power_mode_info.h" 25#include "power_mgr_client.h" 26#endif 27 28namespace OHOS { 29namespace DevStandbyMgr { 30namespace { 31 constexpr int32_t NIGHT_ENTRANCE_HOUR = 23; 32 constexpr int32_t NIGHT_ENTRANCE_MIN = 45; 33 constexpr int32_t DAY_ENTRANCE_HOUR = 6; 34 constexpr int32_t DAY_ENTRANCE_MIN = 0; 35 constexpr int32_t TWENTY_MIN_ENTRANCE_MIN = 20; 36 constexpr int32_t QUARTER_MIN_ENTRANCE_MIN = 15; 37 constexpr int32_t TEN_MIN_ENTRANCE_MIN = 10; 38 constexpr int32_t NIGHT_TWENTY_TWO_CLOCK = 22; 39 constexpr int32_t NIGHT_TWENTY_THREE_CLOCK = 23; 40 constexpr int32_t NIGHT_FIVE_CLOCK = 5; 41 constexpr int32_t THREE_QUARTERS = 45; 42#ifdef STANDBY_POWER_MANAGER_ENABLE 43 constexpr int32_t SAVE_MODE_ENTRANCE_MIN = 1; 44#endif 45} 46 47bool TimeProvider::ConvertTimeStampToLocalTime(int64_t curTimeStamp, struct tm& curLocalTime) 48{ 49 auto res = localtime_r(&curTimeStamp, &curLocalTime); 50 if (res == nullptr) { 51 STANDBYSERVICE_LOGE("localtime_r failed, can not get valid local time"); 52 return false; 53 } 54 return true; 55} 56 57uint32_t TimeProvider::GetCondition(int64_t afterNextSeconds) 58{ 59 int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC; 60 struct tm curLocalTime {}; 61 curSecTimeStamp += afterNextSeconds; 62 if (!ConvertTimeStampToLocalTime(curSecTimeStamp, curLocalTime)) { 63 STANDBYSERVICE_LOGE("convert time stamp to local time failed"); 64 return ConditionType::DAY_STANDBY; 65 } 66 STANDBYSERVICE_LOGD("current local time info: %{public}02d:%{public}02d:%{public}02d", curLocalTime.tm_hour, 67 curLocalTime.tm_min, curLocalTime.tm_sec); 68 if ((curLocalTime.tm_hour < NIGHT_ENTRANCE_HOUR || curLocalTime.tm_min < NIGHT_ENTRANCE_MIN) && 69 (curLocalTime.tm_hour >= DAY_ENTRANCE_HOUR)) { 70 return ConditionType::DAY_STANDBY; 71 } 72 return ConditionType::NIGHT_STANDBY; 73} 74 75bool TimeProvider::TimeDiffToDayNightSwitch(int64_t& timeDiff) 76{ 77 int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC; 78 bool res {false}; 79 STANDBYSERVICE_LOGD("condition is %{public}u", GetCondition()); 80 if (GetCondition() == ConditionType::NIGHT_STANDBY) { 81 res = DiffToFixedClock(curSecTimeStamp, DAY_ENTRANCE_HOUR, DAY_ENTRANCE_MIN, timeDiff); 82 } else { 83 res = DiffToFixedClock(curSecTimeStamp, NIGHT_ENTRANCE_HOUR, NIGHT_ENTRANCE_MIN, timeDiff); 84 } 85 return res; 86} 87 88bool TimeProvider::DiffToFixedClock(int64_t curTimeStamp, int32_t tmHour, int32_t tmMin, int64_t& timeDiff) 89{ 90 struct tm curUTCTime {}; 91 auto res = gmtime_r(&curTimeStamp, &curUTCTime); 92 if (res == nullptr) { 93 STANDBYSERVICE_LOGE("gmtime_r failed, can not get valid utc time"); 94 return false; 95 } 96 STANDBYSERVICE_LOGD("current utc time info: %{public}02d:%{public}02d:%{public}02d", curUTCTime.tm_hour, 97 curUTCTime.tm_min, curUTCTime.tm_sec); 98 struct tm targetUTCTime = curUTCTime; 99 targetUTCTime.tm_hour = tmHour; 100 targetUTCTime.tm_min = tmMin; 101 targetUTCTime.tm_sec = 0; 102 STANDBYSERVICE_LOGD("target utc time info: %{public}02d:%{public}02d:%{public}02d", targetUTCTime.tm_hour, 103 targetUTCTime.tm_min, targetUTCTime.tm_sec); 104 timeDiff = std::mktime(&targetUTCTime) - curTimeStamp; 105 if (timeDiff < 0) { 106 timeDiff += SEC_PER_DAY; 107 } 108 timeDiff = timeDiff * MSEC_PER_SEC; 109 return true; 110} 111 112int64_t TimeProvider::GetNapTimeOut() 113{ 114 int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC; 115 int32_t napTimeOut = TWENTY_MIN_ENTRANCE_MIN; 116 struct tm curLocalTime {}; 117#ifdef STANDBY_POWER_MANAGER_ENABLE 118 if (IsPowerSaveMode()) { 119 return SAVE_MODE_ENTRANCE_MIN * MSEC_PER_MIN; 120 } 121#endif 122 if (!ConvertTimeStampToLocalTime(curSecTimeStamp, curLocalTime)) { 123 return napTimeOut * MSEC_PER_MIN; 124 } 125 if (curLocalTime.tm_hour == NIGHT_TWENTY_TWO_CLOCK) { 126 napTimeOut = QUARTER_MIN_ENTRANCE_MIN; 127 } else if (curLocalTime.tm_hour == NIGHT_TWENTY_THREE_CLOCK && curLocalTime.tm_min < THREE_QUARTERS) { 128 napTimeOut = QUARTER_MIN_ENTRANCE_MIN; 129 } else if (curLocalTime.tm_hour >= NIGHT_TWENTY_THREE_CLOCK || curLocalTime.tm_hour < NIGHT_FIVE_CLOCK || 130 (curLocalTime.tm_hour == NIGHT_FIVE_CLOCK && curLocalTime.tm_min < THREE_QUARTERS)) { 131 napTimeOut = TEN_MIN_ENTRANCE_MIN; 132 } 133 return napTimeOut * MSEC_PER_MIN; 134} 135 136#ifdef STANDBY_POWER_MANAGER_ENABLE 137bool TimeProvider::IsPowerSaveMode() 138{ 139 PowerMgr::PowerMode mode = PowerMgr::PowerMgrClient::GetInstance().GetDeviceMode(); 140 return (mode == PowerMgr::PowerMode::POWER_SAVE_MODE || mode == PowerMgr::PowerMode::EXTREME_POWER_SAVE_MODE); 141} 142#endif 143 144int32_t TimeProvider::GetRandomDelay(int32_t low, int32_t high) 145{ 146 std::random_device rd; 147 std::mt19937 gen(rd()); 148 std::uniform_int_distribution<> dist(low, high); 149 return dist(gen); 150} 151} // namespace DevStandbyMgr 152} // namespace OHOS 153 154