ART: Refactor run-test 904

Refactor run-test so it does not depend on printf output. That way
we can run it in CTS.

Bug: 32072923
Test: art/test/testrunner/testrunner.py -b --host -t 904
Change-Id: Ia0d2e01dba4f46b81e78c88d9c50aafbc69f679e
diff --git a/test/904-object-allocation/expected.txt b/test/904-object-allocation/expected.txt
index 371d2b7..fdec470 100644
--- a/test/904-object-allocation/expected.txt
+++ b/test/904-object-allocation/expected.txt
@@ -1,8 +1,8 @@
-ObjectAllocated type java.lang.Object/java.lang.Object size 8
-ObjectAllocated type java.lang.Integer/java.lang.Integer size 16
-ObjectAllocated type java.lang.Short/java.lang.Short size 16
+[]
+[ObjectAllocated type java.lang.Object/java.lang.Object size 8, ObjectAllocated type java.lang.Integer/java.lang.Integer size 16, ObjectAllocated type java.lang.Short/java.lang.Short size 16]
 Tracking on same thread
-ObjectAllocated type java.lang.Double/java.lang.Double size 16
+[ObjectAllocated type java.lang.Double/java.lang.Double size 16]
 Tracking on same thread, not disabling tracking
-ObjectAllocated type java.lang.Double/java.lang.Double size 16
+[ObjectAllocated type java.lang.Double/java.lang.Double size 16]
 Tracking on different thread
+[]
diff --git a/test/904-object-allocation/src/art/Test904.java b/test/904-object-allocation/src/art/Test904.java
index 31e0c8c..70a4b98 100644
--- a/test/904-object-allocation/src/art/Test904.java
+++ b/test/904-object-allocation/src/art/Test904.java
@@ -17,6 +17,7 @@
 package art;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 public class Test904 {
   public static void run() throws Exception {
@@ -48,6 +49,8 @@
     // Enable actual logging callback.
     setupObjectAllocCallback(true);
 
+    System.out.println(Arrays.toString(getTrackingEventMessages()));
+
     enableAllocationTracking(null, true);
 
     l.add(new Object());
@@ -65,16 +68,19 @@
 
     l.add(new Byte((byte)0));
 
+    System.out.println(Arrays.toString(getTrackingEventMessages()));
     System.out.println("Tracking on same thread");
 
     testThread(l, true, true);
 
     l.add(new Byte((byte)0));
 
+    System.out.println(Arrays.toString(getTrackingEventMessages()));
     System.out.println("Tracking on same thread, not disabling tracking");
 
     testThread(l, true, false);
 
+    System.out.println(Arrays.toString(getTrackingEventMessages()));
     System.out.println("Tracking on different thread");
 
     testThread(l, false, true);
@@ -84,6 +90,9 @@
     // Disable actual logging callback and re-enable tracking, so we can keep the event enabled and
     // check that shutdown works correctly.
     setupObjectAllocCallback(false);
+
+    System.out.println(Arrays.toString(getTrackingEventMessages()));
+
     enableAllocationTracking(null, true);
   }
 
@@ -142,4 +151,5 @@
 
   private static native void setupObjectAllocCallback(boolean enable);
   private static native void enableAllocationTracking(Thread thread, boolean enable);
+  private static native String[] getTrackingEventMessages();
 }
diff --git a/test/904-object-allocation/tracking.cc b/test/904-object-allocation/tracking.cc
index 8de350b..20b5328 100644
--- a/test/904-object-allocation/tracking.cc
+++ b/test/904-object-allocation/tracking.cc
@@ -15,11 +15,13 @@
  */
 
 #include <iostream>
+#include <mutex>
 #include <pthread.h>
 #include <stdio.h>
 #include <vector>
 
 #include "android-base/logging.h"
+#include "android-base/stringprintf.h"
 #include "jni.h"
 #include "jvmti.h"
 #include "scoped_local_ref.h"
@@ -41,6 +43,9 @@
   return utf_chars.c_str();
 }
 
+static std::mutex gEventsMutex;
+static std::vector<std::string> gEvents;
+
 static void JNICALL ObjectAllocated(jvmtiEnv* ti_env ATTRIBUTE_UNUSED,
                                     JNIEnv* jni_env,
                                     jthread thread ATTRIBUTE_UNUSED,
@@ -51,10 +56,11 @@
   ScopedLocalRef<jclass> object_klass2(jni_env, jni_env->GetObjectClass(object));
   std::string object_klass_descriptor2 = GetClassName(jni_env, object_klass2.get());
 
-  printf("ObjectAllocated type %s/%s size %zu\n",
-         object_klass_descriptor.c_str(),
-         object_klass_descriptor2.c_str(),
-         static_cast<size_t>(size));
+  std::lock_guard<std::mutex> guard(gEventsMutex);
+  gEvents.push_back(android::base::StringPrintf("ObjectAllocated type %s/%s size %zu",
+                                                object_klass_descriptor.c_str(),
+                                                object_klass_descriptor2.c_str(),
+                                                static_cast<size_t>(size)));
 }
 
 extern "C" JNIEXPORT void JNICALL Java_art_Test904_setupObjectAllocCallback(
@@ -76,5 +82,18 @@
   JvmtiErrorToException(env, jvmti_env, ret);
 }
 
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test904_getTrackingEventMessages(
+    JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+  std::lock_guard<std::mutex> guard(gEventsMutex);
+  jobjectArray ret = CreateObjectArray(env,
+                                       static_cast<jint>(gEvents.size()),
+                                       "java/lang/String",
+                                       [&](jint i) {
+    return env->NewStringUTF(gEvents[i].c_str());
+  });
+  gEvents.clear();
+  return ret;
+}
+
 }  // namespace Test904ObjectAllocation
 }  // namespace art