* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_jni.h"
#include <algorithm>
#include <cctype>
#include <jni.h>
#include <string>
#include "plugin_utils.h"
#include "time_common.h"
#include "time_hilog.h"
using namespace OHOS::MiscServices;
namespace OHOS::Time {
namespace {
const char TIME_CLASS_NAME[] = "ohos/ace/plugin/timeplugin/TimePlugin";
static const JNINativeMethod METHODS[] = {
{
"nativeInit",
"()V",
reinterpret_cast<void*>(&TimeJni::NativeInit)
},
};
static const char GET_TIME_ZONE_METHOD[] = "getTimeZone";
static const char GET_TIME_ZONE_METHOD_PARAM[] = "([Ljava/lang/String;)I";
struct {
jobject globalRef;
jmethodID getTimeZone;
} g_timeClass;
}
bool TimeJni::Register(void* env)
{
TIME_HILOGI(TIME_MODULE_JNI, "TiemJni Register start");
auto* jniEnv = static_cast<JNIEnv*>(env);
CHECK_AND_RETURN_RET_LOG(TIME_MODULE_JNI, jniEnv, false);
jclass cls = jniEnv->FindClass(TIME_CLASS_NAME);
CHECK_AND_RETURN_RET_LOG(TIME_MODULE_JNI, cls, false);
bool ret = jniEnv->RegisterNatives(cls, METHODS, sizeof(METHODS) / sizeof(METHODS[0])) == 0;
jniEnv->DeleteLocalRef(cls);
if (!ret) {
TIME_HILOGE(TIME_MODULE_JNI, "TiemJni JNI: RegisterNatives fail.");
return false;
}
TIME_HILOGI(TIME_MODULE_JNI, "TiemJni Register end");
return true;
}
void TimeJni::NativeInit(JNIEnv* env, jobject jobj)
{
TIME_HILOGI(TIME_MODULE_JNI, "TiemJni NativeInit start");
CHECK_AND_RETURN_LOG(TIME_MODULE_JNI, env);
g_timeClass.globalRef = env->NewGlobalRef(jobj);
CHECK_AND_RETURN_LOG(TIME_MODULE_JNI, g_timeClass.globalRef);
jclass cls = env->GetObjectClass(jobj);
CHECK_AND_RETURN_LOG(TIME_MODULE_JNI, cls);
g_timeClass.getTimeZone = env->GetMethodID(cls, GET_TIME_ZONE_METHOD, GET_TIME_ZONE_METHOD_PARAM);
CHECK_AND_RETURN_LOG(TIME_MODULE_JNI, g_timeClass.getTimeZone);
env->DeleteLocalRef(cls);
TIME_HILOGI(TIME_MODULE_JNI, "TiemJni NativeInit end");
}
int32_t TimeJni::GetTimeZone(std::string &timezoneId)
{
auto env = ARKUI_X_Plugin_GetJniEnv();
CHECK_AND_RETURN_RET_LOG(TIME_MODULE_JNI, env, E_TIME_NULLPTR);
CHECK_AND_RETURN_RET_LOG(TIME_MODULE_JNI, g_timeClass.globalRef, E_TIME_NULLPTR);
CHECK_AND_RETURN_RET_LOG(TIME_MODULE_JNI, g_timeClass.getTimeZone, E_TIME_NULLPTR);
jclass stringClass = env->FindClass("java/lang/String");
jobjectArray javaArray = env->NewObjectArray(1, stringClass, nullptr);
jint retJint = env->CallIntMethod(g_timeClass.globalRef, g_timeClass.getTimeZone, javaArray);
int ret = static_cast<int>(retJint);
if (ret == E_TIME_OK) {
jstring stringElement = (jstring)env->GetObjectArrayElement(javaArray, 0);
const char* pStringElement = env->GetStringUTFChars(stringElement, nullptr);
if (pStringElement != nullptr) {
timezoneId = pStringElement;
env->ReleaseStringUTFChars(stringElement, pStringElement);
} else {
ret = E_TIME_DEAL_FAILED;
}
env->DeleteLocalRef(stringElement);
}
env->DeleteLocalRef(javaArray);
return ret;
}
}