From f6d425a179992ad77cb7ee75e4b551299ea484bb Mon Sep 17 00:00:00 2001 From: Hao Zheng Date: Tue, 7 Jan 2025 19:28:53 +0000 Subject: [PATCH] [JNI Example] call native in Java b/372559388 --- .../java/dev/cobalt/coat/StarboardBridge.java | 7 +-- starboard/android/shared/android_main.cc | 51 --------------- starboard/android/shared/starboard_bridge.cc | 63 ++++++++++++++++++- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java b/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java index 1c2ab30c339..2917b6e03e5 100644 --- a/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java +++ b/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java @@ -131,13 +131,11 @@ public StarboardBridge( this.volumeStateReceiver = new VolumeStateReceiver(appContext); this.isAmatiDevice = appContext.getPackageManager().hasSystemFeature(AMATI_EXPERIENCE_FEATURE); - nativeApp = startNativeStarboard(); + nativeApp = StarboardBridgeJni.get().startNativeStarboard(); } private native boolean initJNI(); - private native long startNativeStarboard(); - private native void closeNativeStarboard(long nativeApp); @NativeMethods @@ -146,11 +144,10 @@ interface Natives { long currentMonotonicTime(); + long startNativeStarboard(); // TODO(cobalt, b/372559388): move below native methods to the Natives interface. // boolean initJNI(); - // long startNativeStarboard(); - // void closeNativeStarboard(long nativeApp); } diff --git a/starboard/android/shared/android_main.cc b/starboard/android/shared/android_main.cc index 1a42ab2c65e..4b8c1a42da5 100644 --- a/starboard/android/shared/android_main.cc +++ b/starboard/android/shared/android_main.cc @@ -30,7 +30,6 @@ #include "starboard/event.h" #include "starboard/log.h" #include "starboard/shared/starboard/command_line.h" -#include "starboard/shared/starboard/log_mutex.h" #include "starboard/thread.h" #if SB_IS(EVERGREEN_COMPATIBLE) #include "starboard/crashpad_wrapper/wrapper.h" // nogncheck @@ -59,17 +58,6 @@ Semaphore* g_app_created_semaphore = nullptr; std::atomic_bool g_app_running{false}; #endif // SB_IS(EVERGREEN_COMPATIBLE) -std::vector GetArgs() { - std::vector args; - // Fake program name as args[0] - args.push_back("android_main"); - - JNIEnv* env = base::android::AttachCurrentThread(); - StarboardBridge::GetInstance()->AppendArgs(env, &args); - - return args; -} - #if SB_IS(EVERGREEN_COMPATIBLE) bool CopyDirContents(const std::string& src_dir_path, const std::string& dst_dir_path) { @@ -242,30 +230,6 @@ Java_dev_cobalt_coat_StarboardBridge_nativeIsReleaseBuild() { #endif } -#if SB_IS(EVERGREEN_COMPATIBLE) -void StarboardThreadLaunch() { - // Start the Starboard thread the first time an Activity is created. - if (g_starboard_thread == 0) { - Semaphore semaphore; - - pthread_attr_t attributes; - pthread_attr_init(&attributes); - pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); - - pthread_create(&g_starboard_thread, &attributes, &ThreadEntryPoint, - &semaphore); - - pthread_attr_destroy(&attributes); - - // Wait for the ApplicationAndroid to be created. - semaphore.Take(); - } - - // Ensure application init happens here - ApplicationAndroid::Get(); -} -#endif // SB_IS(EVERGREEN_COMPATIBLE) - // TODO(cobalt, b/372559388): consolidate this function when fully deprecate // JniEnvExt. extern "C" SB_EXPORT_PLATFORM void Java_dev_cobalt_coat_StarboardBridge_initJNI( @@ -278,21 +242,6 @@ extern "C" SB_EXPORT_PLATFORM void Java_dev_cobalt_coat_StarboardBridge_initJNI( StarboardBridge::GetInstance()->Initialize(jni_env, starboard_bridge); } -extern "C" SB_EXPORT_PLATFORM jlong -Java_dev_cobalt_coat_StarboardBridge_startNativeStarboard(JniEnvExt* env) { -#if SB_IS(EVERGREEN_COMPATIBLE) - StarboardThreadLaunch(); -#else - starboard::shared::starboard::GetLoggingMutex(); - auto command_line = std::make_unique(GetArgs()); - LogInit(*command_line); - auto* nativeApp = new ApplicationAndroid(std::move(command_line)); - // Ensure application init happens here - ApplicationAndroid::Get(); - return reinterpret_cast(nativeApp); -#endif // SB_IS(EVERGREEN_COMPATIBLE) -} - extern "C" SB_EXPORT_PLATFORM void Java_dev_cobalt_coat_StarboardBridge_closeNativeStarboard(JniEnvExt* env, jlong nativeApp) { diff --git a/starboard/android/shared/starboard_bridge.cc b/starboard/android/shared/starboard_bridge.cc index b53eca201e4..c28536499ed 100644 --- a/starboard/android/shared/starboard_bridge.cc +++ b/starboard/android/shared/starboard_bridge.cc @@ -14,20 +14,63 @@ #include "starboard/android/shared/starboard_bridge.h" +#include + +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "starboard/android/shared/application_android.h" #include "starboard/android/shared/file_internal.h" +#include "starboard/android/shared/log_internal.h" #include "starboard/common/time.h" #include "starboard/media.h" #include "starboard/shared/starboard/audio_sink/audio_sink_internal.h" +#include "starboard/shared/starboard/command_line.h" +#include "starboard/shared/starboard/log_mutex.h" // Must come after all headers that specialize FromJniType() / ToJniType(). -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" #include "cobalt/android/jni_headers/StarboardBridge_jni.h" namespace starboard { namespace android { namespace shared { +namespace { +#if SB_IS(EVERGREEN_COMPATIBLE) +void StarboardThreadLaunch() { + // Start the Starboard thread the first time an Activity is created. + if (g_starboard_thread == 0) { + Semaphore semaphore; + + pthread_attr_t attributes; + pthread_attr_init(&attributes); + pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); + + pthread_create(&g_starboard_thread, &attributes, &ThreadEntryPoint, + &semaphore); + + pthread_attr_destroy(&attributes); + + // Wait for the ApplicationAndroid to be created. + semaphore.Take(); + } + + // Ensure application init happens here + ApplicationAndroid::Get(); +} +#endif // SB_IS(EVERGREEN_COMPATIBLE) +} // namespace + +std::vector GetArgs() { + std::vector args; + // Fake program name as args[0] + args.push_back("android_main"); + + JNIEnv* env = base::android::AttachCurrentThread(); + StarboardBridge::GetInstance()->AppendArgs(env, &args); + + return args; +} + extern "C" SB_EXPORT_PLATFORM void JNI_StarboardBridge_OnStop(JNIEnv* env) { ::starboard::shared::starboard::audio_sink::SbAudioSinkImpl::TearDown(); SbFileAndroidTeardown(); @@ -38,6 +81,22 @@ JNI_StarboardBridge_CurrentMonotonicTime(JNIEnv* env) { return CurrentMonotonicTime(); } +extern "C" SB_EXPORT_PLATFORM jlong +JNI_StarboardBridge_StartNativeStarboard(JNIEnv* env) { +#if SB_IS(EVERGREEN_COMPATIBLE) + StarboardThreadLaunch(); +#else + starboard::shared::starboard::GetLoggingMutex(); + auto command_line = std::make_unique(GetArgs()); + LogInit(*command_line); + auto* nativeApp = new ApplicationAndroid(std::move(command_line)); + SB_LOG(INFO) << "hao: StartNativeStarboard: " << nativeApp; + // Ensure application init happens here + ApplicationAndroid::Get(); + return reinterpret_cast(nativeApp); +#endif // SB_IS(EVERGREEN_COMPATIBLE) +} + // StarboardBridge::GetInstance() should not be inlined in the // header. This makes sure that when source files from multiple targets include // this header they don't end up with different copies of the inlined code