Attach JVM to the current thread on callback.

Bug: 406779989
Test: asyncMethodTestValidationPasses

Change-Id: I1aea069f484075bff9822afcaa649dfd0951bf8d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/239974
Auto-Submit: Jim Blackler <jimblackler@google.com>
Commit-Queue: Jim Blackler <jimblackler@google.com>
Reviewed-by: Barış Kaya <bkaya@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/art/kotlin_record_conversion.cpp b/generator/templates/art/kotlin_record_conversion.cpp
index 148f7d2..742d611 100644
--- a/generator/templates/art/kotlin_record_conversion.cpp
+++ b/generator/templates/art/kotlin_record_conversion.cpp
@@ -148,6 +148,9 @@
                         //* callback.
                         UserData* userData1 = static_cast<UserData *>({{ userdata }});
                         JNIEnv *env = userData1->env;
+                        JavaVM* jvm = userData1->jvm;
+                        jvm->AttachCurrentThread(&env, NULL);
+
                         if (env->ExceptionCheck()) {
                             return;
                         }
@@ -175,7 +178,7 @@
                     };
                     //* TODO(b/330293719): free associated resources.
                     outStruct->{{ userdata }} = new UserData(
-                            {.env = env, .callback = env->NewGlobalRef(in)});
+                            {.env = env, .callback = env->NewGlobalRef(in), .jvm = c->jvm});
 
                 {% else %}
                     {{ unreachable_code() }}
diff --git a/generator/templates/art/structures.h b/generator/templates/art/structures.h
index 4f7efb4..d2489e8 100644
--- a/generator/templates/art/structures.h
+++ b/generator/templates/art/structures.h
@@ -34,6 +34,7 @@
 struct UserData {
     JNIEnv *env;
     jobject callback;
+    JavaVM *jvm;
 };
 
 // Converts Kotlin objects representing Dawn structures into native structures that can be passed
diff --git a/tools/android/webgpu/src/main/cpp/JNIContext.cpp b/tools/android/webgpu/src/main/cpp/JNIContext.cpp
index 7d35ae7..779a1f3 100644
--- a/tools/android/webgpu/src/main/cpp/JNIContext.cpp
+++ b/tools/android/webgpu/src/main/cpp/JNIContext.cpp
@@ -29,7 +29,9 @@
 
 namespace dawn::kotlin_api {
 
-JNIContext::JNIContext(JNIEnv* env) : env(env) {}
+JNIContext::JNIContext(JNIEnv* env) : env(env) {
+    env->GetJavaVM(&jvm);
+}
 
 JNIContext::~JNIContext() {
     for (auto [s, utf] : mStringsToRelease) {
diff --git a/tools/android/webgpu/src/main/cpp/JNIContext.h b/tools/android/webgpu/src/main/cpp/JNIContext.h
index d46dafa..c800ee2 100644
--- a/tools/android/webgpu/src/main/cpp/JNIContext.h
+++ b/tools/android/webgpu/src/main/cpp/JNIContext.h
@@ -51,6 +51,7 @@
 
     // Public members for convenience.
     JNIEnv* const env;
+    JavaVM* jvm;
 
     const char* GetStringUTFChars(jstring s);
     const jint* GetIntArrayElements(jintArray a);