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