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