* Copyright (c) 2022-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 "plugins/intl/android/java/jni/intl_plugin_jni.h"
#include <jni.h>
#include <string>
#include "inner_api/plugin_utils_inner.h"
#include "log.h"
#include "plugin_utils.h"
namespace OHOS::Plugin {
namespace {
const char INTL_PLUGIN_CLASS_NAME[] = "ohos/ace/plugin/intlplugin/INTLPlugin";
static const JNINativeMethod METHODS[] = {
{ "nativeInit", "()V", reinterpret_cast<void*>(INTLPluginJni::NativeInit) },
};
const char METHOD_IS24HOUR_CLOCK[] = "is24HourClock";
const char METHOD_GET_SYSTEM_LOCALE[] = "getSystemLocale";
const char METHOD_GET_SYSTEM_TIMEZONE[] = "getSystemTimezone";
const char METHOD_GET_SYSTEM_CALENDAR[] = "getSystemCalendar";
const char METHOD_GET_NUMBERING_SYSTEM[] = "getNumberingSystem";
const char METHOD_GET_DEVICE_TYPE[] = "getDeviceType";
const char SIGNATURE_IS24HOUR_CLOCK[] = "()Z";
const char SIGNATURE_GET_SYSTEM_LOCALE[] = "()Ljava/lang/String;";
const char SIGNATURE_GET_SYSTEM_TIMEZONE[] = "()Ljava/lang/String;";
const char SIGNATURE_GET_SYSTEM_CALENDAR[] = "()Ljava/lang/String;";
const char SIGNATURE_GET_NUMBERING_SYSTEM[] = "()Ljava/lang/String;";
const char SIGNATURE_GET_DEVICE_TYPE[] = "()Ljava/lang/String;";
struct {
jmethodID is24HourClock;
jmethodID getSystemLocale;
jmethodID getSystemTimezone;
jmethodID getSystemCalendar;
jmethodID getNumberingSystem;
jmethodID getDeviceType;
jobject globalRef;
} g_pluginClass;
}
bool INTLPluginJni::Register(void* env)
{
auto* jniEnv = static_cast<JNIEnv*>(env);
CHECK_NULL_RETURN(jniEnv, false);
jclass cls = jniEnv->FindClass(INTL_PLUGIN_CLASS_NAME);
CHECK_NULL_RETURN(cls, false);
bool ret = jniEnv->RegisterNatives(cls, METHODS, sizeof(METHODS) / sizeof(METHODS[0])) == 0;
jniEnv->DeleteLocalRef(cls);
if (!ret) {
LOGE("INTLPlugin JNI: RegisterNatives fail.");
return false;
}
return true;
}
void INTLPluginJni::NativeInit(JNIEnv* env, jobject jobj)
{
CHECK_NULL_VOID(env);
g_pluginClass.globalRef = env->NewGlobalRef(jobj);
CHECK_NULL_VOID(g_pluginClass.globalRef);
jclass cls = env->GetObjectClass(jobj);
CHECK_NULL_VOID(cls);
g_pluginClass.is24HourClock = env->GetMethodID(cls, METHOD_IS24HOUR_CLOCK, SIGNATURE_IS24HOUR_CLOCK);
CHECK_NULL_VOID(g_pluginClass.is24HourClock);
g_pluginClass.getSystemLocale = env->GetMethodID(cls, METHOD_GET_SYSTEM_LOCALE, SIGNATURE_GET_SYSTEM_LOCALE);
CHECK_NULL_VOID(g_pluginClass.getSystemLocale);
g_pluginClass.getSystemTimezone = env->GetMethodID(cls, METHOD_GET_SYSTEM_TIMEZONE, SIGNATURE_GET_SYSTEM_TIMEZONE);
CHECK_NULL_VOID(g_pluginClass.getSystemTimezone);
g_pluginClass.getSystemCalendar = env->GetMethodID(cls, METHOD_GET_SYSTEM_CALENDAR, SIGNATURE_GET_SYSTEM_CALENDAR);
CHECK_NULL_VOID(g_pluginClass.getSystemCalendar);
g_pluginClass.getNumberingSystem =
env->GetMethodID(cls, METHOD_GET_NUMBERING_SYSTEM, SIGNATURE_GET_NUMBERING_SYSTEM);
CHECK_NULL_VOID(g_pluginClass.getNumberingSystem);
g_pluginClass.getDeviceType = env->GetMethodID(cls, METHOD_GET_DEVICE_TYPE, SIGNATURE_GET_DEVICE_TYPE);
CHECK_NULL_VOID(g_pluginClass.getDeviceType);
env->DeleteLocalRef(cls);
}
bool INTLPluginJni::Is24HourClock()
{
bool result = true;
auto env = ARKUI_X_Plugin_GetJniEnv();
if (!(env) || !(g_pluginClass.globalRef) || !(g_pluginClass.is24HourClock)) {
LOGW("INTLPluginJni get none ptr error");
return result;
}
result = static_cast<bool>(env->CallBooleanMethod(g_pluginClass.globalRef, g_pluginClass.is24HourClock));
if (env->ExceptionCheck()) {
LOGE("INTL JNI: call is24HourClock failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
return result;
}
std::string INTLPluginJni::GetSystemLocale()
{
jstring result;
auto env = ARKUI_X_Plugin_GetJniEnv();
if (!(env) || !(g_pluginClass.globalRef) || !(g_pluginClass.getSystemLocale)) {
LOGW("INTLPluginJni get none ptr error");
return "";
}
result = static_cast<jstring>(env->CallObjectMethod(g_pluginClass.globalRef, g_pluginClass.getSystemLocale));
if (env->ExceptionCheck()) {
LOGE("INTL JNI: call getSystemLocale failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
std::string locale = env->GetStringUTFChars(result, NULL);
return locale;
}
std::string INTLPluginJni::GetSystemTimezone()
{
jstring result;
auto env = ARKUI_X_Plugin_GetJniEnv();
if (!(env) || !(g_pluginClass.globalRef) || !(g_pluginClass.getSystemTimezone)) {
LOGW("INTLPluginJni get none ptr error");
return "";
}
result = static_cast<jstring>(env->CallObjectMethod(g_pluginClass.globalRef, g_pluginClass.getSystemTimezone));
if (env->ExceptionCheck()) {
LOGE("INTL JNI: call getSystemTimezone failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
std::string timezone = env->GetStringUTFChars(result, NULL);
return timezone;
}
std::string INTLPluginJni::GetSystemCalendar()
{
jstring result;
auto env = ARKUI_X_Plugin_GetJniEnv();
if (!(env) || !(g_pluginClass.globalRef) || !(g_pluginClass.getSystemCalendar)) {
LOGW("INTLPluginJni get none ptr error");
return "";
}
result = static_cast<jstring>(env->CallObjectMethod(g_pluginClass.globalRef, g_pluginClass.getSystemCalendar));
if (env->ExceptionCheck()) {
LOGE("INTL JNI: call getSystemCalendar failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
std::string calendar = env->GetStringUTFChars(result, NULL);
return calendar;
}
std::string INTLPluginJni::GetNumberingSystem()
{
jstring result;
auto env = ARKUI_X_Plugin_GetJniEnv();
if (!(env) || !(g_pluginClass.globalRef) || !(g_pluginClass.getNumberingSystem)) {
LOGW("INTLPluginJni get none ptr error");
return "";
}
result = static_cast<jstring>(env->CallObjectMethod(g_pluginClass.globalRef, g_pluginClass.getNumberingSystem));
if (env->ExceptionCheck()) {
LOGE("INTL JNI: call getNumberingSystem failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
std::string numberingSystem = env->GetStringUTFChars(result, NULL);
return numberingSystem;
}
std::string INTLPluginJni::GetDeviceType()
{
std::string result = "phones";
auto env = ARKUI_X_Plugin_GetJniEnv();
if (!(env) || !(g_pluginClass.globalRef) || !(g_pluginClass.getDeviceType)) {
LOGW("INTLPluginJni get none ptr error");
return "";
}
auto jString = static_cast<jstring>(env->CallObjectMethod(g_pluginClass.globalRef, g_pluginClass.getDeviceType));
if (env->ExceptionCheck()) {
LOGE("INTL JNI: call getDeviceType failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
result = env->GetStringUTFChars(jString, NULL);
if (jString) {
env->DeleteLocalRef(jString);
}
return result;
}
}