1 /*
2 * Copyright (c) 2024 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_hilog.h"
17 #include "system_date_time.h"
18 #include "cj_ffi/cj_common_ffi.h"
19 #include "time_service_client.h"
20 #include "utils.h"
21 #include "parameters.h"
22
23 namespace OHOS {
24 namespace CJSystemapi {
25 namespace SystemDateTime {
26
27 using namespace MiscServices;
28 constexpr const char *TIMEZONE_KEY = "persist.time.timezone";
29 constexpr int32_t STARTUP = 0;
30 constexpr int64_t SECONDS_TO_NANO = 1000000000;
31 constexpr int64_t SECONDS_TO_MILLI = 1000;
32 constexpr int64_t NANO_TO_MILLI = SECONDS_TO_NANO / SECONDS_TO_MILLI;
33
SetTime(int64_t time)34 int SystemDateTimeImpl::SetTime(int64_t time)
35 {
36 auto innerCode = TimeServiceClient::GetInstance()->SetTimeV9(time);
37 if (innerCode != CjErrorCode::ERROR_OK) {
38 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
39 return ERROR;
40 }
41
42 return SUCCESS_CODE;
43 }
44
getCurrentTime(bool isNano)45 std::tuple<int32_t, int64_t> SystemDateTimeImpl::getCurrentTime(bool isNano)
46 {
47 int32_t innerCode;
48 int64_t time = 0;
49 if (isNano) {
50 innerCode = TimeServiceClient::GetInstance()->GetWallTimeNs(time);
51 } else {
52 innerCode = TimeServiceClient::GetInstance()->GetWallTimeMs(time);
53 }
54 if (innerCode != CjErrorCode::ERROR_OK) {
55 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
56 return {innerCode, ERROR};
57 }
58 return {SUCCESS_CODE, time};
59 }
60
getRealActiveTime(bool isNano)61 std::tuple<int32_t, int64_t> SystemDateTimeImpl::getRealActiveTime(bool isNano)
62 {
63 int32_t innerCode;
64 int64_t time = 0;
65 if (isNano) {
66 innerCode = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(time);
67 } else {
68 innerCode = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(time);
69 }
70 if (innerCode != CjErrorCode::ERROR_OK) {
71 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
72 return {innerCode, ERROR};
73 }
74 return {SUCCESS_CODE, time};
75 }
76
getRealTime(bool isNano)77 std::tuple<int32_t, int64_t> SystemDateTimeImpl::getRealTime(bool isNano)
78 {
79 int32_t innerCode;
80 int64_t time = 0;
81 if (isNano) {
82 innerCode = TimeServiceClient::GetInstance()->GetBootTimeNs(time);
83 } else {
84 innerCode = TimeServiceClient::GetInstance()->GetBootTimeMs(time);
85 }
86 if (innerCode != CjErrorCode::ERROR_OK) {
87 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
88 return {innerCode, ERROR};
89 }
90 return {SUCCESS_CODE, time};
91 }
92
GetDeviceTime(clockid_t clockId,bool isNano,int64_t & time)93 int32_t SystemDateTimeImpl::GetDeviceTime(clockid_t clockId, bool isNano, int64_t &time)
94 {
95 struct timespec tv {};
96 if (clock_gettime(clockId, &tv) < 0) {
97 TIME_HILOGE(TIME_MODULE_CLIENT, "failed clock_gettime");
98 return ERROR;
99 }
100
101 if (isNano) {
102 time = tv.tv_sec * SECONDS_TO_NANO + tv.tv_nsec;
103 } else {
104 time = tv.tv_sec * SECONDS_TO_MILLI + tv.tv_nsec / NANO_TO_MILLI;
105 }
106 return 0;
107 }
108
getTime(bool isNano)109 std::tuple<int32_t, int64_t> SystemDateTimeImpl::getTime(bool isNano)
110 {
111 int32_t innerCode;
112 int64_t time = 0;
113 innerCode = GetDeviceTime(CLOCK_REALTIME, isNano, time);
114 if (innerCode != CjErrorCode::ERROR_OK) {
115 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
116 return {innerCode, ERROR};
117 }
118 return {SUCCESS_CODE, time};
119 }
120
getUpTime(int32_t timeType,bool isNano)121 std::tuple<int32_t, int64_t> SystemDateTimeImpl::getUpTime(int32_t timeType, bool isNano)
122 {
123 int32_t innerCode;
124 int64_t time = 0;
125 if (timeType == STARTUP) {
126 innerCode = GetDeviceTime(CLOCK_BOOTTIME, isNano, time);
127 } else {
128 innerCode = GetDeviceTime(CLOCK_MONOTONIC, isNano, time);
129 }
130 if (innerCode != CjErrorCode::ERROR_OK) {
131 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
132 return {innerCode, ERROR};
133 }
134 return {SUCCESS_CODE, time};
135 }
136
SetTimeZone(char * timezone)137 int SystemDateTimeImpl::SetTimeZone(char* timezone)
138 {
139 auto innerCode = TimeServiceClient::GetInstance()->SetTimeZoneV9(timezone);
140 if (innerCode != CjErrorCode::ERROR_OK) {
141 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
142 return ERROR;
143 }
144 return SUCCESS_CODE;
145 }
146
MallocCString(const std::string & origin)147 char* MallocCString(const std::string& origin)
148 {
149 if (origin.empty()) {
150 return nullptr;
151 }
152 auto len = origin.length() + 1;
153 char* res = static_cast<char*>(malloc(sizeof(char) * len));
154 if (res == nullptr) {
155 return nullptr;
156 }
157 return std::char_traits<char>::copy(res, origin.c_str(), len);
158 }
159
GetTimezone(std::string & timezone)160 int32_t GetTimezone(std::string &timezone)
161 {
162 timezone = OHOS::system::GetParameter(TIMEZONE_KEY, "Asia/Shanghai");
163 if (timezone.empty()) {
164 return ERROR;
165 }
166 return ERROR_OK;
167 }
168
getTimezone()169 std::tuple<int32_t, char*> SystemDateTimeImpl::getTimezone()
170 {
171 int32_t innerCode;
172 std::string time;
173 innerCode = GetTimezone(time);
174 if (innerCode != CjErrorCode::ERROR_OK) {
175 TIME_HILOGE(TIME_MODULE_CLIENT, "failed innerCode is %{public}d", innerCode);
176 return {innerCode, nullptr};
177 }
178 return {SUCCESS_CODE, MallocCString(time)};
179 }
180 } // SystemDateTime
181 } // CJSystemapi
182 } // OHOS