Skip to content

Commit

Permalink
[WIP] Move designer specific code to a separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
grendello committed Mar 1, 2021
1 parent 6b663c2 commit 922e697
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 148 deletions.
1 change: 1 addition & 0 deletions src/monodroid/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ if(ANDROID)
else()
list(APPEND XAMARIN_MONODROID_SOURCES
${SOURCES_DIR}/designer-assemblies.cc
${SOURCES_DIR}/monodroid-glue-designer.cc
${JAVA_INTEROP_SRC_PATH}/java-interop-gc-bridge-mono.cc
${JAVA_INTEROP_SRC_PATH}/java-interop-jvm.cc
)
Expand Down
2 changes: 2 additions & 0 deletions src/monodroid/jni/mono_android_Runtime.h

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

147 changes: 147 additions & 0 deletions src/monodroid/jni/monodroid-glue-designer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
//
// Android designer support code, not used on devices
//
#include "globals.hh"
#include "mono_android_Runtime.h"
#include "monodroid-glue-internal.hh"

using namespace xamarin::android::internal;

// DO NOT USE ON NORMAL X.A
// This function only works with the custom TypeManager embedded with the designer process.
force_inline static void
reinitialize_android_runtime_type_manager (JNIEnv *env)
{
jclass typeManager = env->FindClass ("mono/android/TypeManager");
env->UnregisterNatives (typeManager);

jmethodID resetRegistration = env->GetStaticMethodID (typeManager, "resetRegistration", "()V");
env->CallStaticVoidMethod (typeManager, resetRegistration);

env->DeleteLocalRef (typeManager);
}

inline void
MonodroidRuntime::shutdown_android_runtime (MonoDomain *domain)
{
MonoClass *runtime = get_android_runtime_class (domain);
MonoMethod *method = mono_class_get_method_from_name (runtime, "Exit", 0);

utils.monodroid_runtime_invoke (domain, method, nullptr, nullptr, nullptr);
}

inline jint
MonodroidRuntime::Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava,
jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
{
log_info (LOG_DEFAULT, "CREATING NEW CONTEXT");
reinitialize_android_runtime_type_manager (env);
MonoDomain *root_domain = mono_get_root_domain ();
mono_jit_thread_attach (root_domain);

jstring_array_wrapper runtimeApks (env, runtimeApksJava);
jstring_array_wrapper assemblies (env, assembliesJava);
jstring_array_wrapper assembliePaths (env, assembliesPaths);
MonoDomain *domain = create_and_initialize_domain (env, klass, runtimeApks, assemblies, assembliesBytes, assembliePaths, loader, /*is_root_domain:*/ false, force_preload_assemblies);
mono_domain_set (domain, FALSE);
int domain_id = mono_domain_get_id (domain);
current_context_id = domain_id;
log_info (LOG_DEFAULT, "Created new context with id %d\n", domain_id);
return domain_id;
}

inline void
MonodroidRuntime::Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID)
{
log_info (LOG_DEFAULT, "SWITCHING CONTEXT");
MonoDomain *domain = mono_domain_get_by_id ((int)contextID);
if (current_context_id != (int)contextID) {
mono_domain_set (domain, TRUE);
// Reinitialize TypeManager so that its JNI handle goes into the right domain
reinitialize_android_runtime_type_manager (env);
}
current_context_id = (int)contextID;
}

inline void
MonodroidRuntime::Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array)
{
MonoDomain *root_domain = mono_get_root_domain ();
mono_jit_thread_attach (root_domain);
current_context_id = -1;

jint *contextIDs = env->GetIntArrayElements (array, nullptr);
jsize count = env->GetArrayLength (array);

log_info (LOG_DEFAULT, "Cleaning %d domains", count);

for (jsize i = 0; i < count; i++) {
int domain_id = contextIDs[i];
MonoDomain *domain = mono_domain_get_by_id (domain_id);

if (domain == nullptr)
continue;
log_info (LOG_DEFAULT, "Shutting down domain `%d'", contextIDs[i]);
shutdown_android_runtime (domain);
osBridge.remove_monodroid_domain (domain);
designerAssemblies.clear_for_domain (domain);
}
osBridge.on_destroy_contexts ();
for (jsize i = 0; i < count; i++) {
int domain_id = contextIDs[i];
MonoDomain *domain = mono_domain_get_by_id (domain_id);

if (domain == nullptr)
continue;
log_info (LOG_DEFAULT, "Unloading domain `%d'", contextIDs[i]);
mono_domain_unload (domain);
}
env->ReleaseIntArrayElements (array, contextIDs, JNI_ABORT);

reinitialize_android_runtime_type_manager (env);

log_info (LOG_DEFAULT, "All domain cleaned up");
}

JNIEXPORT jint
JNICALL Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
{
return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
env,
klass,
runtimeApksJava,
assembliesJava,
assembliesBytes,
assembliesPaths,
loader,
force_preload_assemblies
);
}

/* !DO NOT REMOVE! Used by older versions of the Android Designer (pre-16.4) */
JNIEXPORT jint
JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobject loader)
{
return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
env,
klass,
runtimeApksJava,
assembliesJava,
nullptr, // assembliesBytes
nullptr, // assembliesPaths
loader,
false // force_preload_assemblies
);
}

JNIEXPORT void
JNICALL Java_mono_android_Runtime_switchToContext (JNIEnv *env, [[maybe_unused]] jclass klass, jint contextID)
{
monodroidRuntime.Java_mono_android_Runtime_switchToContext (env, contextID);
}

JNIEXPORT void
JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, [[maybe_unused]] jclass klass, jintArray array)
{
monodroidRuntime.Java_mono_android_Runtime_destroyContexts (env, array);
}
4 changes: 3 additions & 1 deletion src/monodroid/jni/monodroid-glue-internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,13 @@ namespace xamarin::android::internal
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);
#if !defined (ANDROID)
jint Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava,
jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies);
void Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID);
void Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array);
void shutdown_android_runtime (MonoDomain *domain);
#endif
jint Java_JNI_OnLoad (JavaVM *vm, void *reserved);

int get_android_api_level () const
Expand Down Expand Up @@ -239,7 +242,6 @@ namespace xamarin::android::internal
}

MonoClass* get_android_runtime_class (MonoDomain *domain);
void shutdown_android_runtime (MonoDomain *domain);
MonoDomain* create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain);
MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks,
jstring_array_wrapper &assemblies, jobjectArray assembliesBytes, jstring_array_wrapper &assembliesPaths,
Expand Down
149 changes: 2 additions & 147 deletions src/monodroid/jni/monodroid-glue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks,

size_t cur_num_assemblies = embeddedAssemblies.register_from<should_register_file> (apk_file.get_cstr ());

if (strstr (apk_file.get_cstr (), "/Mono.Android.DebugRuntime") == nullptr &&
strstr (apk_file.get_cstr (), "/Mono.Android.Platform.ApiLevel_") == nullptr)
*out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies);
*out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies);
prev_num_assemblies = cur_num_assemblies;
}
}
Expand Down Expand Up @@ -1018,7 +1016,7 @@ MonodroidRuntime::init_android_runtime (MonoDomain *domain, JNIEnv *env, jclass
}
}

inline MonoClass*
MonoClass*
MonodroidRuntime::get_android_runtime_class (MonoDomain *domain)
{
MonoAssembly *assm = utils.monodroid_load_assembly (domain, "Mono.Android");
Expand All @@ -1028,15 +1026,6 @@ MonodroidRuntime::get_android_runtime_class (MonoDomain *domain)
return runtime;
}

inline void
MonodroidRuntime::shutdown_android_runtime (MonoDomain *domain)
{
MonoClass *runtime = get_android_runtime_class (domain);
MonoMethod *method = mono_class_get_method_from_name (runtime, "Exit", 0);

utils.monodroid_runtime_invoke (domain, method, nullptr, nullptr, nullptr);
}

inline void
MonodroidRuntime::propagate_uncaught_exception (MonoDomain *domain, JNIEnv *env, jobject javaThread, jthrowable javaException)
{
Expand Down Expand Up @@ -2016,97 +2005,6 @@ JNICALL Java_mono_android_Runtime_register (JNIEnv *env, [[maybe_unused]] jclass
monodroidRuntime.Java_mono_android_Runtime_register (env, managedType, nativeClass, methods);
}

// DO NOT USE ON NORMAL X.A
// This function only works with the custom TypeManager embedded with the designer process.
static void
reinitialize_android_runtime_type_manager (JNIEnv *env)
{
jclass typeManager = env->FindClass ("mono/android/TypeManager");
env->UnregisterNatives (typeManager);

jmethodID resetRegistration = env->GetStaticMethodID (typeManager, "resetRegistration", "()V");
env->CallStaticVoidMethod (typeManager, resetRegistration);

env->DeleteLocalRef (typeManager);
}

inline jint
MonodroidRuntime::Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava,
jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
{
log_info (LOG_DEFAULT, "CREATING NEW CONTEXT");
reinitialize_android_runtime_type_manager (env);
MonoDomain *root_domain = mono_get_root_domain ();
mono_jit_thread_attach (root_domain);

jstring_array_wrapper runtimeApks (env, runtimeApksJava);
jstring_array_wrapper assemblies (env, assembliesJava);
jstring_array_wrapper assembliePaths (env, assembliesPaths);
MonoDomain *domain = create_and_initialize_domain (env, klass, runtimeApks, assemblies, assembliesBytes, assembliePaths, loader, /*is_root_domain:*/ false, force_preload_assemblies);
mono_domain_set (domain, FALSE);
int domain_id = mono_domain_get_id (domain);
current_context_id = domain_id;
log_info (LOG_DEFAULT, "Created new context with id %d\n", domain_id);
return domain_id;
}

inline void
MonodroidRuntime::Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID)
{
log_info (LOG_DEFAULT, "SWITCHING CONTEXT");
MonoDomain *domain = mono_domain_get_by_id ((int)contextID);
if (current_context_id != (int)contextID) {
mono_domain_set (domain, TRUE);
// Reinitialize TypeManager so that its JNI handle goes into the right domain
reinitialize_android_runtime_type_manager (env);
}
current_context_id = (int)contextID;
}

inline void
MonodroidRuntime::Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array)
{
MonoDomain *root_domain = mono_get_root_domain ();
mono_jit_thread_attach (root_domain);
current_context_id = -1;

jint *contextIDs = env->GetIntArrayElements (array, nullptr);
jsize count = env->GetArrayLength (array);

log_info (LOG_DEFAULT, "Cleaning %d domains", count);

for (jsize i = 0; i < count; i++) {
int domain_id = contextIDs[i];
MonoDomain *domain = mono_domain_get_by_id (domain_id);

if (domain == nullptr)
continue;
log_info (LOG_DEFAULT, "Shutting down domain `%d'", contextIDs[i]);
shutdown_android_runtime (domain);
osBridge.remove_monodroid_domain (domain);
#ifndef ANDROID
designerAssemblies.clear_for_domain (domain);
#endif
}
osBridge.on_destroy_contexts ();
#ifndef ANDROID
for (jsize i = 0; i < count; i++) {
int domain_id = contextIDs[i];
MonoDomain *domain = mono_domain_get_by_id (domain_id);

if (domain == nullptr)
continue;
log_info (LOG_DEFAULT, "Unloading domain `%d'", contextIDs[i]);
mono_domain_unload (domain);
}
#endif // !defined(ANDROID)
env->ReleaseIntArrayElements (array, contextIDs, JNI_ABORT);

reinitialize_android_runtime_type_manager (env);

log_info (LOG_DEFAULT, "All domain cleaned up");
}

char*
MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass)
{
Expand Down Expand Up @@ -2146,49 +2044,6 @@ get_jnienv (void)
return osBridge.ensure_jnienv ();
}

JNIEXPORT jint
JNICALL Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
{
return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
env,
klass,
runtimeApksJava,
assembliesJava,
assembliesBytes,
assembliesPaths,
loader,
force_preload_assemblies
);
}

/* !DO NOT REMOVE! Used by older versions of the Android Designer (pre-16.4) */
JNIEXPORT jint
JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobject loader)
{
return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
env,
klass,
runtimeApksJava,
assembliesJava,
nullptr, // assembliesBytes
nullptr, // assembliesPaths
loader,
false // force_preload_assemblies
);
}

JNIEXPORT void
JNICALL Java_mono_android_Runtime_switchToContext (JNIEnv *env, [[maybe_unused]] jclass klass, jint contextID)
{
monodroidRuntime.Java_mono_android_Runtime_switchToContext (env, contextID);
}

JNIEXPORT void
JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, [[maybe_unused]] jclass klass, jintArray array)
{
monodroidRuntime.Java_mono_android_Runtime_destroyContexts (env, array);
}

JNIEXPORT void
JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, [[maybe_unused]] jclass klass, jobject javaThread, jthrowable javaException)
{
Expand Down

0 comments on commit 922e697

Please sign in to comment.