• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <ani.h>
17 #include <array>
18 #include <iostream>
19 #include <ctime>
20 #include "time_hilog.h"
21 #include "time_service_client.h"
22 
23 using namespace OHOS::MiscServices;
24 
25 constexpr ani_long SECS_TO_NANO = 1000000000;
26 constexpr ani_long SECS_TO_MILLI = 1000;
27 constexpr ani_long NANO_TO_MILLI = 1000000;
28 
GetRealTime(ani_boolean isNano)29 static ani_long GetRealTime(ani_boolean isNano)
30 {
31     struct timespec ts;
32 
33     if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
34         TIME_HILOGE(TIME_MODULE_JS_ANI, "failed clock_gettime, errno: %{public}s", strerror(errno));
35         return 0;
36     }
37 
38     if (isNano) {
39         return ts.tv_sec * SECS_TO_NANO + ts.tv_nsec;
40     }
41 
42     return ts.tv_sec * SECS_TO_MILLI + ts.tv_nsec / NANO_TO_MILLI;
43 }
44 
GetTime(ani_env * env,ani_object booleanObject)45 static ani_double GetTime([[maybe_unused]] ani_env *env, ani_object booleanObject)
46 {
47     ani_boolean isUndefined = false;
48     env->Reference_IsUndefined(booleanObject, &isUndefined);
49     if (isUndefined) {
50         return GetRealTime(false);
51     }
52     ani_boolean isNano;
53     if (ANI_OK !=env->Object_CallMethodByName_Boolean(booleanObject, "unboxed", nullptr, &isNano)) {
54         TIME_HILOGE(TIME_MODULE_JS_ANI, "Object_CallMethodByName_Boolean Fail");
55     }
56     return GetRealTime(isNano);
57 }
58 
GetTimeZone(ani_env * env)59 static ani_string GetTimeZone([[maybe_unused]] ani_env *env)
60 {
61     std::string timezone;
62     auto status = TimeServiceClient::GetInstance()->GetTimeZone(timezone);
63     if (ANI_OK != status) {
64         TIME_HILOGE(TIME_MODULE_JS_ANI, "GetTimeZone failed, errno: %{public}d", status);
65     }
66     ani_string tzCstr;
67     env->String_NewUTF8(timezone.c_str(), timezone.size(), &tzCstr);
68     return tzCstr;
69 }
70 
ANI_Constructor(ani_vm * vm,uint32_t * result)71 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
72 {
73     ani_env *env;
74     if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
75         TIME_HILOGE(TIME_MODULE_JS_ANI, "Unsupported ANI_VERSION_1");
76         return ANI_ERROR;
77     }
78 
79     static const char *namespaceName = "L@ohos/systemDateTime/systemDateTime;";
80     ani_namespace ns;
81     if (ANI_OK != env->FindNamespace(namespaceName, &ns)) {
82         TIME_HILOGE(TIME_MODULE_JS_ANI, "Not found '%{public}s'", namespaceName);
83         return ANI_ERROR;
84     }
85 
86     std::array methods = {
87         ani_native_function {"getTime", nullptr, reinterpret_cast<void *>(GetTime)},
88         ani_native_function {"getTimezoneSync", ":Lstd/core/String;", reinterpret_cast<void *>(GetTimeZone)},
89     };
90 
91     if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
92         TIME_HILOGE(TIME_MODULE_JS_ANI, "Cannot bind native methods to '%{public}s'", namespaceName);
93         return ANI_ERROR;
94     };
95 
96     *result = ANI_VERSION_1;
97     return ANI_OK;
98 }