• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
28 namespace OHOS {
29 namespace DevStandbyMgr {
30 namespace {
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     constexpr int32_t SUPER_POWER_SAVING_MODE = 650;
43 #ifdef STANDBY_POWER_MANAGER_ENABLE
44     constexpr int32_t SAVE_MODE_ENTRANCE_MIN = 1;
45 #endif
46 }
47 
ConvertTimeStampToLocalTime(int64_t curTimeStamp,struct tm & curLocalTime)48 bool TimeProvider::ConvertTimeStampToLocalTime(int64_t curTimeStamp, struct tm& curLocalTime)
49 {
50     auto res = localtime_r(&curTimeStamp, &curLocalTime);
51     if (res == nullptr) {
52         STANDBYSERVICE_LOGE("localtime_r failed, can not get valid local time");
53         return false;
54     }
55     return true;
56 }
57 
GetCondition(int64_t afterNextSeconds)58 uint32_t TimeProvider::GetCondition(int64_t afterNextSeconds)
59 {
60     int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC;
61     struct tm curLocalTime {};
62     curSecTimeStamp += afterNextSeconds;
63     if (!ConvertTimeStampToLocalTime(curSecTimeStamp, curLocalTime)) {
64         STANDBYSERVICE_LOGE("convert time stamp to local time failed");
65         return ConditionType::DAY_STANDBY;
66     }
67     STANDBYSERVICE_LOGD("current local time info: %{public}02d:%{public}02d:%{public}02d", curLocalTime.tm_hour,
68         curLocalTime.tm_min, curLocalTime.tm_sec);
69     if ((curLocalTime.tm_hour < NIGHT_ENTRANCE_HOUR || curLocalTime.tm_min < NIGHT_ENTRANCE_MIN) &&
70         (curLocalTime.tm_hour >= DAY_ENTRANCE_HOUR)) {
71         return ConditionType::DAY_STANDBY;
72     }
73     return ConditionType::NIGHT_STANDBY;
74 }
75 
TimeDiffToDayNightSwitch(int64_t & timeDiff)76 bool TimeProvider::TimeDiffToDayNightSwitch(int64_t& timeDiff)
77 {
78     int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC;
79     bool res {false};
80     STANDBYSERVICE_LOGD("condition is %{public}u", GetCondition());
81     if (GetCondition() == ConditionType::NIGHT_STANDBY) {
82         res = DiffToFixedClock(curSecTimeStamp, DAY_ENTRANCE_HOUR, DAY_ENTRANCE_MIN, timeDiff);
83     } else {
84         res = DiffToFixedClock(curSecTimeStamp, NIGHT_ENTRANCE_HOUR, NIGHT_ENTRANCE_MIN, timeDiff);
85     }
86     return res;
87 }
88 
DiffToFixedClock(int64_t curTimeStamp,int32_t tmHour,int32_t tmMin,int64_t & timeDiff)89 bool TimeProvider::DiffToFixedClock(int64_t curTimeStamp, int32_t tmHour, int32_t tmMin, int64_t& timeDiff)
90 {
91     struct tm curUTCTime {};
92     auto res = gmtime_r(&curTimeStamp, &curUTCTime);
93     if (res == nullptr) {
94         STANDBYSERVICE_LOGE("gmtime_r failed, can not get valid utc time");
95         return false;
96     }
97     STANDBYSERVICE_LOGD("current utc time info: %{public}02d:%{public}02d:%{public}02d", curUTCTime.tm_hour,
98         curUTCTime.tm_min, curUTCTime.tm_sec);
99     struct tm targetUTCTime = curUTCTime;
100     targetUTCTime.tm_hour = tmHour;
101     targetUTCTime.tm_min = tmMin;
102     targetUTCTime.tm_sec = 0;
103     STANDBYSERVICE_LOGD("target utc time info: %{public}02d:%{public}02d:%{public}02d", targetUTCTime.tm_hour,
104         targetUTCTime.tm_min, targetUTCTime.tm_sec);
105     timeDiff = std::mktime(&targetUTCTime) - curTimeStamp;
106     if (timeDiff < 0) {
107         timeDiff += SEC_PER_DAY;
108     }
109     timeDiff = timeDiff * MSEC_PER_SEC;
110     return true;
111 }
112 
GetNapTimeOut()113 int64_t TimeProvider::GetNapTimeOut()
114 {
115     int64_t curSecTimeStamp = MiscServices::TimeServiceClient::GetInstance()->GetWallTimeMs() / MSEC_PER_SEC;
116     int32_t napTimeOut = TWENTY_MIN_ENTRANCE_MIN;
117     struct tm curLocalTime {};
118 #ifdef STANDBY_POWER_MANAGER_ENABLE
119     if (IsPowerSaveMode()) {
120         return SAVE_MODE_ENTRANCE_MIN * MSEC_PER_MIN;
121     }
122 #endif
123     if (!ConvertTimeStampToLocalTime(curSecTimeStamp, curLocalTime)) {
124         return napTimeOut * MSEC_PER_MIN;
125     }
126     if (curLocalTime.tm_hour == NIGHT_TWENTY_TWO_CLOCK) {
127         napTimeOut = QUARTER_MIN_ENTRANCE_MIN;
128     } else if (curLocalTime.tm_hour == NIGHT_TWENTY_THREE_CLOCK && curLocalTime.tm_min < THREE_QUARTERS) {
129         napTimeOut = QUARTER_MIN_ENTRANCE_MIN;
130     } else if (curLocalTime.tm_hour >= NIGHT_TWENTY_THREE_CLOCK || curLocalTime.tm_hour < NIGHT_FIVE_CLOCK ||
131         (curLocalTime.tm_hour == NIGHT_FIVE_CLOCK && curLocalTime.tm_min < THREE_QUARTERS)) {
132         napTimeOut = TEN_MIN_ENTRANCE_MIN;
133     }
134     return napTimeOut * MSEC_PER_MIN;
135 }
136 
137 #ifdef STANDBY_POWER_MANAGER_ENABLE
IsPowerSaveMode()138 bool TimeProvider::IsPowerSaveMode()
139 {
140     PowerMgr::PowerMode mode = PowerMgr::PowerMgrClient::GetInstance().GetDeviceMode();
141     return (mode == PowerMgr::PowerMode::POWER_SAVE_MODE
142         || mode == PowerMgr::PowerMode::EXTREME_POWER_SAVE_MODE
143         || static_cast<int32_t>(mode) == SUPER_POWER_SAVING_MODE);
144 }
145 #endif
146 
GetRandomDelay(int32_t low,int32_t high)147 int32_t TimeProvider::GetRandomDelay(int32_t low, int32_t high)
148 {
149     std::random_device rd;
150     std::mt19937 gen(rd());
151     std::uniform_int_distribution<> dist(low, high);
152     return dist(gen);
153 }
154 
GetCurrentDate()155 int32_t TimeProvider::GetCurrentDate()
156 {
157     time_t now = std::time(0);
158     tm* local_time = gmtime(&now);
159     if (local_time == nullptr) {
160         STANDBYSERVICE_LOGE("get local time failed");
161         return 0;
162     }
163     return local_time->tm_mday;
164 }
165 }  // namespace DevStandbyMgr
166 }  // namespace OHOS
167 
168