From e61dc39d1479d9c33fc736a25a6be2608c107311 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 2 Sep 2022 10:51:09 -0400 Subject: [PATCH 1/4] Bump Java API level to leverage faster Date Time Offset API --- Configuration.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configuration.props b/Configuration.props index 4f8d499d9d4..0aa03683792 100644 --- a/Configuration.props +++ b/Configuration.props @@ -25,7 +25,7 @@ v4.4 19 - 21 + 26 21 $(AndroidFirstApiLevel) From f595bf476cbf3e9769770a83f8be1b20600c5433 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 2 Sep 2022 10:58:57 -0400 Subject: [PATCH 2/4] Add LocalDateTimeOffset to monovm_props --- .../java/mono/android/MonoPackageManager.java | 9 +++++++++ src/java-runtime/java/mono/android/Runtime.java | 3 ++- src/monodroid/jni/mono_android_Runtime.h | 8 ++++---- src/monodroid/jni/monodroid-glue-internal.hh | 4 ++-- src/monodroid/jni/monodroid-glue.cc | 12 +++++++----- src/monodroid/jni/monovm-properties.cc | 2 ++ src/monodroid/jni/monovm-properties.hh | 11 +++++++++-- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/java-runtime/java/mono/android/MonoPackageManager.java b/src/java-runtime/java/mono/android/MonoPackageManager.java index 4a8fac7dbdb..9bac76c135e 100644 --- a/src/java-runtime/java/mono/android/MonoPackageManager.java +++ b/src/java-runtime/java/mono/android/MonoPackageManager.java @@ -2,6 +2,9 @@ import java.io.*; import java.lang.String; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.Calendar; import java.util.Locale; import java.util.HashSet; import java.util.zip.*; @@ -42,6 +45,11 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack String dataDir = getNativeLibraryPath (context); ClassLoader loader = context.getClassLoader (); String runtimeDir = getNativeLibraryPath (runtimePackage); + int localDateTimeOffset = (Calendar.getInstance ().get (Calendar.ZONE_OFFSET) + Calendar.getInstance ().get (Calendar.DST_OFFSET)) / 1000; + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + localDateTimeOffset = OffsetDateTime.now().getOffset().getTotalSeconds(); + } // // Should the order change here, src/monodroid/jni/SharedConstants.hh must be updated accordingly @@ -106,6 +114,7 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack apks, runtimeDir, appDirs, + localDateTimeOffset, loader, MonoPackageManager_Resources.Assemblies, Build.VERSION.SDK_INT, diff --git a/src/java-runtime/java/mono/android/Runtime.java b/src/java-runtime/java/mono/android/Runtime.java index 32b3276012a..0f482543820 100644 --- a/src/java-runtime/java/mono/android/Runtime.java +++ b/src/java-runtime/java/mono/android/Runtime.java @@ -14,12 +14,13 @@ public class Runtime { Thread.setDefaultUncaughtExceptionHandler (new XamarinUncaughtExceptionHandler (Thread.getDefaultUncaughtExceptionHandler ())); } - public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName, int apiLevel, String[] environmentVariables); + public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, int localDateTimeOffset, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName, int apiLevel, String[] environmentVariables); public static native void initInternal ( String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, + int localDateTimeOffset, ClassLoader loader, String[] assemblies, int apiLevel, diff --git a/src/monodroid/jni/mono_android_Runtime.h b/src/monodroid/jni/mono_android_Runtime.h index 321df5be496..447cbbc94a7 100644 --- a/src/monodroid/jni/mono_android_Runtime.h +++ b/src/monodroid/jni/mono_android_Runtime.h @@ -10,18 +10,18 @@ extern "C" { /* * Class: mono_android_Runtime * Method: init - * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/ClassLoader;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V + * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILjava/lang/ClassLoader;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_mono_android_Runtime_init - (JNIEnv *, jclass, jstring, jobjectArray, jstring, jobjectArray, jobject, jobjectArray, jobjectArray, jstring, jint, jobjectArray); + (JNIEnv *, jclass, jstring, jobjectArray, jstring, jobjectArray, jint, jobject, jobjectArray, jobjectArray, jstring, jint, jobjectArray); /* * Class: mono_android_Runtime * Method: initInternal - * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/ClassLoader;[Ljava/lang/String;IZZ)V + * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILjava/lang/ClassLoader;[Ljava/lang/String;IZZ)V */ JNIEXPORT void JNICALL Java_mono_android_Runtime_initInternal - (JNIEnv *, jclass, jstring, jobjectArray, jstring, jobjectArray, jobject, jobjectArray, jint, jboolean, jboolean); + (JNIEnv *, jclass, jstring, jobjectArray, jstring, jobjectArray, jint, jobject, jobjectArray, jint, jboolean, jboolean); /* * Class: mono_android_Runtime diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/monodroid/jni/monodroid-glue-internal.hh index 8b0ef579bee..f35b0c2d832 100644 --- a/src/monodroid/jni/monodroid-glue-internal.hh +++ b/src/monodroid/jni/monodroid-glue-internal.hh @@ -174,8 +174,8 @@ namespace xamarin::android::internal public: void Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods); void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, - jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, - jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator, + jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, + jobject loader, jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator, jboolean haveSplitApks); #if !defined (ANDROID) jint Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index 655dac4d223..29a5121b2c0 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -2152,8 +2152,8 @@ MonodroidRuntime::install_logging_handlers () inline void MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, - jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, - jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator, + jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, + jobject loader, jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator, jboolean haveSplitApks) { char *mono_log_mask_raw = nullptr; @@ -2180,7 +2180,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl mono_opt_aot_lazy_assembly_load = application_config.aot_lazy_load ? TRUE : FALSE; { - MonoVMProperties monovm_props { home }; + MonoVMProperties monovm_props { home, localDateTimeOffset }; // NOTE: the `const_cast` breaks the contract made to MonoVMProperties that the arrays it returns won't be // modified, but it's "ok" since Mono doesn't modify them and by using `const char* const*` in MonoVMProperties @@ -2441,7 +2441,7 @@ JNI_OnLoad (JavaVM *vm, void *reserved) /* !DO NOT REMOVE! Used by the Android Designer */ JNIEXPORT void JNICALL Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, - jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, + jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, [[maybe_unused]] jobjectArray externalStorageDirs, jobjectArray assembliesJava, [[maybe_unused]] jstring packageName, jint apiLevel, [[maybe_unused]] jobjectArray environmentVariables) { @@ -2452,6 +2452,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject runtimeApksJava, runtimeNativeLibDir, appDirs, + localDateTimeOffset, loader, assembliesJava, apiLevel, @@ -2462,7 +2463,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject JNIEXPORT void JNICALL Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, - jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, + jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator, jboolean haveSplitApks) { @@ -2473,6 +2474,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, runtimeApksJava, runtimeNativeLibDir, appDirs, + localDateTimeOffset, loader, assembliesJava, apiLevel, diff --git a/src/monodroid/jni/monovm-properties.cc b/src/monodroid/jni/monovm-properties.cc index 4650d46fe1a..b98eac0b6ee 100644 --- a/src/monodroid/jni/monovm-properties.cc +++ b/src/monodroid/jni/monovm-properties.cc @@ -5,9 +5,11 @@ using namespace xamarin::android::internal; MonoVMProperties::property_array MonoVMProperties::_property_keys { RUNTIME_IDENTIFIER_KEY, APP_CONTEXT_BASE_DIRECTORY_KEY, + LOCAL_DATE_TIME_OFFSET_KEY, }; MonoVMProperties::property_array MonoVMProperties::_property_values { SharedConstants::runtime_identifier, nullptr, + nullptr, }; diff --git a/src/monodroid/jni/monovm-properties.hh b/src/monodroid/jni/monovm-properties.hh index f800b1a4261..ea316a66ee1 100644 --- a/src/monodroid/jni/monovm-properties.hh +++ b/src/monodroid/jni/monovm-properties.hh @@ -10,7 +10,7 @@ namespace xamarin::android::internal { class MonoVMProperties final { - constexpr static size_t PROPERTY_COUNT = 2; + constexpr static size_t PROPERTY_COUNT = 3; constexpr static char RUNTIME_IDENTIFIER_KEY[] = "RUNTIME_IDENTIFIER"; constexpr static size_t RUNTIME_IDENTIFIER_INDEX = 0; @@ -18,15 +18,22 @@ namespace xamarin::android::internal constexpr static char APP_CONTEXT_BASE_DIRECTORY_KEY[] = "APP_CONTEXT_BASE_DIRECTORY"; constexpr static size_t APP_CONTEXT_BASE_DIRECTORY_INDEX = 1; + constexpr static char LOCAL_DATE_TIME_OFFSET_KEY[] = "System.TimeZoneInfo.LocalDateTimeOffset"; + constexpr static size_t LOCAL_DATE_TIME_OFFSET_INDEX = 2; + using property_array = const char*[PROPERTY_COUNT]; public: - explicit MonoVMProperties (jstring_wrapper& filesDir) + explicit MonoVMProperties (jstring_wrapper& filesDir, jint localDateTimeOffset) { static_assert (PROPERTY_COUNT == N_PROPERTY_KEYS); static_assert (PROPERTY_COUNT == N_PROPERTY_VALUES); _property_values[APP_CONTEXT_BASE_DIRECTORY_INDEX] = strdup (filesDir.get_cstr ()); + + char localDateTimeOffsetBuffer[32]; + snprintf (localDateTimeOffsetBuffer, sizeof(localDateTimeOffsetBuffer), "%d", localDateTimeOffset); + _property_values[LOCAL_DATE_TIME_OFFSET_INDEX] = strdup (localDateTimeOffsetBuffer); } constexpr int property_count () const From 874d0c482df41ad1b5abf49a458d55a53a0e045e Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 2 Sep 2022 14:42:06 -0400 Subject: [PATCH 3/4] Address feedback --- src/java-runtime/java/mono/android/MonoPackageManager.java | 5 ++++- src/monodroid/jni/monovm-properties.hh | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/java-runtime/java/mono/android/MonoPackageManager.java b/src/java-runtime/java/mono/android/MonoPackageManager.java index 9bac76c135e..c5f42a87729 100644 --- a/src/java-runtime/java/mono/android/MonoPackageManager.java +++ b/src/java-runtime/java/mono/android/MonoPackageManager.java @@ -45,11 +45,14 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack String dataDir = getNativeLibraryPath (context); ClassLoader loader = context.getClassLoader (); String runtimeDir = getNativeLibraryPath (runtimePackage); - int localDateTimeOffset = (Calendar.getInstance ().get (Calendar.ZONE_OFFSET) + Calendar.getInstance ().get (Calendar.DST_OFFSET)) / 1000; + int localDateTimeOffset; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { localDateTimeOffset = OffsetDateTime.now().getOffset().getTotalSeconds(); } + else { + localDateTimeOffset = (Calendar.getInstance ().get (Calendar.ZONE_OFFSET) + Calendar.getInstance ().get (Calendar.DST_OFFSET)) / 1000; + } // // Should the order change here, src/monodroid/jni/SharedConstants.hh must be updated accordingly diff --git a/src/monodroid/jni/monovm-properties.hh b/src/monodroid/jni/monovm-properties.hh index ea316a66ee1..8a9437c738b 100644 --- a/src/monodroid/jni/monovm-properties.hh +++ b/src/monodroid/jni/monovm-properties.hh @@ -31,9 +31,9 @@ namespace xamarin::android::internal _property_values[APP_CONTEXT_BASE_DIRECTORY_INDEX] = strdup (filesDir.get_cstr ()); - char localDateTimeOffsetBuffer[32]; - snprintf (localDateTimeOffsetBuffer, sizeof(localDateTimeOffsetBuffer), "%d", localDateTimeOffset); - _property_values[LOCAL_DATE_TIME_OFFSET_INDEX] = strdup (localDateTimeOffsetBuffer); + static_local_string<32> localDateTimeOffsetBuffer; + localDateTimeOffsetBuffer.append (localDateTimeOffset); + _property_values[LOCAL_DATE_TIME_OFFSET_INDEX] = strdup (localDateTimeOffsetBuffer.get ()); } constexpr int property_count () const From 5a5af05ae63eec9334764d71cc3b49f06fb53975 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Mon, 26 Sep 2022 17:13:59 -0400 Subject: [PATCH 4/4] WIP --- src/java-runtime/java/mono/android/Runtime.java | 2 +- src/monodroid/jni/mono_android_Runtime.h | 4 ++-- src/monodroid/jni/monodroid-glue.cc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/java-runtime/java/mono/android/Runtime.java b/src/java-runtime/java/mono/android/Runtime.java index 0f482543820..01e62b2398c 100644 --- a/src/java-runtime/java/mono/android/Runtime.java +++ b/src/java-runtime/java/mono/android/Runtime.java @@ -14,7 +14,7 @@ public class Runtime { Thread.setDefaultUncaughtExceptionHandler (new XamarinUncaughtExceptionHandler (Thread.getDefaultUncaughtExceptionHandler ())); } - public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, int localDateTimeOffset, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName, int apiLevel, String[] environmentVariables); + public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName, int apiLevel, String[] environmentVariables); public static native void initInternal ( String lang, String[] runtimeApks, diff --git a/src/monodroid/jni/mono_android_Runtime.h b/src/monodroid/jni/mono_android_Runtime.h index 447cbbc94a7..a9be6770e9a 100644 --- a/src/monodroid/jni/mono_android_Runtime.h +++ b/src/monodroid/jni/mono_android_Runtime.h @@ -10,10 +10,10 @@ extern "C" { /* * Class: mono_android_Runtime * Method: init - * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILjava/lang/ClassLoader;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V + * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/ClassLoader;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_mono_android_Runtime_init - (JNIEnv *, jclass, jstring, jobjectArray, jstring, jobjectArray, jint, jobject, jobjectArray, jobjectArray, jstring, jint, jobjectArray); + (JNIEnv *, jclass, jstring, jobjectArray, jstring, jobjectArray, jobject, jobjectArray, jobjectArray, jstring, jint, jobjectArray); /* * Class: mono_android_Runtime diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index 29a5121b2c0..3600bee35e0 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -2441,7 +2441,7 @@ JNI_OnLoad (JavaVM *vm, void *reserved) /* !DO NOT REMOVE! Used by the Android Designer */ JNIEXPORT void JNICALL Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, - jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, + jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, [[maybe_unused]] jobjectArray externalStorageDirs, jobjectArray assembliesJava, [[maybe_unused]] jstring packageName, jint apiLevel, [[maybe_unused]] jobjectArray environmentVariables) { @@ -2452,7 +2452,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject runtimeApksJava, runtimeNativeLibDir, appDirs, - localDateTimeOffset, + 0, loader, assembliesJava, apiLevel,