Loading core/java/android/util/Log.java +4 −2 Original line number Diff line number Diff line Loading @@ -75,8 +75,7 @@ import java.net.UnknownHostException; @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.RavenwoodNativeSubstitutionClass( // "com.android.platform.test.ravenwood.nativesubstitution.Log_host") @android.ravenwood.annotation.RavenwoodRedirectionClass("Log_host") public final class Log { /** @hide */ @IntDef({ASSERT, ERROR, WARN, INFO, DEBUG, VERBOSE}) Loading Loading @@ -250,6 +249,7 @@ public final class Log { * tag limit of concern after this API level. */ @FastNative @android.ravenwood.annotation.RavenwoodRedirect public static native boolean isLoggable(@Nullable String tag, @Level int level); /** Loading Loading @@ -425,6 +425,7 @@ public final class Log { * @hide */ @UnsupportedAppUsage @android.ravenwood.annotation.RavenwoodRedirect public static native int println_native(int bufID, int priority, String tag, String msg); /** Loading Loading @@ -452,6 +453,7 @@ public final class Log { * Return the maximum payload the log daemon accepts without truncation. * @return LOGGER_ENTRY_MAX_PAYLOAD. */ @android.ravenwood.annotation.RavenwoodRedirect private static native int logger_entry_max_payload_native(); /** Loading ravenwood/Android.bp +10 −1 Original line number Diff line number Diff line Loading @@ -279,6 +279,15 @@ cc_defaults { shared_libs: [ "liblog", ], visibility: ["//visibility:private"], } cc_library_host_shared { name: "libravenwood_initializer", defaults: ["ravenwood_jni_defaults"], srcs: [ "runtime-jni/ravenwood_initializer.cpp", ], } // We need this as a separate library because we need to overload the Loading @@ -301,7 +310,6 @@ cc_library_host_shared { "libutils", "libcutils", ], visibility: ["//frameworks/base"], } // For collecting the *stats.csv files in a known directory under out/host/linux-x86/testcases/. Loading Loading @@ -659,6 +667,7 @@ android_ravenwood_libgroup { ], jni_libs: [ // Libraries has to be loaded in the following order "libravenwood_initializer", "libravenwood_sysprop", "libravenwood_runtime", "libandroid_runtime", Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ public final class RavenwoodNativeLoader { * See frameworks/base/core/jni/platform/host/HostRuntime.cpp */ private static final Class<?>[] sLibandroidClasses = { android.util.Log.class, // android.util.Log.class, // Not using native log: b/377377826 android.os.Parcel.class, android.os.Binder.class, android.os.SystemProperties.class, Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +46 −6 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; import com.android.hoststubgen.hosthelper.HostTestUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.RavenwoodRuntimeNative; import com.android.ravenwood.RavenwoodRuntimeState; Loading Loading @@ -86,6 +87,7 @@ public class RavenwoodRuntimeEnvironmentController { } private static final String MAIN_THREAD_NAME = "RavenwoodMain"; private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer"; private static final String RAVENWOOD_NATIVE_SYSPROP_NAME = "ravenwood_sysprop"; private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime"; private static final String RAVENWOOD_BUILD_PROP = Loading Loading @@ -139,23 +141,61 @@ public class RavenwoodRuntimeEnvironmentController { return res; } private static final Object sInitializationLock = new Object(); @GuardedBy("sInitializationLock") private static boolean sInitialized = false; @GuardedBy("sInitializationLock") private static Throwable sExceptionFromGlobalInit; private static RavenwoodAwareTestRunner sRunner; private static RavenwoodSystemProperties sProps; private static boolean sInitialized = false; /** * Initialize the global environment. */ public static void globalInitOnce() { if (sInitialized) { return; } synchronized (sInitializationLock) { if (!sInitialized) { // globalInitOnce() is called from class initializer, which cause // this method to be called recursively, sInitialized = true; // This is the first call. try { globalInitInner(); } catch (Throwable th) { Log.e(TAG, "globalInit() failed", th); sExceptionFromGlobalInit = th; throw th; } } else { // Subsequent calls. If the first call threw, just throw the same error, to prevent // the test from running. if (sExceptionFromGlobalInit != null) { Log.e(TAG, "globalInit() failed re-throwing the same exception", sExceptionFromGlobalInit); SneakyThrow.sneakyThrow(sExceptionFromGlobalInit); } } } } private static void globalInitInner() { if (RAVENWOOD_VERBOSE_LOGGING) { Log.v(TAG, "globalInit() called here...", new RuntimeException("NOT A CRASH")); } // Some process-wide initialization. (maybe redirect stdout/stderr) RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME); // We haven't initialized liblog yet, so directly write to System.out here. RavenwoodCommonUtils.log(TAG, "globalInit()"); RavenwoodCommonUtils.log(TAG, "globalInitInner()"); // Load libravenwood_sysprop first // Load libravenwood_sysprop before other libraries that may use SystemProperties. var libProp = RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_SYSPROP_NAME); System.load(libProp); RavenwoodRuntimeNative.reloadNativeLibrary(libProp); Loading ravenwood/runtime-jni/ravenwood_initializer.cpp 0 → 100644 +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This file is compiled into a single SO file, which we load at the very first. * We can do process-wide initialization here. */ #include <fcntl.h> #include <unistd.h> #include "jni_helper.h" static void maybeRedirectLog() { auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT"); if (ravenwoodLogOut == NULL) { return; } ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut); // Redirect stdin / stdout to /dev/tty. int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND); if (ttyFd == -1) { ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut, strerror(errno)); return; } dup2(ttyFd, 1); dup2(ttyFd, 2); } extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { ALOGI("%s: JNI_OnLoad", __FILE__); maybeRedirectLog(); return JNI_VERSION_1_4; } Loading
core/java/android/util/Log.java +4 −2 Original line number Diff line number Diff line Loading @@ -75,8 +75,7 @@ import java.net.UnknownHostException; @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.RavenwoodNativeSubstitutionClass( // "com.android.platform.test.ravenwood.nativesubstitution.Log_host") @android.ravenwood.annotation.RavenwoodRedirectionClass("Log_host") public final class Log { /** @hide */ @IntDef({ASSERT, ERROR, WARN, INFO, DEBUG, VERBOSE}) Loading Loading @@ -250,6 +249,7 @@ public final class Log { * tag limit of concern after this API level. */ @FastNative @android.ravenwood.annotation.RavenwoodRedirect public static native boolean isLoggable(@Nullable String tag, @Level int level); /** Loading Loading @@ -425,6 +425,7 @@ public final class Log { * @hide */ @UnsupportedAppUsage @android.ravenwood.annotation.RavenwoodRedirect public static native int println_native(int bufID, int priority, String tag, String msg); /** Loading Loading @@ -452,6 +453,7 @@ public final class Log { * Return the maximum payload the log daemon accepts without truncation. * @return LOGGER_ENTRY_MAX_PAYLOAD. */ @android.ravenwood.annotation.RavenwoodRedirect private static native int logger_entry_max_payload_native(); /** Loading
ravenwood/Android.bp +10 −1 Original line number Diff line number Diff line Loading @@ -279,6 +279,15 @@ cc_defaults { shared_libs: [ "liblog", ], visibility: ["//visibility:private"], } cc_library_host_shared { name: "libravenwood_initializer", defaults: ["ravenwood_jni_defaults"], srcs: [ "runtime-jni/ravenwood_initializer.cpp", ], } // We need this as a separate library because we need to overload the Loading @@ -301,7 +310,6 @@ cc_library_host_shared { "libutils", "libcutils", ], visibility: ["//frameworks/base"], } // For collecting the *stats.csv files in a known directory under out/host/linux-x86/testcases/. Loading Loading @@ -659,6 +667,7 @@ android_ravenwood_libgroup { ], jni_libs: [ // Libraries has to be loaded in the following order "libravenwood_initializer", "libravenwood_sysprop", "libravenwood_runtime", "libandroid_runtime", Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ public final class RavenwoodNativeLoader { * See frameworks/base/core/jni/platform/host/HostRuntime.cpp */ private static final Class<?>[] sLibandroidClasses = { android.util.Log.class, // android.util.Log.class, // Not using native log: b/377377826 android.os.Parcel.class, android.os.Binder.class, android.os.SystemProperties.class, Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +46 −6 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; import com.android.hoststubgen.hosthelper.HostTestUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.RavenwoodRuntimeNative; import com.android.ravenwood.RavenwoodRuntimeState; Loading Loading @@ -86,6 +87,7 @@ public class RavenwoodRuntimeEnvironmentController { } private static final String MAIN_THREAD_NAME = "RavenwoodMain"; private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer"; private static final String RAVENWOOD_NATIVE_SYSPROP_NAME = "ravenwood_sysprop"; private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime"; private static final String RAVENWOOD_BUILD_PROP = Loading Loading @@ -139,23 +141,61 @@ public class RavenwoodRuntimeEnvironmentController { return res; } private static final Object sInitializationLock = new Object(); @GuardedBy("sInitializationLock") private static boolean sInitialized = false; @GuardedBy("sInitializationLock") private static Throwable sExceptionFromGlobalInit; private static RavenwoodAwareTestRunner sRunner; private static RavenwoodSystemProperties sProps; private static boolean sInitialized = false; /** * Initialize the global environment. */ public static void globalInitOnce() { if (sInitialized) { return; } synchronized (sInitializationLock) { if (!sInitialized) { // globalInitOnce() is called from class initializer, which cause // this method to be called recursively, sInitialized = true; // This is the first call. try { globalInitInner(); } catch (Throwable th) { Log.e(TAG, "globalInit() failed", th); sExceptionFromGlobalInit = th; throw th; } } else { // Subsequent calls. If the first call threw, just throw the same error, to prevent // the test from running. if (sExceptionFromGlobalInit != null) { Log.e(TAG, "globalInit() failed re-throwing the same exception", sExceptionFromGlobalInit); SneakyThrow.sneakyThrow(sExceptionFromGlobalInit); } } } } private static void globalInitInner() { if (RAVENWOOD_VERBOSE_LOGGING) { Log.v(TAG, "globalInit() called here...", new RuntimeException("NOT A CRASH")); } // Some process-wide initialization. (maybe redirect stdout/stderr) RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME); // We haven't initialized liblog yet, so directly write to System.out here. RavenwoodCommonUtils.log(TAG, "globalInit()"); RavenwoodCommonUtils.log(TAG, "globalInitInner()"); // Load libravenwood_sysprop first // Load libravenwood_sysprop before other libraries that may use SystemProperties. var libProp = RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_SYSPROP_NAME); System.load(libProp); RavenwoodRuntimeNative.reloadNativeLibrary(libProp); Loading
ravenwood/runtime-jni/ravenwood_initializer.cpp 0 → 100644 +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This file is compiled into a single SO file, which we load at the very first. * We can do process-wide initialization here. */ #include <fcntl.h> #include <unistd.h> #include "jni_helper.h" static void maybeRedirectLog() { auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT"); if (ravenwoodLogOut == NULL) { return; } ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut); // Redirect stdin / stdout to /dev/tty. int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND); if (ttyFd == -1) { ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut, strerror(errno)); return; } dup2(ttyFd, 1); dup2(ttyFd, 2); } extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { ALOGI("%s: JNI_OnLoad", __FILE__); maybeRedirectLog(); return JNI_VERSION_1_4; }