1 /*
2 * Copyright (C) 2022 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 "napi_system_date_time.h"
17
18 #include "parameters.h"
19 #include "napi_work.h"
20 #include "napi_utils.h"
21 #include "time_hilog.h"
22 #include "time_service_client.h"
23
24 using namespace OHOS::MiscServices;
25
26 namespace OHOS {
27 namespace MiscServices {
28 namespace Time {
29
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 constexpr int32_t STARTUP = 0;
34 constexpr int32_t ACTIVE = 1;
35 const std::string TIMEZONE_KEY = "persist.time.timezone";
36
SystemDateTimeInit(napi_env env,napi_value exports)37 napi_value NapiSystemDateTime::SystemDateTimeInit(napi_env env, napi_value exports)
38 {
39 napi_value timeType = nullptr;
40 napi_value startup = nullptr;
41 napi_value active = nullptr;
42 NAPI_CALL(env, napi_create_int32(env, STARTUP, &startup));
43 NAPI_CALL(env, napi_create_int32(env, ACTIVE, &active));
44 NAPI_CALL(env, napi_create_object(env, &timeType));
45 NAPI_CALL(env, napi_set_named_property(env, timeType, "STARTUP", startup));
46 NAPI_CALL(env, napi_set_named_property(env, timeType, "ACTIVE", active));
47
48 napi_property_descriptor descriptors[] = {
49 DECLARE_NAPI_STATIC_FUNCTION("setTime", SetTime),
50 DECLARE_NAPI_STATIC_FUNCTION("getCurrentTime", GetCurrentTime),
51 DECLARE_NAPI_STATIC_FUNCTION("getRealActiveTime", GetRealActiveTime),
52 DECLARE_NAPI_STATIC_FUNCTION("getRealTime", GetRealTime),
53 DECLARE_NAPI_STATIC_FUNCTION("getTime", GetTime),
54 DECLARE_NAPI_STATIC_FUNCTION("updateNtpTime", UpdateNtpTime),
55 DECLARE_NAPI_STATIC_FUNCTION("getNtpTime", GetNtpTime),
56 DECLARE_NAPI_STATIC_FUNCTION("setDate", SetDate),
57 DECLARE_NAPI_STATIC_FUNCTION("getDate", GetDate),
58 DECLARE_NAPI_STATIC_FUNCTION("setTimezone", SetTimezone),
59 DECLARE_NAPI_STATIC_FUNCTION("getTimezone", GetTimezone),
60 DECLARE_NAPI_STATIC_FUNCTION("getUptime", GetUptime),
61 DECLARE_NAPI_STATIC_FUNCTION("getTimezoneSync", GetTimezoneSync),
62 DECLARE_NAPI_STATIC_PROPERTY("TimeType", timeType),
63 };
64
65 napi_status status =
66 napi_define_properties(env, exports, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors);
67 if (status != napi_ok) {
68 TIME_HILOGE(TIME_MODULE_JS_NAPI, "define manager properties failed, status=%{public}d", status);
69 return NapiUtils::GetUndefinedValue(env);
70 }
71 return exports;
72 }
73
SetTime(napi_env env,napi_callback_info info)74 napi_value NapiSystemDateTime::SetTime(napi_env env, napi_callback_info info)
75 {
76 struct SetTimeContext : public ContextBase {
77 int64_t time = 0;
78 };
79 auto *setTimeContext = new SetTimeContext();
80 auto inputParser = [env, setTimeContext](size_t argc, napi_value *argv) {
81 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimeContext, argc >= ARGC_ONE,
82 "Mandatory parameters are left unspecified", JsErrorCode::PARAMETER_ERROR);
83 setTimeContext->status = napi_get_value_int64(env, argv[ARGV_FIRST], &setTimeContext->time);
84 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimeContext, setTimeContext->status == napi_ok,
85 "The type of 'time' must be number", JsErrorCode::PARAMETER_ERROR);
86 setTimeContext->status = napi_ok;
87 };
88 setTimeContext->GetCbInfo(env, info, inputParser);
89 auto executor = [setTimeContext]() {
90 auto innerCode = TimeServiceClient::GetInstance()->SetTimeV9(setTimeContext->time);
91 if (innerCode != JsErrorCode::ERROR_OK) {
92 setTimeContext->errCode = innerCode;
93 setTimeContext->status = napi_generic_failure;
94 }
95 };
96 auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
97 return NapiWork::AsyncEnqueue(env, setTimeContext, "SetTime", executor, complete);
98 }
99
SetDate(napi_env env,napi_callback_info info)100 napi_value NapiSystemDateTime::SetDate(napi_env env, napi_callback_info info)
101 {
102 struct SetDateContext : public ContextBase {
103 int64_t time = 0;
104 };
105 auto *setDateContext = new SetDateContext();
106 auto inputParser = [env, setDateContext](size_t argc, napi_value *argv) {
107 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, argc >= ARGC_ONE,
108 "Mandatory parameters are left unspecified", JsErrorCode::PARAMETER_ERROR);
109 napi_valuetype valueType = napi_undefined;
110 napi_typeof(env, argv[ARGV_FIRST], &valueType);
111 if (valueType == napi_number) {
112 napi_get_value_int64(env, argv[ARGV_FIRST], &setDateContext->time);
113 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, setDateContext->time >= 0,
114 "date number must >= 0", JsErrorCode::PARAMETER_ERROR);
115 } else {
116 bool hasProperty = false;
117 napi_valuetype resValueType = napi_undefined;
118 napi_has_named_property(env, argv[ARGV_FIRST], "getTime", &hasProperty);
119 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, hasProperty,
120 "The type of 'date' must be Date", JsErrorCode::PARAMETER_ERROR);
121 napi_value getTimeFunc = nullptr;
122 napi_get_named_property(env, argv[0], "getTime", &getTimeFunc);
123 napi_value getTimeResult = nullptr;
124 napi_call_function(env, argv[0], getTimeFunc, 0, nullptr, &getTimeResult);
125 napi_typeof(env, getTimeResult, &resValueType);
126 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, resValueType == napi_number,
127 "The type of 'date' must be Date", JsErrorCode::PARAMETER_ERROR);
128 setDateContext->status = napi_get_value_int64(env, getTimeResult, &setDateContext->time);
129 }
130 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, setDateContext->status == napi_ok,
131 "The type of 'date' must be Date", JsErrorCode::PARAMETER_ERROR);
132 setDateContext->status = napi_ok;
133 };
134 setDateContext->GetCbInfo(env, info, inputParser);
135 auto executor = [setDateContext]() {
136 auto innerCode = TimeServiceClient::GetInstance()->SetTimeV9(setDateContext->time);
137 if (innerCode != JsErrorCode::ERROR_OK) {
138 setDateContext->errCode = innerCode;
139 setDateContext->status = napi_generic_failure;
140 }
141 };
142 auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
143 return NapiWork::AsyncEnqueue(env, setDateContext, "SetDate", executor, complete);
144 }
145
GetRealActiveTime(napi_env env,napi_callback_info info)146 napi_value NapiSystemDateTime::GetRealActiveTime(napi_env env, napi_callback_info info)
147 {
148 struct GetRealActiveTimeContext : public ContextBase {
149 int64_t time = 0;
150 bool isNano = false;
151 };
152 auto *getRealActiveTimeContext = new GetRealActiveTimeContext();
153 auto inputParser = [env, getRealActiveTimeContext](size_t argc, napi_value *argv) {
154 if (argc >= ARGC_ONE) {
155 napi_valuetype valueType = napi_undefined;
156 napi_typeof(env, argv[ARGV_FIRST], &valueType);
157 if (valueType == napi_boolean) {
158 getRealActiveTimeContext->status =
159 napi_get_value_bool(env, argv[ARGV_FIRST], &getRealActiveTimeContext->isNano);
160 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealActiveTimeContext,
161 getRealActiveTimeContext->status == napi_ok, "invalid isNano", JsErrorCode::PARAMETER_ERROR);
162 }
163 }
164 getRealActiveTimeContext->status = napi_ok;
165 };
166 getRealActiveTimeContext->GetCbInfo(env, info, inputParser);
167 auto executor = [getRealActiveTimeContext]() {
168 int32_t innerCode;
169 if (getRealActiveTimeContext->isNano) {
170 innerCode = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(getRealActiveTimeContext->time);
171 } else {
172 innerCode = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(getRealActiveTimeContext->time);
173 }
174 if (innerCode != JsErrorCode::ERROR_OK) {
175 getRealActiveTimeContext->errCode = NapiUtils::ConvertErrorCode(innerCode);
176 getRealActiveTimeContext->status = napi_generic_failure;
177 }
178 };
179 auto complete = [env, getRealActiveTimeContext](napi_value &output) {
180 getRealActiveTimeContext->status = napi_create_int64(env, getRealActiveTimeContext->time, &output);
181 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealActiveTimeContext,
182 "convert native object to javascript object failed", JsErrorCode::ERROR);
183 };
184 return NapiWork::AsyncEnqueue(env, getRealActiveTimeContext, "GetRealActiveTime", executor, complete);
185 }
186
GetCurrentTime(napi_env env,napi_callback_info info)187 napi_value NapiSystemDateTime::GetCurrentTime(napi_env env, napi_callback_info info)
188 {
189 struct GetCurrentTimeContext : public ContextBase {
190 int64_t time = 0;
191 bool isNano = false;
192 };
193 auto *getCurrentTimeContext = new GetCurrentTimeContext();
194 auto inputParser = [env, getCurrentTimeContext](size_t argc, napi_value *argv) {
195 if (argc >= ARGC_ONE) {
196 napi_valuetype valueType = napi_undefined;
197 napi_typeof(env, argv[ARGV_FIRST], &valueType);
198 if (valueType == napi_boolean) {
199 getCurrentTimeContext->status =
200 napi_get_value_bool(env, argv[ARGV_FIRST], &getCurrentTimeContext->isNano);
201 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getCurrentTimeContext,
202 getCurrentTimeContext->status == napi_ok, "invalid isNano", JsErrorCode::PARAMETER_ERROR);
203 }
204 }
205 getCurrentTimeContext->status = napi_ok;
206 };
207 getCurrentTimeContext->GetCbInfo(env, info, inputParser);
208 auto executor = [getCurrentTimeContext]() {
209 int32_t innerCode;
210 if (getCurrentTimeContext->isNano) {
211 innerCode = TimeServiceClient::GetInstance()->GetWallTimeNs(getCurrentTimeContext->time);
212 } else {
213 innerCode = TimeServiceClient::GetInstance()->GetWallTimeMs(getCurrentTimeContext->time);
214 }
215 if (innerCode != JsErrorCode::ERROR_OK) {
216 getCurrentTimeContext->errCode = innerCode;
217 getCurrentTimeContext->status = napi_generic_failure;
218 }
219 };
220 auto complete = [getCurrentTimeContext, env](napi_value &output) {
221 getCurrentTimeContext->status = napi_create_int64(env, getCurrentTimeContext->time, &output);
222 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getCurrentTimeContext,
223 "convert native object to javascript object failed", JsErrorCode::ERROR);
224 };
225 return NapiWork::AsyncEnqueue(env, getCurrentTimeContext, "GetCurrentTime", executor, complete);
226 }
227
GetTime(napi_env env,napi_callback_info info)228 napi_value NapiSystemDateTime::GetTime(napi_env env, napi_callback_info info)
229 {
230 struct GetTimeContext : public ContextBase {
231 int64_t time = 0;
232 bool isNano = false;
233 };
234 auto *getTimeContext = new GetTimeContext();
235 auto inputParser = [env, getTimeContext](size_t argc, napi_value *argv) {
236 if (argc >= ARGC_ONE) {
237 napi_valuetype valueType = napi_undefined;
238 napi_typeof(env, argv[ARGV_FIRST], &valueType);
239 if (valueType == napi_boolean) {
240 getTimeContext->status = napi_get_value_bool(env, argv[ARGV_FIRST], &getTimeContext->isNano);
241 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimeContext, getTimeContext->status == napi_ok,
242 "invalid isNano", JsErrorCode::PARAMETER_ERROR);
243 }
244 }
245 getTimeContext->status = napi_ok;
246 };
247 getTimeContext->GetCbInfo(env, info, inputParser, true);
248 auto executor = [getTimeContext]() {
249 int32_t innerCode = GetDeviceTime(CLOCK_REALTIME, getTimeContext->isNano, getTimeContext->time);
250 if (innerCode != JsErrorCode::ERROR_OK) {
251 getTimeContext->errCode = innerCode;
252 getTimeContext->status = napi_generic_failure;
253 }
254 };
255 auto complete = [getTimeContext](napi_value &output) {
256 getTimeContext->status = napi_create_int64(getTimeContext->env, getTimeContext->time, &output);
257 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimeContext,
258 "convert native object to javascript object failed", JsErrorCode::ERROR);
259 };
260 return NapiWork::SyncEnqueue(env, getTimeContext, "GetTime", executor, complete);
261 }
262
GetRealTime(napi_env env,napi_callback_info info)263 napi_value NapiSystemDateTime::GetRealTime(napi_env env, napi_callback_info info)
264 {
265 struct GetRealTimeContext : public ContextBase {
266 int64_t time = 0;
267 bool isNano = false;
268 };
269 auto *getRealTimeContext = new GetRealTimeContext();
270 auto inputParser = [env, getRealTimeContext](size_t argc, napi_value *argv) {
271 if (argc >= ARGC_ONE) {
272 napi_valuetype valueType = napi_undefined;
273 napi_typeof(env, argv[ARGV_FIRST], &valueType);
274 if (valueType == napi_boolean) {
275 getRealTimeContext->status = napi_get_value_bool(env, argv[ARGV_FIRST], &getRealTimeContext->isNano);
276 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealTimeContext, getRealTimeContext->status == napi_ok,
277 "invalid isNano", JsErrorCode::PARAMETER_ERROR);
278 }
279 }
280 getRealTimeContext->status = napi_ok;
281 };
282 getRealTimeContext->GetCbInfo(env, info, inputParser);
283 auto executor = [getRealTimeContext]() {
284 int32_t innerCode;
285 if (getRealTimeContext->isNano) {
286 innerCode = TimeServiceClient::GetInstance()->GetBootTimeNs(getRealTimeContext->time);
287 } else {
288 innerCode = TimeServiceClient::GetInstance()->GetBootTimeMs(getRealTimeContext->time);
289 }
290 if (innerCode != JsErrorCode::ERROR_OK) {
291 getRealTimeContext->errCode = innerCode;
292 getRealTimeContext->status = napi_generic_failure;
293 }
294 };
295 auto complete = [getRealTimeContext](napi_value &output) {
296 getRealTimeContext->status = napi_create_int64(getRealTimeContext->env, getRealTimeContext->time, &output);
297 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealTimeContext,
298 "convert native object to javascript object failed", JsErrorCode::ERROR);
299 };
300 return NapiWork::AsyncEnqueue(env, getRealTimeContext, "GetRealTime", executor, complete);
301 }
302
GetUptime(napi_env env,napi_callback_info info)303 napi_value NapiSystemDateTime::GetUptime(napi_env env, napi_callback_info info)
304 {
305 struct GetUpTimeContext : public ContextBase {
306 int64_t time = 0;
307 int32_t timeType = STARTUP;
308 bool isNanoseconds = false;
309 };
310 auto *getUpTimeContext = new GetUpTimeContext();
311 auto inputParser = [env, getUpTimeContext](size_t argc, napi_value *argv) {
312 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, argc >= ARGC_ONE,
313 "Mandatory parameters are left unspecified", JsErrorCode::PARAMETER_ERROR);
314 getUpTimeContext->status = napi_get_value_int32(env, argv[ARGV_FIRST], &getUpTimeContext->timeType);
315 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, getUpTimeContext->status == napi_ok,
316 "The type of 'timeType' must be number or enum", JsErrorCode::PARAMETER_ERROR);
317 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext,
318 (getUpTimeContext->timeType >= STARTUP && getUpTimeContext->timeType <= ACTIVE),
319 "The 'timeType' must be 'STARTUP' or 'ACTIVE' or 0 or 1", JsErrorCode::PARAMETER_ERROR);
320 if (argc >= ARGC_TWO) {
321 napi_valuetype valueType = napi_undefined;
322 napi_typeof(env, argv[ARGV_SECOND], &valueType);
323 if (valueType == napi_boolean) {
324 getUpTimeContext->status =
325 napi_get_value_bool(env, argv[ARGV_SECOND], &getUpTimeContext->isNanoseconds);
326 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, getUpTimeContext->status == napi_ok,
327 "get isNanoseconds failed", JsErrorCode::PARAMETER_ERROR);
328 }
329 }
330 getUpTimeContext->status = napi_ok;
331 };
332 getUpTimeContext->GetCbInfo(env, info, inputParser, true);
333 auto executor = [getUpTimeContext]() {
334 int32_t innerCode;
335 if (getUpTimeContext->timeType == STARTUP) {
336 innerCode = GetDeviceTime(CLOCK_BOOTTIME, getUpTimeContext->isNanoseconds, getUpTimeContext->time);
337 } else {
338 innerCode = GetDeviceTime(CLOCK_MONOTONIC, getUpTimeContext->isNanoseconds, getUpTimeContext->time);
339 }
340 if (innerCode != JsErrorCode::ERROR_OK) {
341 getUpTimeContext->errCode = innerCode;
342 getUpTimeContext->status = napi_generic_failure;
343 }
344 };
345 auto complete = [getUpTimeContext](napi_value &output) {
346 getUpTimeContext->status = napi_create_int64(getUpTimeContext->env, getUpTimeContext->time, &output);
347 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext,
348 "convert native object to javascript object failed", JsErrorCode::ERROR);
349 };
350 return NapiWork::SyncEnqueue(env, getUpTimeContext, "GetUpTime", executor, complete);
351 }
352
GetDate(napi_env env,napi_callback_info info)353 napi_value NapiSystemDateTime::GetDate(napi_env env, napi_callback_info info)
354 {
355 struct GetDateContext : public ContextBase {
356 int64_t time = 0;
357 };
358 auto *getDateContext = new GetDateContext();
359 auto inputParser = [getDateContext](size_t argc, napi_value *argv) { getDateContext->status = napi_ok; };
360 getDateContext->GetCbInfo(env, info, inputParser);
361 auto executor = [getDateContext]() {
362 auto innerCode = TimeServiceClient::GetInstance()->GetWallTimeMs(getDateContext->time);
363 if (innerCode != JsErrorCode::ERROR_OK) {
364 getDateContext->errCode = innerCode;
365 getDateContext->status = napi_generic_failure;
366 }
367 };
368 auto complete = [env, getDateContext](napi_value &output) {
369 getDateContext->status = napi_create_date(env, getDateContext->time, &output);
370 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getDateContext,
371 "convert native object to javascript object failed", JsErrorCode::ERROR);
372 };
373
374 return NapiWork::AsyncEnqueue(env, getDateContext, "GetDate", executor, complete);
375 }
376
SetTimezone(napi_env env,napi_callback_info info)377 napi_value NapiSystemDateTime::SetTimezone(napi_env env, napi_callback_info info)
378 {
379 struct SetTimezoneContext : public ContextBase {
380 std::string timezone;
381 };
382 auto *setTimezoneContext = new SetTimezoneContext();
383 auto inputParser = [env, setTimezoneContext](size_t argc, napi_value *argv) {
384 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimezoneContext, argc >= ARGC_ONE,
385 "Mandatory parameters are left unspecified", JsErrorCode::PARAMETER_ERROR);
386 setTimezoneContext->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], setTimezoneContext->timezone);
387 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimezoneContext, setTimezoneContext->status == napi_ok,
388 "The type of 'timezone' must be string", JsErrorCode::PARAMETER_ERROR);
389 setTimezoneContext->status = napi_ok;
390 };
391 setTimezoneContext->GetCbInfo(env, info, inputParser);
392 auto executor = [setTimezoneContext]() {
393 auto innerCode = TimeServiceClient::GetInstance()->SetTimeZoneV9(setTimezoneContext->timezone);
394 if (innerCode != JsErrorCode::ERROR_OK) {
395 setTimezoneContext->errCode = innerCode;
396 setTimezoneContext->status = napi_generic_failure;
397 }
398 };
399 auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
400 return NapiWork::AsyncEnqueue(env, setTimezoneContext, "SetTimezone", executor, complete);
401 }
402
GetTimezone(napi_env env,napi_callback_info info)403 napi_value NapiSystemDateTime::GetTimezone(napi_env env, napi_callback_info info)
404 {
405 struct GetTimezoneContext : public ContextBase {
406 std::string timezone;
407 };
408 auto *getTimezoneContext = new GetTimezoneContext();
409 auto inputParser = [getTimezoneContext](size_t argc, napi_value *argv) {
410 getTimezoneContext->status = napi_ok;
411 };
412 getTimezoneContext->GetCbInfo(env, info, inputParser);
413
414 auto executor = [getTimezoneContext]() {
415 auto innerCode = TimeServiceClient::GetInstance()->GetTimeZone(getTimezoneContext->timezone);
416 if (innerCode != JsErrorCode::ERROR_OK) {
417 getTimezoneContext->errCode = innerCode;
418 getTimezoneContext->status = napi_generic_failure;
419 }
420 };
421 auto complete = [env, getTimezoneContext](napi_value &output) {
422 getTimezoneContext->status = napi_create_string_utf8(env, getTimezoneContext->timezone.c_str(),
423 getTimezoneContext->timezone.size(), &output);
424 TIME_HILOGI(TIME_MODULE_JS_NAPI, "%{public}s, ", getTimezoneContext->timezone.c_str());
425 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimezoneContext,
426 "convert native object to javascript object failed", JsErrorCode::ERROR);
427 };
428 return NapiWork::AsyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete);
429 }
430
GetTimezoneSync(napi_env env,napi_callback_info info)431 napi_value NapiSystemDateTime::GetTimezoneSync(napi_env env, napi_callback_info info)
432 {
433 struct GetTimezoneContext : public ContextBase {
434 std::string timezone;
435 };
436 auto *getTimezoneContext = new GetTimezoneContext();
437 auto inputParser = [getTimezoneContext](size_t argc, napi_value *argv) { getTimezoneContext->status = napi_ok; };
438 getTimezoneContext->GetCbInfo(env, info, inputParser, true);
439
440 auto executor = [getTimezoneContext]() {
441 auto innerCode = GetTimezone(getTimezoneContext->timezone);
442 if (innerCode != JsErrorCode::ERROR_OK) {
443 getTimezoneContext->errCode = innerCode;
444 getTimezoneContext->status = napi_generic_failure;
445 }
446 };
447 auto complete = [env, getTimezoneContext](napi_value &output) {
448 getTimezoneContext->status = napi_create_string_utf8(env, getTimezoneContext->timezone.c_str(),
449 getTimezoneContext->timezone.size(), &output);
450 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimezoneContext,
451 "convert native object to javascript object failed", JsErrorCode::ERROR);
452 };
453 return NapiWork::SyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete);
454 }
455
UpdateNtpTime(napi_env env,napi_callback_info info)456 napi_value NapiSystemDateTime::UpdateNtpTime(napi_env env, napi_callback_info info)
457 {
458 struct UpdateNtpTime : public ContextBase {
459 int64_t time = 0;
460 };
461 auto *updateNtpTimeContext = new UpdateNtpTime();
462 auto inputParser = [env, updateNtpTimeContext](size_t argc, napi_value *argv) {
463 updateNtpTimeContext->status = napi_ok;
464 };
465 updateNtpTimeContext->GetCbInfo(env, info, inputParser);
466
467 auto executor = [updateNtpTimeContext]() {
468 int32_t innerCode = TimeServiceClient::GetInstance()->GetNtpTimeMs(updateNtpTimeContext->time);
469 if (innerCode != JsErrorCode::ERROR_OK) {
470 updateNtpTimeContext->errCode = innerCode;
471 updateNtpTimeContext->status = napi_generic_failure;
472 }
473 };
474 auto complete = [env](napi_value &output) {
475 output = NapiUtils::GetUndefinedValue(env);
476 };
477 return NapiWork::AsyncEnqueue(env, updateNtpTimeContext, "UpdateNtpTime", executor, complete);
478 }
479
GetNtpTime(napi_env env,napi_callback_info info)480 napi_value NapiSystemDateTime::GetNtpTime(napi_env env, napi_callback_info info)
481 {
482 struct GetNtpTimeContext : public ContextBase {
483 int64_t time = 0;
484 };
485 auto *getNtpTimeContext = new GetNtpTimeContext();
486 auto inputParser = [env, getNtpTimeContext](size_t argc, napi_value *argv) {
487 getNtpTimeContext->status = napi_ok;
488 };
489 getNtpTimeContext->GetCbInfo(env, info, inputParser);
490
491 auto executor = [getNtpTimeContext]() {
492 int32_t innerCode = TimeServiceClient::GetInstance()->GetRealTimeMs(getNtpTimeContext->time);
493 if (innerCode != JsErrorCode::ERROR_OK) {
494 getNtpTimeContext->errCode = innerCode;
495 getNtpTimeContext->status = napi_generic_failure;
496 }
497 };
498 auto complete = [getNtpTimeContext](napi_value &output) {
499 getNtpTimeContext->status = napi_create_int64(getNtpTimeContext->env, getNtpTimeContext->time, &output);
500 CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getNtpTimeContext,
501 "convert native object to javascript object failed", JsErrorCode::ERROR);
502 };
503 return NapiWork::SyncEnqueue(env, getNtpTimeContext, "GetNtpTime", executor, complete);
504 }
505
GetDeviceTime(clockid_t clockId,bool isNano,int64_t & time)506 int32_t NapiSystemDateTime::GetDeviceTime(clockid_t clockId, bool isNano, int64_t &time)
507 {
508 struct timespec tv {};
509 if (clock_gettime(clockId, &tv) < 0) {
510 TIME_HILOGE(TIME_MODULE_SERVICE, "failed clock_gettime, errno: %{public}s", strerror(errno));
511 return ERROR;
512 }
513
514 if (isNano) {
515 time = tv.tv_sec * SECONDS_TO_NANO + tv.tv_nsec;
516 } else {
517 time = tv.tv_sec * SECONDS_TO_MILLI + tv.tv_nsec / NANO_TO_MILLI;
518 }
519 return ERROR_OK;
520 }
521
GetTimezone(std::string & timezone)522 int32_t NapiSystemDateTime::GetTimezone(std::string &timezone)
523 {
524 timezone = system::GetParameter(TIMEZONE_KEY, "Asia/Shanghai");
525 if (timezone.empty()) {
526 TIME_HILOGW(TIME_MODULE_SERVICE, "No found timezone from system parameter.");
527 return ERROR;
528 }
529 return ERROR_OK;
530 }
531 } // namespace Time
532 } // namespace MiscServices
533 } // namespace OHOS