Fix UnsatisfiedLinkError in CtsJvmti tests

A few CtsJvmti tests were failing due to the test setup racing with
the process that attaches the agent and loads the native library.
This change registers the native methods to fix the issue.

Bug: 112338190
Test: atest CtsJvmtiRedefineClassesHostTestCases \
            CtsJvmtiTaggingHostTestCases \
            CtsJvmtiTrackingHostTestCases

Change-Id: If2a1e838a4a706d06554a1e2c3674ee901c73229
(cherry picked from commit fa112a05f89055ceae16ab8b007849a9f882759b)
Merged-In: If2a1e838a4a706d06554a1e2c3674ee901c73229
diff --git a/hostsidetests/jvmti/allocation-tracking/app/src/android/jvmti/cts/JvmtiTrackingTest.java b/hostsidetests/jvmti/allocation-tracking/app/src/android/jvmti/cts/JvmtiTrackingTest.java
index 7a13e79..6c22f37 100644
--- a/hostsidetests/jvmti/allocation-tracking/app/src/android/jvmti/cts/JvmtiTrackingTest.java
+++ b/hostsidetests/jvmti/allocation-tracking/app/src/android/jvmti/cts/JvmtiTrackingTest.java
@@ -22,16 +22,12 @@
 import art.Main;
 
 /**
- * Check tagging-related functionality.
+ * Check tracking-related functionality.
  */
 public class JvmtiTrackingTest extends JvmtiTestBase {
 
     @Before
     public void setUp() throws Exception {
-        // Bind our native methods.
-        Main.bindAgentJNI("android/jvmti/cts/JvmtiTrackingTest",
-                getClass().getClassLoader());
-
         prefetchClassNames();
     }
 
diff --git a/hostsidetests/jvmti/base/jni/cts_agent.cpp b/hostsidetests/jvmti/base/jni/cts_agent.cpp
index 665a47e..4499f4b 100644
--- a/hostsidetests/jvmti/base/jni/cts_agent.cpp
+++ b/hostsidetests/jvmti/base/jni/cts_agent.cpp
@@ -25,10 +25,24 @@
 
 namespace art {
 
+extern void register_art_Main(jvmtiEnv*, JNIEnv*);
+extern void register_android_jvmti_cts_JvmtiRedefineClassesTest(jvmtiEnv*, JNIEnv*);
+extern void register_android_jvmti_cts_JvmtiTaggingTest(jvmtiEnv*, JNIEnv*);
+extern void register_android_jvmti_cts_JvmtiTrackingTest(jvmtiEnv*, JNIEnv*);
+
 static void InformMainAttach(jvmtiEnv* jenv,
                              JNIEnv* env,
                              const char* class_name,
                              const char* method_name) {
+  // Register native methods from available classes
+  // The agent is used with each test class, but we don't know which class is currently available.
+  // For that reason, we try to register the native methods in each one. Each function returns
+  // without throwing an error if the specified class can't be found.
+  register_art_Main(jenv, env);
+  register_android_jvmti_cts_JvmtiRedefineClassesTest(jenv, env);
+  register_android_jvmti_cts_JvmtiTaggingTest(jenv, env);
+  register_android_jvmti_cts_JvmtiTrackingTest(jenv, env);
+
   // Use JNI to load the class.
   ScopedLocalRef<jclass> klass(env, FindClass(jenv, env, class_name, nullptr));
   CHECK(klass.get() != nullptr) << class_name;
diff --git a/hostsidetests/jvmti/base/jni/redefine.cpp b/hostsidetests/jvmti/base/jni/redefine.cpp
index f96108c..003b909 100644
--- a/hostsidetests/jvmti/base/jni/redefine.cpp
+++ b/hostsidetests/jvmti/base/jni/redefine.cpp
@@ -23,6 +23,7 @@
 
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "jni_binder.h"
 #include "jni_helper.h"
 #include "jvmti_helper.h"
 #include "jvmti.h"
@@ -172,5 +173,40 @@
   env->ReleaseByteArrayElements(dex_bytes, redef_bytes, 0);
 }
 
+static JNINativeMethod gMethods[] = {
+  { "redefineClass", "(Ljava/lang/Class;[B)I",
+          (void*)Java_android_jvmti_cts_JvmtiRedefineClassesTest_redefineClass },
+
+  { "retransformClass", "(Ljava/lang/Class;)I",
+          (void*)Java_android_jvmti_cts_JvmtiRedefineClassesTest_retransformClass },
+
+  { "setTransformationEvent", "(Z)V",
+          (void*)Java_android_jvmti_cts_JvmtiRedefineClassesTest_setTransformationEvent },
+
+  { "clearTransformations", "()V",
+          (void*)Java_android_jvmti_cts_JvmtiRedefineClassesTest_clearTransformations },
+
+  { "setPopTransformations", "(Z)V",
+          (void*)Java_android_jvmti_cts_JvmtiRedefineClassesTest_setPopTransformations },
+
+  { "pushTransformationResult", "(Ljava/lang/String;[B)V",
+          (void*)Java_android_jvmti_cts_JvmtiRedefineClassesTest_pushTransformationResult },
+};
+
+void register_android_jvmti_cts_JvmtiRedefineClassesTest(jvmtiEnv* jenv, JNIEnv* env) {
+  ScopedLocalRef<jclass> klass(env, FindClass(jenv, env,
+          "android/jvmti/cts/JvmtiRedefineClassesTest", nullptr));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    return;
+  }
+
+  env->RegisterNatives(klass.get(), gMethods, sizeof(gMethods) / sizeof(JNINativeMethod));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    LOG(ERROR) << "Could not register natives for JvmtiRedefineClassesTest class";
+  }
+}
+
 }  // namespace art
 
diff --git a/hostsidetests/jvmti/base/jni/tagging.cpp b/hostsidetests/jvmti/base/jni/tagging.cpp
index 372805b..d2208f3 100644
--- a/hostsidetests/jvmti/base/jni/tagging.cpp
+++ b/hostsidetests/jvmti/base/jni/tagging.cpp
@@ -18,6 +18,7 @@
 
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "jni_binder.h"
 #include "jni_helper.h"
 #include "jvmti_helper.h"
 #include "jvmti.h"
@@ -127,5 +128,48 @@
   return CreateObjectArray(env, 3, "java/lang/Object", callback);
 }
 
+static JNINativeMethod gMethodsForMain[] = {
+  { "setTag", "(Ljava/lang/Object;J)V",
+          (void*)Java_android_jvmti_cts_JniBindings_setTag },
+
+  { "getTag", "(Ljava/lang/Object;)J",
+          (void*)Java_android_jvmti_cts_JniBindings_getTag },
+};
+
+void register_art_Main(jvmtiEnv* jenv, JNIEnv* env) {
+  ScopedLocalRef<jclass> klass(env, FindClass(jenv, env, "art/Main", nullptr));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    return;
+  }
+
+  env->RegisterNatives(klass.get(), gMethodsForMain,
+          sizeof(gMethodsForMain) / sizeof(JNINativeMethod));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    LOG(ERROR) << "Could not register natives for Main class";
+  }
+}
+
+static JNINativeMethod gMethods[] = {
+  { "getTaggedObjects", "([JZZ)[Ljava/lang/Object;",
+          (void*)Java_android_jvmti_cts_JvmtiTaggingTest_getTaggedObjects },
+};
+
+void register_android_jvmti_cts_JvmtiTaggingTest(jvmtiEnv* jenv, JNIEnv* env) {
+  ScopedLocalRef<jclass> klass(env, FindClass(jenv, env,
+          "android/jvmti/cts/JvmtiTaggingTest", nullptr));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    return;
+  }
+
+  env->RegisterNatives(klass.get(), gMethods, sizeof(gMethods) / sizeof(JNINativeMethod));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    LOG(ERROR) << "Could not register natives for JvmtiTaggingTest class";
+  }
+}
+
 }  // namespace art
 
diff --git a/hostsidetests/jvmti/base/jni/tracking.cpp b/hostsidetests/jvmti/base/jni/tracking.cpp
index a07d653..0503e82 100644
--- a/hostsidetests/jvmti/base/jni/tracking.cpp
+++ b/hostsidetests/jvmti/base/jni/tracking.cpp
@@ -21,6 +21,7 @@
 
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
+#include "jni_binder.h"
 #include "jvmti_helper.h"
 #include "scoped_local_ref.h"
 #include "scoped_utf_chars.h"
@@ -93,4 +94,30 @@
   return env->NewStringUTF(result.c_str());
 }
 
+static JNINativeMethod gMethods[] = {
+  { "setupObjectAllocCallback", "(Z)V",
+          (void*)Java_android_jvmti_cts_JvmtiTrackingTest_setupObjectAllocCallback },
+
+  { "enableAllocationTracking", "(Ljava/lang/Thread;Z)V",
+          (void*)Java_android_jvmti_cts_JvmtiTrackingTest_enableAllocationTracking },
+
+  { "getAndResetAllocationTrackingString", "()Ljava/lang/String;",
+          (void*)Java_android_jvmti_cts_JvmtiTrackingTest_getAndResetAllocationTrackingString },
+};
+
+void register_android_jvmti_cts_JvmtiTrackingTest(jvmtiEnv* jenv, JNIEnv* env) {
+  ScopedLocalRef<jclass> klass(env, FindClass(jenv, env,
+          "android/jvmti/cts/JvmtiTrackingTest", nullptr));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    return;
+  }
+
+  env->RegisterNatives(klass.get(), gMethods, sizeof(gMethods) / sizeof(JNINativeMethod));
+  if (env->ExceptionCheck()) {
+    env->ExceptionClear();
+    LOG(ERROR) << "Could not register natives for JvmtiTrackingTest class";
+  }
+}
+
 }  // namespace art