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