From b8a23f35793d3ca4eeb4f018082d23dd47088d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pereda?= Date: Wed, 14 Feb 2024 09:47:07 +0100 Subject: [PATCH] Add locale API to device service (#389) --- .../gluonhq/attach/device/DeviceService.java | 9 +++++++- .../device/impl/AndroidDeviceService.java | 11 ++++++++-- .../attach/device/impl/DeviceInfo.java | 22 +++++++++++++------ .../attach/device/impl/IOSDeviceService.java | 15 +++++++++---- .../device/src/main/native/android/c/device.c | 15 ++++++++----- .../android/dalvik/DalvikDeviceService.java | 16 +++++++++++++- modules/device/src/main/native/ios/Device.m | 12 +++++++--- .../config/jniconfig-aarch64-android.json | 2 +- .../substrate/config/jniconfig-arm64-ios.json | 2 +- .../config/jniconfig-x86_64-ios.json | 2 +- 10 files changed, 80 insertions(+), 26 deletions(-) diff --git a/modules/device/src/main/java/com/gluonhq/attach/device/DeviceService.java b/modules/device/src/main/java/com/gluonhq/attach/device/DeviceService.java index 3fd68e19..20904813 100644 --- a/modules/device/src/main/java/com/gluonhq/attach/device/DeviceService.java +++ b/modules/device/src/main/java/com/gluonhq/attach/device/DeviceService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019 Gluon + * Copyright (c) 2016, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,4 +91,11 @@ static Optional create() { * @since 3.3.0 */ boolean isWearable(); + + /** + * Returns the string representation of the current locale of the device + * @return the device locale + * @since 4.0.20 + */ + String getLocale(); } diff --git a/modules/device/src/main/java/com/gluonhq/attach/device/impl/AndroidDeviceService.java b/modules/device/src/main/java/com/gluonhq/attach/device/impl/AndroidDeviceService.java index 49f86c96..384f94b7 100644 --- a/modules/device/src/main/java/com/gluonhq/attach/device/impl/AndroidDeviceService.java +++ b/modules/device/src/main/java/com/gluonhq/attach/device/impl/AndroidDeviceService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Gluon + * Copyright (c) 2020, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +23,8 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */package com.gluonhq.attach.device.impl; + */ +package com.gluonhq.attach.device.impl; import com.gluonhq.attach.device.DeviceService; @@ -36,6 +37,7 @@ public class AndroidDeviceService implements DeviceService { static { System.loadLibrary("device"); } + private static final DeviceInfo deviceInfo = getDeviceInfo(); public AndroidDeviceService() { @@ -66,5 +68,10 @@ public boolean isWearable() { return deviceInfo.isWearable(); } + @Override + public String getLocale() { + return deviceInfo.getLocale(); + } + private static native DeviceInfo getDeviceInfo(); } \ No newline at end of file diff --git a/modules/device/src/main/java/com/gluonhq/attach/device/impl/DeviceInfo.java b/modules/device/src/main/java/com/gluonhq/attach/device/impl/DeviceInfo.java index 0e7866d0..94d969a8 100644 --- a/modules/device/src/main/java/com/gluonhq/attach/device/impl/DeviceInfo.java +++ b/modules/device/src/main/java/com/gluonhq/attach/device/impl/DeviceInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Gluon + * Copyright (c) 2020, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,20 +26,24 @@ */ package com.gluonhq.attach.device.impl; +import java.util.Locale; + public class DeviceInfo { - private String model; - private String uuid; - private String platform; - private String version; - private boolean wearable; + private final String model; + private final String uuid; + private final String platform; + private final String version; + private final boolean wearable; + private final String locale; - public DeviceInfo(String model, String uuid, String platform, String version, boolean wearable) { + public DeviceInfo(String model, String uuid, String platform, String version, boolean wearable, String locale) { this.model = model; this.uuid = uuid; this.platform = platform; this.version = version; this.wearable = wearable; + this.locale = locale; } public String getModel() { @@ -61,4 +65,8 @@ public String getVersion() { public boolean isWearable() { return wearable; } + + public String getLocale() { + return locale; + } } diff --git a/modules/device/src/main/java/com/gluonhq/attach/device/impl/IOSDeviceService.java b/modules/device/src/main/java/com/gluonhq/attach/device/impl/IOSDeviceService.java index 62f91f5b..fb71d710 100644 --- a/modules/device/src/main/java/com/gluonhq/attach/device/impl/IOSDeviceService.java +++ b/modules/device/src/main/java/com/gluonhq/attach/device/impl/IOSDeviceService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019 Gluon + * Copyright (c) 2016, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,11 +35,12 @@ public class IOSDeviceService implements DeviceService { System.loadLibrary("Device"); initDevice(); } - + private static String model; private static String uuid; private static String platform; private static String version; + private static String locale; @Override public String getModel() { @@ -66,16 +67,22 @@ public boolean isWearable() { // TODO: Find out if iOS device is wearable return false; } - + + @Override + public String getLocale() { + return locale; + } + // native private native static void initDevice(); // callback - private static void sendDeviceData(String model, String uuid, String platform, String version) { + private static void sendDeviceData(String model, String uuid, String platform, String version, String locale) { IOSDeviceService.model = model; IOSDeviceService.uuid = uuid; IOSDeviceService.platform = platform; IOSDeviceService.version = version; + IOSDeviceService.locale = locale; } } diff --git a/modules/device/src/main/native/android/c/device.c b/modules/device/src/main/native/android/c/device.c index 041a8df2..9081ada3 100644 --- a/modules/device/src/main/native/android/c/device.c +++ b/modules/device/src/main/native/android/c/device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Gluon + * Copyright (c) 2020, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,10 +38,11 @@ static jmethodID jDeviceServiceGetUuid; static jmethodID jDeviceServiceGetPlatform; static jmethodID jDeviceServiceGetVersion; static jmethodID jDeviceServiceIsWearable; +static jmethodID jDeviceServiceGetLocale; static void initializeGraalHandles(JNIEnv* env) { jGraalDeviceInfoClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "com/gluonhq/attach/device/impl/DeviceInfo")); - jGraalDeviceInfoInitMethod = (*env)->GetMethodID(env, jGraalDeviceInfoClass, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V"); + jGraalDeviceInfoInitMethod = (*env)->GetMethodID(env, jGraalDeviceInfoClass, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V"); } static void initializeDeviceDalvikHandles() { @@ -53,6 +54,7 @@ static void initializeDeviceDalvikHandles() { jDeviceServiceGetPlatform = (*dalvikEnv)->GetMethodID(dalvikEnv, jDeviceServiceClass, "getPlatform", "()Ljava/lang/String;"); jDeviceServiceGetVersion = (*dalvikEnv)->GetMethodID(dalvikEnv, jDeviceServiceClass, "getVersion", "()Ljava/lang/String;"); jDeviceServiceIsWearable = (*dalvikEnv)->GetMethodID(dalvikEnv, jDeviceServiceClass, "isWearable", "()Z"); + jDeviceServiceGetLocale = (*dalvikEnv)->GetMethodID(dalvikEnv, jDeviceServiceClass, "getLocale", "()Ljava/lang/String;"); jobject jActivity = substrateGetActivity(); jobject jtmpobj = (*dalvikEnv)->NewObject(dalvikEnv, jDeviceServiceClass, jDeviceServiceInitMethod, jActivity); @@ -101,20 +103,23 @@ JNIEXPORT jobject JNICALL Java_com_gluonhq_attach_device_impl_AndroidDeviceServi const char *responsePlatformChars = (*dalvikEnv)->GetStringUTFChars(dalvikEnv, platform, 0); jstring version = (*dalvikEnv)->CallObjectMethod(dalvikEnv, jDalvikDeviceService, jDeviceServiceGetVersion); const char *responseVersionChars = (*dalvikEnv)->GetStringUTFChars(dalvikEnv, version, 0); + jstring locale = (*dalvikEnv)->CallObjectMethod(dalvikEnv, jDalvikDeviceService, jDeviceServiceGetLocale); + const char *responseLocaleChars = (*dalvikEnv)->GetStringUTFChars(dalvikEnv, locale, 0); jboolean wearable = (*dalvikEnv)->CallBooleanMethod(dalvikEnv, jDalvikDeviceService, jDeviceServiceIsWearable); DETACH_DALVIK(); if (isDebugAttach()) { - ATTACH_LOG_FINE("Retrieved DeviceInfo: model=%s, uuid=%s, platform=%s, version=%s, wearable=%d\n", - responseModelChars, responseUuidChars, responsePlatformChars, responseVersionChars, wearable); + ATTACH_LOG_FINE("Retrieved DeviceInfo: model=%s, uuid=%s, platform=%s, version=%s, wearable=%d, locale=%s\n", + responseModelChars, responseUuidChars, responsePlatformChars, responseVersionChars, wearable, responseLocaleChars); } jstring responseModelString = (*env)->NewStringUTF(env, responseModelChars); jstring responseUuidString = (*env)->NewStringUTF(env, responseUuidChars); jstring responsePlatformString = (*env)->NewStringUTF(env, responsePlatformChars); jstring responseVersionString = (*env)->NewStringUTF(env, responseVersionChars); + jstring responseLocaleString = (*env)->NewStringUTF(env, responseLocaleChars); jobject jtmpobj = (*env)->NewObject(env, jGraalDeviceInfoClass, jGraalDeviceInfoInitMethod, responseModelString, responseUuidString, responsePlatformString, responseVersionString, - wearable); + wearable, responseLocaleString); return (*env)->NewGlobalRef(env, jtmpobj); } diff --git a/modules/device/src/main/native/android/dalvik/DalvikDeviceService.java b/modules/device/src/main/native/android/dalvik/DalvikDeviceService.java index 4d0a4e0b..e5307208 100644 --- a/modules/device/src/main/native/android/dalvik/DalvikDeviceService.java +++ b/modules/device/src/main/native/android/dalvik/DalvikDeviceService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Gluon + * Copyright (c) 2020, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ import android.provider.Settings.Secure; import android.util.Log; +import java.util.Locale; import java.util.UUID; public class DalvikDeviceService { @@ -83,4 +84,17 @@ public String getVersion() { public boolean isWearable() { return activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); } + + public String getLocale() { + Locale locale; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + locale = activity.getResources().getConfiguration().getLocales().get(0); + } else { + locale = activity.getResources().getConfiguration().locale; + } + if (debug) { + Log.v(TAG, String.format("Current locale: %s", locale.toString())); + } + return locale.toString(); + } } diff --git a/modules/device/src/main/native/ios/Device.m b/modules/device/src/main/native/ios/Device.m index 1b8407b3..669a4cf3 100644 --- a/modules/device/src/main/native/ios/Device.m +++ b/modules/device/src/main/native/ios/Device.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019 Gluon + * Copyright (c) 2016, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,7 +61,7 @@ deviceInited = 1; mat_jDeviceServiceClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "com/gluonhq/attach/device/impl/IOSDeviceService")); - mat_jDeviceService_sendDevice = (*env)->GetStaticMethodID(env, mat_jDeviceServiceClass, "sendDeviceData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + mat_jDeviceService_sendDevice = (*env)->GetStaticMethodID(env, mat_jDeviceServiceClass, "sendDeviceData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); UIDevice* currentDevice = [UIDevice currentDevice]; @@ -81,9 +81,15 @@ const char *versionChars = [deviceVersion UTF8String]; jstring argVersion = (*env)->NewStringUTF(env, versionChars); - (*env)->CallStaticVoidMethod(env, mat_jDeviceServiceClass, mat_jDeviceService_sendDevice, argModel, argId, argPlatform, argVersion); + NSLocale *locale = [NSLocale currentLocale]; + NSString *localeFormat = [NSString stringWithFormat:@"%@_%@", [locale objectForKey:NSLocaleLanguageCode], [locale objectForKey:NSLocaleCountryCode]]; + const char *localeChars = [localeFormat UTF8String]; + jstring argLocale = (*env)->NewStringUTF(env, localeChars); + + (*env)->CallStaticVoidMethod(env, mat_jDeviceServiceClass, mat_jDeviceService_sendDevice, argModel, argId, argPlatform, argVersion, argLocale); (*env)->DeleteLocalRef(env, argModel); (*env)->DeleteLocalRef(env, argId); (*env)->DeleteLocalRef(env, argPlatform); (*env)->DeleteLocalRef(env, argVersion); + (*env)->DeleteLocalRef(env, argLocale); } \ No newline at end of file diff --git a/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-aarch64-android.json b/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-aarch64-android.json index 9295f00c..74da232f 100644 --- a/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-aarch64-android.json +++ b/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-aarch64-android.json @@ -2,7 +2,7 @@ { "name" : "com.gluonhq.attach.device.impl.DeviceInfo", "methods":[ - {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean"] } + {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] } ] } ] diff --git a/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-arm64-ios.json b/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-arm64-ios.json index 2a4c2b30..aaf7f183 100644 --- a/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-arm64-ios.json +++ b/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-arm64-ios.json @@ -1,6 +1,6 @@ [ { "name" : "com.gluonhq.attach.device.impl.IOSDeviceService", - "methods":[{"name":"sendDeviceData","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String"] }] + "methods":[{"name":"sendDeviceData","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String"] }] } ] \ No newline at end of file diff --git a/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-x86_64-ios.json b/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-x86_64-ios.json index 2a4c2b30..aaf7f183 100644 --- a/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-x86_64-ios.json +++ b/modules/device/src/main/resources/META-INF/substrate/config/jniconfig-x86_64-ios.json @@ -1,6 +1,6 @@ [ { "name" : "com.gluonhq.attach.device.impl.IOSDeviceService", - "methods":[{"name":"sendDeviceData","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String"] }] + "methods":[{"name":"sendDeviceData","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String"] }] } ] \ No newline at end of file