Merge "Make the log format more realistic" into main am: e2f6a591c7 am: 3863a8d715

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3367287

Change-Id: Icadbc25a65434060e5e33ca659074412cd519c0f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 1dd9d46..f8737a5 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -75,7 +75,7 @@
 @android.ravenwood.annotation.RavenwoodClassLoadHook(
         "com.android.platform.test.ravenwood.runtimehelper.ClassLoadHook.onClassLoaded")
 // Uncomment the following annotation to switch to the Java substitution version.
-@android.ravenwood.annotation.RavenwoodRedirectionClass("Log_host")
+@android.ravenwood.annotation.RavenwoodRedirectionClass("Log_ravenwood")
 public final class Log {
     /** @hide */
     @IntDef({ASSERT, ERROR, WARN, INFO, DEBUG, VERBOSE})
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index e730a29..b3987f4 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -58,6 +58,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Log;
+import android.util.Log_ravenwood;
 import android.view.DisplayAdjustments;
 
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -217,6 +218,9 @@
         // Some process-wide initialization. (maybe redirect stdout/stderr)
         RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME);
 
+        // Redirect stdout/stdin to the Log API.
+        RuntimeInit.redirectLogStreams();
+
         dumpCommandLineArgs();
 
         // We haven't initialized liblog yet, so directly write to System.out here.
@@ -230,6 +234,8 @@
         // Make sure libravenwood_runtime is loaded.
         System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));
 
+        Log_ravenwood.onRavenwoodRuntimeNativeReady();
+
         // Do the basic set up for the android sysprops.
         RavenwoodSystemProperties.initialize();
 
@@ -247,9 +253,6 @@
         // Make sure libandroid_runtime is loaded.
         RavenwoodNativeLoader.loadFrameworkNativeCode();
 
-        // Redirect stdout/stdin to liblog.
-        RuntimeInit.redirectLogStreams();
-
         // Touch some references early to ensure they're <clinit>'ed
         Objects.requireNonNull(Build.TYPE);
         Objects.requireNonNull(Build.VERSION.SDK);
diff --git a/ravenwood/runtime-helper-src/framework/android/util/Log_host.java b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
similarity index 62%
rename from ravenwood/runtime-helper-src/framework/android/util/Log_host.java
rename to ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
index c85bd23..7b26fe5 100644
--- a/ravenwood/runtime-helper-src/framework/android/util/Log_host.java
+++ b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
@@ -18,9 +18,13 @@
 import android.util.Log.Level;
 
 import com.android.internal.os.RuntimeInit;
+import com.android.ravenwood.RavenwoodRuntimeNative;
 import com.android.ravenwood.common.RavenwoodCommonUtils;
 
 import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
 
 /**
  * Ravenwood "native substitution" class for {@link android.util.Log}.
@@ -29,7 +33,10 @@
  * In order to switch to this Java implementation, uncomment the @RavenwoodNativeSubstitutionClass
  * annotation on {@link android.util.Log}.
  */
-public class Log_host {
+public class Log_ravenwood {
+
+    public static final SimpleDateFormat sTimestampFormat =
+            new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US);
 
     public static boolean isLoggable(String tag, @Level int level) {
         return true;
@@ -39,15 +46,6 @@
         if (priority < Log.INFO && !RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING) {
             return msg.length(); // No verbose logging.
         }
-        final String buffer;
-        switch (bufID) {
-            case Log.LOG_ID_MAIN: buffer = "main"; break;
-            case Log.LOG_ID_RADIO: buffer = "radio"; break;
-            case Log.LOG_ID_EVENTS: buffer = "event"; break;
-            case Log.LOG_ID_SYSTEM: buffer = "system"; break;
-            case Log.LOG_ID_CRASH: buffer = "crash"; break;
-            default: buffer = "buf:" + bufID; break;
-        }
 
         final String prio;
         switch (priority) {
@@ -60,8 +58,12 @@
             default: prio = "prio:" + priority; break;
         }
 
+        String leading =  sTimestampFormat.format(new Date())
+                + " %-6d %-6d %s %-8s: ".formatted(getPid(), getTid(), prio, tag);
+        var out = getRealOut();
         for (String s : msg.split("\\n")) {
-            getRealOut().println(String.format("logd: [%s] %s %s: %s", buffer, prio, tag, s));
+            out.print(leading);
+            out.println(s);
         }
         return msg.length();
     }
@@ -81,4 +83,34 @@
             return System.out;
         }
     }
+
+    /**
+     * PID. We need to use a JNI method to get it, but JNI isn't initially ready.
+     * Call {@link #onRavenwoodRuntimeNativeReady} to signal when JNI is ready, at which point
+     * we set this field.
+     * (We don't want to call native methods that may not be fully initialized even with a
+     * try-catch, because partially initialized JNI methods could crash the process.)
+     */
+    private static volatile int sPid = 0;
+
+    private static ThreadLocal<Integer> sTid =
+            ThreadLocal.withInitial(RavenwoodRuntimeNative::gettid);
+
+    /**
+     * Call it when {@link RavenwoodRuntimeNative} is usable.
+     */
+    public static void onRavenwoodRuntimeNativeReady() {
+        sPid = RavenwoodRuntimeNative.getpid();
+    }
+
+    private static int getPid() {
+        return sPid;
+    }
+
+    private static int getTid() {
+        if (sPid == 0) {
+            return 0; // Native methods not ready yet.
+        }
+        return sTid.get();
+    }
 }
diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
index 9a78989..acbcdf1 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
@@ -62,6 +62,8 @@
         removeSystemProperty(null);
     }
 
+    public static native int getpid();
+
     public static native int gettid();
 
     public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException {
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index c1993f6..bab4c7e 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -174,6 +174,9 @@
     throwIfMinusOne(env, "setenv", setenv(name.c_str(), value.c_str(), overwrite ? 1 : 0));
 }
 
+static jint Linux_getpid(JNIEnv* env, jobject) {
+    return getpid();
+}
 
 static jint Linux_gettid(JNIEnv* env, jobject) {
     // gettid(2() was added in glibc 2.30 but Android uses an older version in prebuilt.
@@ -196,6 +199,7 @@
     { "stat", "(Ljava/lang/String;)Landroid/system/StructStat;", (void*)Linux_stat },
     { "nOpen", "(Ljava/lang/String;II)I", (void*)Linux_open },
     { "setenv", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*)Linux_setenv },
+    { "getpid", "()I", (void*)Linux_getpid },
     { "gettid", "()I", (void*)Linux_gettid },
 };