• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include <string>
16 #include <initializer_list>
17 
18 #include "time_service_client.h"
19 #include "napi/native_api.h"
20 #include "napi/native_node_api.h"
21 #include "js_native_api.h"
22 #include "time_common.h"
23 #include "js_systemtime.h"
24 
25 namespace OHOS {
26 namespace MiscServicesNapi {
27 using namespace OHOS::MiscServices;
28 const size_t ARGC_TYPE_SET1 = 1;
29 const size_t ARGC_TYPE_SET2 = 2;
30 
TimeGetCallbackErrorValue(napi_env env,int errCode)31 napi_value TimeGetCallbackErrorValue(napi_env env, int errCode)
32 {
33     napi_value result = nullptr;
34     napi_value eCode = nullptr;
35     NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
36     NAPI_CALL(env, napi_create_object(env, &result));
37     NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
38     return result;
39 }
40 
TimeNapiGetNull(napi_env env)41 napi_value TimeNapiGetNull(napi_env env)
42 {
43     napi_value result = nullptr;
44     napi_get_null(env, &result);
45     return result;
46 }
47 
TimeSetPromise(const napi_env & env,const napi_deferred & deferred,const int & errorCode,const napi_value & result)48 void TimeSetPromise(const napi_env &env, const napi_deferred &deferred, const int &errorCode, const napi_value &result)
49 {
50     if (errorCode == NO_ERROR) {
51         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result));
52         return;
53     }
54     NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, result));
55 }
56 
TimeSetCallback(const napi_env & env,const napi_ref & callbackIn,const int & errorCode,const napi_value & result)57 void TimeSetCallback(const napi_env &env, const napi_ref &callbackIn, const int &errorCode, const napi_value &result)
58 {
59     napi_value undefined = nullptr;
60     napi_get_undefined(env, &undefined);
61 
62     napi_value callback = nullptr;
63     napi_value resultout = nullptr;
64     napi_get_reference_value(env, callbackIn, &callback);
65     napi_value results[ARGS_TWO] = {0};
66     results[PARAM0] = TimeGetCallbackErrorValue(env, errorCode);
67     results[PARAM1] = result;
68     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &results[PARAM0], &resultout));
69 }
70 
TimeReturnCallbackPromise(const napi_env & env,const TimeCallbackPromiseInfo & info,const napi_value & result)71 void TimeReturnCallbackPromise(const napi_env &env, const TimeCallbackPromiseInfo &info, const napi_value &result)
72 {
73     if (info.isCallback) {
74         TimeSetCallback(env, info.callback, info.errorCode, result);
75     } else {
76         TimeSetPromise(env, info.deferred, info.errorCode, result);
77     }
78 }
79 
TimeJSParaError(const napi_env & env,const napi_ref & callback)80 napi_value TimeJSParaError(const napi_env &env, const napi_ref &callback)
81 {
82     if (callback) {
83         return TimeNapiGetNull(env);
84     } else {
85         napi_value promise = nullptr;
86         napi_deferred deferred = nullptr;
87         napi_create_promise(env, &deferred, &promise);
88         TimeSetPromise(env, deferred, ERROR, TimeNapiGetNull(env));
89         return promise;
90     }
91 }
92 
TimePaddingAsyncCallbackInfo(const napi_env & env,AsyncContext * & asynccallbackinfo,const napi_ref & callback,napi_value & promise)93 void TimePaddingAsyncCallbackInfo(const napi_env &env,
94     AsyncContext *&asynccallbackinfo,
95     const napi_ref &callback,
96     napi_value &promise)
97 {
98     if (callback) {
99         asynccallbackinfo->callbackRef = callback;
100         asynccallbackinfo->isCallback = true;
101     } else {
102         napi_deferred deferred = nullptr;
103         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
104         asynccallbackinfo->deferred = deferred;
105         asynccallbackinfo->isCallback = false;
106     }
107 }
108 
ParseParametersBySetTime(const napi_env & env,const napi_value (& argv)[SET_TIME_MAX_PARA],const size_t & argc,int64_t & times,napi_ref & callback)109 napi_value ParseParametersBySetTime(const napi_env &env, const napi_value (&argv)[SET_TIME_MAX_PARA],
110     const size_t &argc, int64_t &times, napi_ref &callback)
111 {
112     NAPI_ASSERT(env, argc >= SET_TIME_MAX_PARA - 1, "Wrong number of arguments");
113     napi_valuetype valueType = napi_undefined;
114 
115     // argv[0]: times or date object
116     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
117     NAPI_ASSERT(env, valueType == napi_number || valueType == napi_object, "Wrong argument type. string expected.");
118     if (valueType == napi_number) {
119         napi_get_value_int64(env, argv[0], &times);
120         NAPI_ASSERT(env, times >= 0, "Wrong argument timer. Positive number expected.");
121     } else {
122         bool hasProperty = false;
123         napi_valuetype resValueType = napi_undefined;
124         NAPI_CALL(env, napi_has_named_property(env, argv[0], "getTime", &hasProperty));
125         NAPI_ASSERT(env, hasProperty, "type expected.");
126         napi_value getTimeFunc = nullptr;
127         napi_get_named_property(env, argv[0], "getTime", &getTimeFunc);
128         napi_value getTimeResult = nullptr;
129         napi_call_function(env, argv[0], getTimeFunc, 0, nullptr, &getTimeResult);
130         NAPI_CALL(env, napi_typeof(env, getTimeResult, &resValueType));
131         NAPI_ASSERT(env, resValueType == napi_number, "type mismatch");
132         napi_get_value_int64(env, getTimeResult, &times);
133     }
134 
135     // argv[1]:callback
136     if (argc >= SET_TIME_MAX_PARA) {
137         NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
138         NAPI_ASSERT(env, valueType == napi_function, "Wrong argument type. Function expected.");
139         napi_create_reference(env, argv[1], 1, &callback);
140     }
141     return TimeNapiGetNull(env);
142 }
143 
JSSystemTimeSetTime(napi_env env,napi_callback_info info)144 napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info)
145 {
146     size_t argc = SET_TIME_MAX_PARA;
147     napi_value argv[SET_TIME_MAX_PARA] = {0};
148     napi_value thisVar = nullptr;
149     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
150     int64_t times = INVALID_TIME;
151     napi_ref callback = nullptr;
152     if (ParseParametersBySetTime(env, argv, argc, times, callback) == nullptr) {
153         return TimeJSParaError(env, callback);
154     }
155     AsyncContext *asyncContext = new (std::nothrow)AsyncContext {.env = env, .time = times};
156     if (!asyncContext) {
157         return TimeJSParaError(env, callback);
158     }
159     napi_value promise = nullptr;
160     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
161     napi_value resource = nullptr;
162     napi_create_string_utf8(env, "JSSystemTimeSetTime", NAPI_AUTO_LENGTH, &resource);
163     napi_create_async_work(env,
164         nullptr,
165         resource,
166         [](napi_env env, void *data) {
167             AsyncContext *asyncContext = (AsyncContext*)data;
168             asyncContext->isOK = TimeServiceClient::GetInstance()->SetTime(asyncContext->time);
169         },
170         [](napi_env env, napi_status status, void *data) {
171             AsyncContext *asyncContext = (AsyncContext*)data;
172             if (!asyncContext->isOK) {
173                 asyncContext->errorCode = ERROR;
174             }
175             TimeCallbackPromiseInfo info;
176             info.isCallback = asyncContext->isCallback;
177             info.callback = asyncContext->callbackRef;
178             info.deferred = asyncContext->deferred;
179             info.errorCode = asyncContext->errorCode;
180             napi_value result = 0;
181             napi_get_null(env, &result);
182             TimeReturnCallbackPromise(env, info, result);
183             napi_delete_async_work(env, asyncContext->work);
184             if (asyncContext) {
185                 delete asyncContext;
186                 asyncContext = nullptr;
187             }
188         },
189         (void*)asyncContext,
190         &asyncContext->work);
191     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
192     if (asyncContext->isCallback) {
193         return TimeNapiGetNull(env);
194     } else {
195         return promise;
196     }
197 }
198 
ParseParametersBySetTimezone(const napi_env & env,const napi_value (& argv)[SET_TIMEZONE_MAX_PARA],const size_t & argc,std::string & timezoneId,napi_ref & callback)199 napi_value ParseParametersBySetTimezone(const napi_env &env, const napi_value (&argv)[SET_TIMEZONE_MAX_PARA],
200     const size_t &argc, std::string &timezoneId, napi_ref &callback)
201 {
202     NAPI_ASSERT(env, argc >= SET_TIMEZONE_MAX_PARA - 1, "Wrong number of arguments");
203     napi_valuetype valueType = napi_undefined;
204 
205     // argv[0]: timezoneid
206     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
207     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument type. string expected.");
208     char timeZoneChars[MAX_TIME_ZONE_ID];
209     size_t copied;
210     napi_get_value_string_utf8(env, argv[0], timeZoneChars, MAX_TIME_ZONE_ID - 1, &copied);
211     TIME_HILOGD(TIME_MODULE_JNI, "timezone str: %{public}s", timeZoneChars);
212 
213     timezoneId = std::string(timeZoneChars);
214 
215     // argv[1]:callback
216     if (argc >= SET_TIMEZONE_MAX_PARA) {
217         NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
218         NAPI_ASSERT(env, valueType == napi_function, "Wrong argument type. Function expected.");
219         napi_create_reference(env, argv[1], 1, &callback);
220     }
221     return TimeNapiGetNull(env);
222 }
223 
JSSystemTimeSetTimeZone(napi_env env,napi_callback_info info)224 napi_value JSSystemTimeSetTimeZone(napi_env env, napi_callback_info info)
225 {
226     size_t argc = SET_TIMEZONE_MAX_PARA;
227     napi_value argv[SET_TIMEZONE_MAX_PARA] = {0};
228     napi_value thisVar = nullptr;
229     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
230     std::string timezoneId;
231     napi_ref callback = nullptr;
232     if (ParseParametersBySetTimezone(env, argv, argc, timezoneId, callback) == nullptr) {
233         return TimeJSParaError(env, callback);
234     }
235     AsyncContext *asyncContext = new (std::nothrow)AsyncContext {.env = env, .timeZone = timezoneId};
236     if (!asyncContext) {
237         return TimeJSParaError(env, callback);
238     }
239     napi_value promise = nullptr;
240     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
241     napi_value resource = nullptr;
242     napi_create_string_utf8(env, "JSSystemTimeSetTimeZone", NAPI_AUTO_LENGTH, &resource);
243     napi_create_async_work(env,
244         nullptr,
245         resource,
246         [](napi_env env, void *data) {
247             AsyncContext *asyncContext = (AsyncContext*)data;
248             asyncContext->isOK = TimeServiceClient::GetInstance()->SetTimeZone(asyncContext->timeZone);
249         },
250         [](napi_env env, napi_status status, void *data) {
251             AsyncContext *asyncContext = (AsyncContext*)data;
252             if (!asyncContext->isOK) {
253                 asyncContext->errorCode = ERROR;
254             }
255             TimeCallbackPromiseInfo info;
256             info.isCallback = asyncContext->isCallback;
257             info.callback = asyncContext->callbackRef;
258             info.deferred = asyncContext->deferred;
259             info.errorCode = asyncContext->errorCode;
260             napi_value result = 0;
261             napi_get_null(env, &result);
262             TimeReturnCallbackPromise(env, info, result);
263             napi_delete_async_work(env, asyncContext->work);
264             if (asyncContext) {
265                 delete asyncContext;
266                 asyncContext = nullptr;
267             }
268         },
269         (void*)asyncContext,
270         &asyncContext->work);
271     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
272     if (asyncContext->isCallback) {
273         return TimeNapiGetNull(env);
274     } else {
275         return promise;
276     }
277 }
278 
ParseParametersGet(const napi_env & env,const napi_value (& argv)[SET_TIMEZONE_MAX_PARA],const size_t & argc,napi_ref & callback)279 napi_value ParseParametersGet(const napi_env &env, const napi_value (&argv)[SET_TIMEZONE_MAX_PARA],
280     const size_t &argc, napi_ref &callback)
281 {
282     napi_valuetype valueType = napi_undefined;
283     if (argc == ARGC_TYPE_SET1) {
284         NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
285         NAPI_ASSERT(env, valueType == napi_function, "Wrong argument type. Function expected.");
286         napi_create_reference(env, argv[0], ARGC_TYPE_SET1, &callback);
287     }
288     return TimeNapiGetNull(env);
289 }
290 
ParseParametersGetNA(const napi_env & env,const napi_value (& argv)[SET_TIMEZONE_MAX_PARA],const size_t & argc,napi_ref & callback,bool * isNano)291 napi_value ParseParametersGetNA(const napi_env &env, const napi_value (&argv)[SET_TIMEZONE_MAX_PARA],
292     const size_t &argc, napi_ref &callback, bool *isNano)
293 {
294     napi_valuetype valueType = napi_undefined;
295     if (argc == ARGC_TYPE_SET1) {
296         NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
297         if (valueType == napi_function) {
298             napi_create_reference(env, argv[0], ARGC_TYPE_SET1, &callback);
299         } else if (valueType == napi_boolean) {
300             napi_get_value_bool(env, argv[0], isNano);
301         }
302     } else if (argc == ARGC_TYPE_SET2) {
303         napi_get_value_bool(env, argv[0], isNano);
304         napi_create_reference(env, argv[1], ARGC_TYPE_SET1, &callback);
305     }
306     return TimeNapiGetNull(env);
307 }
308 
JSSystemTimeGetCurrentTime(napi_env env,napi_callback_info info)309 napi_value JSSystemTimeGetCurrentTime(napi_env env, napi_callback_info info)
310 {
311     size_t argc = SET_TIMEZONE_MAX_PARA;
312     napi_value argv[SET_TIMEZONE_MAX_PARA] = {0};
313     napi_value thisVar = nullptr;
314     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
315     napi_ref callback = nullptr;
316     bool isNano = false;
317     if (ParseParametersGetNA(env, argv, argc, callback, &isNano) == nullptr) {
318         return TimeJSParaError(env, callback);
319     }
320     AsyncContext* asyncContext = new (std::nothrow)AsyncContext {.env = env};
321     if (!asyncContext) {
322         return TimeJSParaError(env, callback);
323     }
324     napi_value promise = nullptr;
325     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
326     asyncContext->isNano = isNano;
327     napi_value resource = nullptr;
328     napi_create_string_utf8(env, "JSSystemTimeGetCurrentTime", NAPI_AUTO_LENGTH, &resource);
329     napi_create_async_work(env,
330         nullptr,
331         resource,
332         [](napi_env env, void* data) {
333             AsyncContext* asyncContext = (AsyncContext*)data;
334             if (asyncContext->isNano) {
335                 asyncContext->time = TimeServiceClient::GetInstance()->GetWallTimeNs();
336             } else {
337                 asyncContext->time = TimeServiceClient::GetInstance()->GetWallTimeMs();
338             }
339         },
340         [](napi_env env, napi_status status, void* data) {
341             AsyncContext* asyncContext = (AsyncContext*)data;
342             if (asyncContext->time < 0) {
343             }
344             TimeCallbackPromiseInfo info;
345             info.isCallback = asyncContext->isCallback;
346             info.callback = asyncContext->callbackRef;
347             info.deferred = asyncContext->deferred;
348             info.errorCode = asyncContext->errorCode;
349             napi_value result = nullptr;
350             napi_create_int64(env, asyncContext->time, &result);
351             TimeReturnCallbackPromise(env, info, result);
352             napi_delete_async_work(env, asyncContext->work);
353             if (asyncContext) {
354                 delete asyncContext;
355                 asyncContext = nullptr;
356             }
357         },
358         (void*)asyncContext,
359         &asyncContext->work);
360     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
361     if (asyncContext->isCallback) {
362         return TimeNapiGetNull(env);
363     } else {
364         return promise;
365     }
366 }
367 
JSSystemTimeGetRealActiveTime(napi_env env,napi_callback_info info)368 napi_value JSSystemTimeGetRealActiveTime(napi_env env, napi_callback_info info)
369 {
370     size_t argc = SET_TIMEZONE_MAX_PARA;
371     napi_value argv[SET_TIMEZONE_MAX_PARA] = {0};
372     napi_value thisVar = nullptr;
373     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
374     napi_ref callback = nullptr;
375     bool isNano = false;
376     if (ParseParametersGetNA(env, argv, argc, callback, &isNano) == nullptr) {
377         return TimeJSParaError(env, callback);
378     }
379     AsyncContext* asyncContext = new (std::nothrow)AsyncContext {.env = env};
380     if (!asyncContext) {
381         return TimeJSParaError(env, callback);
382     }
383     napi_value promise = nullptr;
384     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
385     asyncContext->isNano = isNano;
386     napi_value resource = nullptr;
387     napi_create_string_utf8(env, "JSSystemTimeGetRealActiveTime", NAPI_AUTO_LENGTH, &resource);
388     napi_create_async_work(env,
389         nullptr,
390         resource,
391         [](napi_env env, void* data) {
392             AsyncContext* asyncContext = (AsyncContext*)data;
393             if (asyncContext->isNano) {
394                 asyncContext->time = TimeServiceClient::GetInstance()->GetMonotonicTimeNs();
395             } else {
396                 asyncContext->time = TimeServiceClient::GetInstance()->GetMonotonicTimeMs();
397             }
398         },
399         [](napi_env env, napi_status status, void* data) {
400             AsyncContext* asyncContext = (AsyncContext*)data;
401             if (asyncContext->time < 0) {
402                 asyncContext->errorCode = ERROR;
403             }
404             TimeCallbackPromiseInfo info;
405             info.isCallback = asyncContext->isCallback;
406             info.callback = asyncContext->callbackRef;
407             info.deferred = asyncContext->deferred;
408             info.errorCode = asyncContext->errorCode;
409             napi_value result = nullptr;
410             napi_create_int64(env, asyncContext->time, &result);
411             TimeReturnCallbackPromise(env, info, result);
412             napi_delete_async_work(env, asyncContext->work);
413             if (asyncContext) {
414                 delete asyncContext;
415                 asyncContext = nullptr;
416             }
417         },
418         (void*)asyncContext,
419         &asyncContext->work);
420     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
421     if (asyncContext->isCallback) {
422         return TimeNapiGetNull(env);
423     } else {
424         return promise;
425     }
426 }
427 
JSSystemTimeGetRealTime(napi_env env,napi_callback_info info)428 napi_value JSSystemTimeGetRealTime(napi_env env, napi_callback_info info)
429 {
430     size_t argc = SET_TIMEZONE_MAX_PARA;
431     napi_value argv[SET_TIMEZONE_MAX_PARA] = {0};
432     napi_value thisVar = nullptr;
433     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
434     napi_ref callback = nullptr;
435     bool isNano = false;
436     if (ParseParametersGetNA(env, argv, argc, callback, &isNano) == nullptr) {
437         return TimeJSParaError(env, callback);
438     }
439     AsyncContext* asyncContext = new (std::nothrow)AsyncContext {.env = env};
440     if (!asyncContext) {
441         return TimeJSParaError(env, callback);
442     }
443     napi_value promise = nullptr;
444     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
445     asyncContext->isNano = isNano;
446     napi_value resource = nullptr;
447     napi_create_string_utf8(env, "JSSystemTimeGetRealTime", NAPI_AUTO_LENGTH, &resource);
448     napi_create_async_work(env,
449         nullptr,
450         resource,
451         [](napi_env env, void* data) {
452             AsyncContext* asyncContext = (AsyncContext*)data;
453             if (asyncContext->isNano) {
454                 asyncContext->time = TimeServiceClient::GetInstance()->GetBootTimeNs();
455             } else {
456                 asyncContext->time = TimeServiceClient::GetInstance()->GetBootTimeMs();
457             }
458         },
459         [](napi_env env, napi_status status, void* data) {
460             AsyncContext* asyncContext = (AsyncContext*)data;
461             if (asyncContext->time < 0) {
462                 asyncContext->errorCode = ERROR;
463             }
464             TimeCallbackPromiseInfo info;
465             info.isCallback = asyncContext->isCallback;
466             info.callback = asyncContext->callbackRef;
467             info.deferred = asyncContext->deferred;
468             info.errorCode = asyncContext->errorCode;
469             napi_value result = nullptr;
470             napi_create_int64(env, asyncContext->time, &result);
471             TimeReturnCallbackPromise(env, info, result);
472             napi_delete_async_work(env, asyncContext->work);
473             if (asyncContext) {
474                 delete asyncContext;
475                 asyncContext = nullptr;
476             }
477         },
478         (void*)asyncContext,
479         &asyncContext->work);
480     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
481     if (asyncContext->isCallback) {
482         return TimeNapiGetNull(env);
483     } else {
484         return promise;
485     }
486 }
487 
JSSystemTimeGetDate(napi_env env,napi_callback_info info)488 napi_value JSSystemTimeGetDate(napi_env env, napi_callback_info info)
489 {
490     size_t argc = SET_TIMEZONE_MAX_PARA;
491     napi_value argv[SET_TIMEZONE_MAX_PARA] = {0};
492     napi_value thisVar = nullptr;
493     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
494     napi_ref callback = nullptr;
495     if (ParseParametersGet(env, argv, argc, callback) == nullptr) {
496         return TimeJSParaError(env, callback);
497     }
498     AsyncContext* asyncContext = new (std::nothrow)AsyncContext {.env = env};
499     if (!asyncContext) {
500         return TimeJSParaError(env, callback);
501     }
502     napi_value promise = nullptr;
503     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
504     napi_value resource = nullptr;
505     napi_create_string_utf8(env, "JSSystemTimeGetDate", NAPI_AUTO_LENGTH, &resource);
506     napi_create_async_work(env,
507         nullptr,
508         resource,
509         [](napi_env env, void* data) {
510             AsyncContext* asyncContext = (AsyncContext*)data;
511             asyncContext->time = TimeServiceClient::GetInstance()->GetWallTimeMs();
512         },
513         [](napi_env env, napi_status status, void* data) {
514             AsyncContext* asyncContext = (AsyncContext*)data;
515             if (asyncContext->time < 0) {
516                 asyncContext->errorCode = ERROR;
517             }
518             TimeCallbackPromiseInfo info;
519             info.isCallback = asyncContext->isCallback;
520             info.callback = asyncContext->callbackRef;
521             info.deferred = asyncContext->deferred;
522             info.errorCode = asyncContext->errorCode;
523             std::string str = "new Date(" + std::to_string(asyncContext->time) + ");";
524             const char *scriptStr = str.c_str();
525             napi_value script = nullptr;
526             napi_create_string_utf8(env, scriptStr, strlen(scriptStr), &script);
527             napi_value result = nullptr;
528             napi_run_script(env, script, &result);
529             TimeReturnCallbackPromise(env, info, result);
530             napi_delete_async_work(env, asyncContext->work);
531             if (asyncContext) {
532                 delete asyncContext;
533                 asyncContext = nullptr;
534             }
535         },
536         (void*)asyncContext,
537         &asyncContext->work);
538     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
539     if (asyncContext->isCallback) {
540         return TimeNapiGetNull(env);
541     } else {
542         return promise;
543     }
544 }
545 
JSSystemTimeGetTimeZone(napi_env env,napi_callback_info info)546 napi_value JSSystemTimeGetTimeZone(napi_env env, napi_callback_info info)
547 {
548     size_t argc = SET_TIMEZONE_MAX_PARA;
549     napi_value argv[SET_TIMEZONE_MAX_PARA] = {0};
550     napi_value thisVar = nullptr;
551     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
552     napi_ref callback = nullptr;
553     if (ParseParametersGet(env, argv, argc, callback) == nullptr) {
554         return TimeJSParaError(env, callback);
555     }
556     AsyncContext* asyncContext = new (std::nothrow)AsyncContext {.env = env};
557     if (!asyncContext) {
558         return TimeJSParaError(env, callback);
559     }
560     TIME_HILOGI(TIME_MODULE_JS_NAPI, " jsgetTimezone start==");
561     napi_value promise = nullptr;
562     TimePaddingAsyncCallbackInfo(env, asyncContext, callback, promise);
563     napi_value resource = nullptr;
564     napi_create_string_utf8(env, "JSSystemTimeGetTimeZone", NAPI_AUTO_LENGTH, &resource);
565     napi_create_async_work(env,
566         nullptr,
567         resource,
568         [](napi_env env, void* data) {
569             AsyncContext* asyncContext = (AsyncContext*)data;
570             asyncContext->timeZone = TimeServiceClient::GetInstance()->GetTimeZone();
571         },
572         [](napi_env env, napi_status status, void* data) {
573             AsyncContext* asyncContext = (AsyncContext*)data;
574             if (asyncContext->timeZone == "") {
575                 asyncContext->errorCode = ERROR;
576             }
577             TimeCallbackPromiseInfo info;
578             info.isCallback = asyncContext->isCallback;
579             info.callback = asyncContext->callbackRef;
580             info.deferred = asyncContext->deferred;
581             info.errorCode = asyncContext->errorCode;
582             napi_value result = nullptr;
583             napi_create_string_utf8(env, asyncContext->timeZone.c_str(), asyncContext->timeZone.length(), &result);
584             TimeReturnCallbackPromise(env, info, result);
585             napi_delete_async_work(env, asyncContext->work);
586             if (asyncContext) {
587                 delete asyncContext;
588                 asyncContext = nullptr;
589             }
590         },
591         (void*)asyncContext,
592         &asyncContext->work);
593     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
594     if (asyncContext->isCallback) {
595         return TimeNapiGetNull(env);
596     } else {
597         return promise;
598     }
599 }
600 
601 EXTERN_C_START
SystemTimeExport(napi_env env,napi_value exports)602 napi_value SystemTimeExport(napi_env env, napi_value exports)
603 {
604     static napi_property_descriptor desc[] = {
605         DECLARE_NAPI_FUNCTION("setTime", JSSystemTimeSetTime),
606         DECLARE_NAPI_FUNCTION("setDate", JSSystemTimeSetTime),
607         DECLARE_NAPI_FUNCTION("setTimezone", JSSystemTimeSetTimeZone),
608         DECLARE_NAPI_FUNCTION("getCurrentTime", JSSystemTimeGetCurrentTime),
609         DECLARE_NAPI_FUNCTION("getRealActiveTime", JSSystemTimeGetRealActiveTime),
610         DECLARE_NAPI_FUNCTION("getRealTime", JSSystemTimeGetRealTime),
611         DECLARE_NAPI_FUNCTION("getDate", JSSystemTimeGetDate),
612         DECLARE_NAPI_FUNCTION("getTimezone", JSSystemTimeGetTimeZone),
613     };
614     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
615     return exports;
616 }
617 EXTERN_C_END
618 
619 static napi_module system_time_module = {
620     .nm_version = 1,
621     .nm_flags = 0,
622     .nm_filename = nullptr,
623     .nm_register_func = SystemTimeExport,
624     .nm_modname = "systemTime",
625     .nm_priv = ((void*)0),
626     .reserved = {0}
627 };
628 
SystemTimeRegister()629 extern "C" __attribute__((constructor)) void SystemTimeRegister()
630 {
631     napi_module_register(&system_time_module);
632 }
633 } // MiscServicesNapi
634 } // OHOS