diff options
author | 2024-11-05 23:46:19 +0000 | |
---|---|---|
committer | 2024-11-05 23:46:19 +0000 | |
commit | f18fab05398dacb7d20387b2fbf082341d80c2fb (patch) | |
tree | 06dd4b80185b40b777fe0852d91d53d8a575f826 | |
parent | 553c39b0e3f8db21c6a23c00b262dd8dbd172ce8 (diff) | |
parent | 35947910a62a0d21e520aa0c53cc225147d5f94c (diff) |
Merge changes I9dc35703,I7c4aea4e into main
* changes:
When globalInitOnce() fails, don't run any tests
Switch back to Java android.util.Log
6 files changed, 111 insertions, 30 deletions
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java index 8358b9a51adb..1dd9d46fdfb7 100644 --- a/core/java/android/util/Log.java +++ b/core/java/android/util/Log.java @@ -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}) @@ -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); /** @@ -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); /** @@ -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(); /** diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp index b3f78ab30021..4731cfbfc935 100644 --- a/ravenwood/Android.bp +++ b/ravenwood/Android.bp @@ -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 @@ -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/. @@ -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", diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java index d29b93c0c171..a208d6dce2ce 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java @@ -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, 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 28c262d53ff1..91778579ab28 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java @@ -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; @@ -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 = @@ -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")); } - sInitialized = true; + + // 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); diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp new file mode 100644 index 000000000000..89fb7c3c3510 --- /dev/null +++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp @@ -0,0 +1,50 @@ +/* + * 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; +} diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp index 5b75e9854758..c1993f691686 100644 --- a/ravenwood/runtime-jni/ravenwood_runtime.cpp +++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp @@ -180,24 +180,6 @@ static jint Linux_gettid(JNIEnv* env, jobject) { return syscall(__NR_gettid); } -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); - 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); -} - // ---- Registration ---- extern void register_android_system_OsConstants(JNIEnv* env); @@ -218,8 +200,6 @@ static const JNINativeMethod sMethods[] = }; extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { - maybeRedirectLog(); - ALOGI("%s: JNI_OnLoad", __FILE__); JNIEnv* env = GetJNIEnvOrDie(vm); |