Skip to content

[Mono.Android] pass in Context at startup #9776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions src/Mono.Android/Android.App/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ public static Context Context {
if (_context != null)
return _context;

IntPtr klass = JNIEnv.FindClass ("mono/MonoPackageManager");
try {
IntPtr field = JNIEnv.GetStaticFieldID (klass, "Context", "Landroid/content/Context;");
IntPtr lref = JNIEnv.GetStaticObjectField (klass, field);
return _context = Java.Lang.Object.GetObject<Context> (lref, JniHandleOwnership.TransferLocalRef)!;
} finally {
JNIEnv.DeleteGlobalRef (klass);
}
var gref = JNIEnvInit.applicationContext;
if (gref == IntPtr.Zero)
throw new InvalidOperationException ("JNIEnvInit.applicationContext is not set!");

return _context = Java.Lang.Object.GetObject<Context> (gref, JniHandleOwnership.TransferGlobalRef)!;
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/Mono.Android/Android.Runtime/JNIEnvInit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internal struct JnienvInitializeArgs {
public bool jniRemappingInUse;
public bool marshalMethodsEnabled;
public IntPtr grefGCUserPeerable;
public IntPtr applicationContext;
}
#pragma warning restore 0649

Expand All @@ -45,6 +46,7 @@ internal struct JnienvInitializeArgs {
internal static IntPtr grefIGCUserPeer_class;
internal static IntPtr grefGCUserPeerable_class;
internal static IntPtr java_class_loader;
internal static IntPtr applicationContext;

internal static JniRuntime? androidRuntime;

Expand Down Expand Up @@ -117,6 +119,7 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
}
}

applicationContext = JNIEnv.NewGlobalRef (args->applicationContext);
SetSynchronizationContext ();
}

Expand Down
8 changes: 2 additions & 6 deletions src/java-runtime/java/mono/android/MonoPackageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public class MonoPackageManager {
static Object lock = new Object ();
static boolean initialized;

static android.content.Context Context;

public static void LoadApplication (Context context)
{
synchronized (lock) {
Expand All @@ -40,9 +38,6 @@ public static void LoadApplication (Context context)
apks = new String[] { runtimePackage.sourceDir };
}

if (context instanceof android.app.Application) {
Context = context;
}
if (!initialized) {
android.content.IntentFilter timezoneChangedFilter = new android.content.IntentFilter (
android.content.Intent.ACTION_TIMEZONE_CHANGED
Expand Down Expand Up @@ -126,7 +121,8 @@ public static void LoadApplication (Context context)
loader,
MonoPackageManager_Resources.Assemblies,
isEmulator (),
haveSplitApks
haveSplitApks,
context
);

net.dot.android.ApplicationRegistration.registerApplications ();
Expand Down
3 changes: 2 additions & 1 deletion src/java-runtime/java/mono/android/Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public static native void initInternal (
ClassLoader loader,
String[] assemblies,
boolean isEmulator,
boolean haveSplitApks
boolean haveSplitApks,
android.content.Context context
);
public static native void register (String managedType, java.lang.Class nativeClass, String methods);
public static native void notifyTimeZoneChanged ();
Expand Down
2 changes: 1 addition & 1 deletion src/native/mono/monodroid/mono_android_Runtime.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/native/mono/monodroid/monodroid-glue-internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ namespace xamarin::android::internal
bool jniRemappingInUse;
bool marshalMethodsEnabled;
jobject grefGCUserPeerable;
jobject applicationContext;
};

using jnienv_initialize_fn = void (*) (JnienvInitializeArgs*);
Expand All @@ -119,7 +120,7 @@ namespace xamarin::android::internal
static void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava,
jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset,
jobject loader, jobjectArray assembliesJava, jboolean isEmulator,
jboolean haveSplitApks) noexcept;
jboolean haveSplitApks, jobject context) noexcept;

static jint Java_JNI_OnLoad (JavaVM *vm, void *reserved) noexcept;

Expand Down Expand Up @@ -185,7 +186,7 @@ namespace xamarin::android::internal
static void set_debug_options () noexcept;
static void parse_gdb_options () noexcept;
static void mono_runtime_init (JNIEnv *env, dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN>& runtime_args) noexcept;
static void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) noexcept;
static void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader, jobject context) noexcept;
static void set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) noexcept;

static void set_environment_variable_for_directory (const char *name, jstring_wrapper &value) noexcept
Expand All @@ -205,7 +206,7 @@ namespace xamarin::android::internal
static MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks,
jstring_array_wrapper &assemblies, jobjectArray assembliesBytes, jstring_array_wrapper &assembliesPaths,
jobject loader, bool is_root_domain, bool force_preload_assemblies,
bool have_split_apks) noexcept;
bool have_split_apks, jobject context) noexcept;

static void gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) noexcept;
static bool should_register_file (const char *filename);
Expand Down
19 changes: 11 additions & 8 deletions src/native/mono/monodroid/monodroid-glue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ MonodroidRuntime::monodroid_debugger_unhandled_exception (MonoException *ex)
}

void
MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) noexcept
MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader, jobject context) noexcept
{
constexpr std::string_view icall_typemap_java_to_managed { "Java.Interop.TypeManager::monodroid_typemap_java_to_managed" };
constexpr std::string_view icall_typemap_managed_to_java { "Android.Runtime.JNIEnv::monodroid_typemap_managed_to_java" };
Expand Down Expand Up @@ -849,6 +849,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec
init.jniAddNativeMethodRegistrationAttributePresent = application_config.jni_add_native_method_registration_attribute_present ? 1 : 0;
init.jniRemappingInUse = application_config.jni_remapping_replacement_type_count > 0 || application_config.jni_remapping_replacement_method_index_entry_count > 0;
init.marshalMethodsEnabled = application_config.marshal_methods_enabled;
init.applicationContext = context;

java_System = RuntimeUtil::get_class_from_runtime_field (env, runtimeClass, "java_lang_System", true);
java_System_identityHashCode = env->GetStaticMethodID (java_System, "identityHashCode", "(Ljava/lang/Object;)I");
Expand Down Expand Up @@ -1253,7 +1254,7 @@ MonoDomain*
MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks,
jstring_array_wrapper &assemblies, [[maybe_unused]] jobjectArray assembliesBytes,
[[maybe_unused]] jstring_array_wrapper &assembliesPaths, jobject loader, bool is_root_domain,
bool force_preload_assemblies, bool have_split_apks) noexcept
bool force_preload_assemblies, bool have_split_apks, jobject context) noexcept
{
MonoDomain* domain = create_domain (env, runtimeApks, is_root_domain, have_split_apks);
// Asserting this on desktop apparently breaks a Designer test
Expand All @@ -1275,7 +1276,7 @@ MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass
bool preload = (AndroidSystem::is_assembly_preload_enabled () || (is_running_on_desktop && force_preload_assemblies));

load_assemblies (default_alc, preload, assemblies);
init_android_runtime (env, runtimeClass, loader);
init_android_runtime (env, runtimeClass, loader, context);
osBridge.add_monodroid_domain (domain);

return domain;
Expand Down Expand Up @@ -1386,7 +1387,7 @@ inline void
MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava,
jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset,
jobject loader, jobjectArray assembliesJava, jboolean isEmulator,
jboolean haveSplitApks) noexcept
jboolean haveSplitApks, jobject context) noexcept
{
char *mono_log_mask_raw = nullptr;
char *mono_log_level_raw = nullptr;
Expand Down Expand Up @@ -1522,7 +1523,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
jstring_array_wrapper assemblies (env, assembliesJava);
jstring_array_wrapper assembliesPaths (env);
/* the first assembly is used to initialize the AppDomain name */
create_and_initialize_domain (env, klass, runtimeApks, assemblies, nullptr, assembliesPaths, loader, /*is_root_domain:*/ true, /*force_preload_assemblies:*/ false, haveSplitApks);
create_and_initialize_domain (env, klass, runtimeApks, assemblies, nullptr, assembliesPaths, loader, /*is_root_domain:*/ true, /*force_preload_assemblies:*/ false, haveSplitApks, context);

// Install our dummy exception handler on Desktop
if constexpr (is_running_on_desktop) {
Expand Down Expand Up @@ -1581,15 +1582,16 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject
loader,
assembliesJava,
/* isEmulator */ JNI_FALSE,
/* haveSplitApks */ JNI_FALSE
/* haveSplitApks */ JNI_FALSE,
/* context */ nullptr
);
}

JNIEXPORT void JNICALL
Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava,
jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader,
jobjectArray assembliesJava, jboolean isEmulator,
jboolean haveSplitApks)
jboolean haveSplitApks, jobject context)
{
MonodroidRuntime::Java_mono_android_Runtime_initInternal (
env,
Expand All @@ -1602,7 +1604,8 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang,
loader,
assembliesJava,
isEmulator,
application_config.ignore_split_configs ? false : haveSplitApks
application_config.ignore_split_configs ? false : haveSplitApks,
context
);
}

Expand Down