diff --git a/starboard/android/shared/android_main.cc b/starboard/android/shared/android_main.cc index dbdb8c074057e..ef469e115d6ed 100644 --- a/starboard/android/shared/android_main.cc +++ b/starboard/android/shared/android_main.cc @@ -17,6 +17,7 @@ #include "starboard/android/shared/jni_env_ext.h" #include "starboard/android/shared/jni_utils.h" #include "starboard/android/shared/log_internal.h" +#include "starboard/common/atomic.h" #include "starboard/common/file.h" #include "starboard/common/semaphore.h" #include "starboard/common/string.h" @@ -48,7 +49,7 @@ Semaphore* g_app_created_semaphore = nullptr; // Safeguard to avoid sending AndroidCommands either when there is no instance // of the Starboard application, or after the run loop has exited and the // ALooper receiving the commands is no longer being polled. -bool g_app_running = false; +atomic_bool g_app_running; std::vector GetArgs() { std::vector args; @@ -235,7 +236,7 @@ void* ThreadEntryPoint(void* context) { // Mark the app running before signaling app created so there's no race to // allow sending the first AndroidCommand after onCreate() returns. - g_app_running = true; + g_app_running.store(true); // Signal GameActivity_onCreate() that it may proceed. g_app_created_semaphore->Put(); @@ -243,12 +244,12 @@ void* ThreadEntryPoint(void* context) { // Enter the Starboard run loop until stopped. int error_level = app.Run(std::move(command_line), GetStartDeepLink().c_str()); -#endif // SB_API_VERSION >= 15 // Mark the app not running before informing StarboardBridge that the app is // stopped so that we won't send any more AndroidCommands as a result of // shutting down the Activity. - g_app_running = false; + g_app_running.store(false); +#endif // SB_API_VERSION >= 15 // Our launcher.py looks for this to know when the app (test) is done. SB_LOG(INFO) << "***Application Stopped*** " << error_level; @@ -262,13 +263,13 @@ void* ThreadEntryPoint(void* context) { } void OnStart(GameActivity* activity) { - if (g_app_running) { + if (g_app_running.load()) { ApplicationAndroid::Get()->SendAndroidCommand(AndroidCommand::kStart); } } void OnResume(GameActivity* activity) { - if (g_app_running) { + if (g_app_running.load()) { // Stop the MediaPlaybackService if activity state transits from background // to foreground. Note that the MediaPlaybackService may already have // been stopped before Cobalt's lifecycle state transits from Concealed @@ -279,7 +280,7 @@ void OnResume(GameActivity* activity) { } void OnPause(GameActivity* activity) { - if (g_app_running) { + if (g_app_running.load()) { // Start the MediaPlaybackService before activity state transits from // foreground to background. ApplicationAndroid::Get()->StartMediaPlaybackService(); @@ -288,28 +289,28 @@ void OnPause(GameActivity* activity) { } void OnStop(GameActivity* activity) { - if (g_app_running) { + if (g_app_running.load()) { ApplicationAndroid::Get()->SendAndroidCommand(AndroidCommand::kStop); } } bool OnTouchEvent(GameActivity* activity, const GameActivityMotionEvent* event) { - if (g_app_running) { + if (g_app_running.load()) { return ApplicationAndroid::Get()->SendAndroidMotionEvent(event); } return false; } bool OnKey(GameActivity* activity, const GameActivityKeyEvent* event) { - if (g_app_running) { + if (g_app_running.load()) { return ApplicationAndroid::Get()->SendAndroidKeyEvent(event); } return false; } void OnWindowFocusChanged(GameActivity* activity, bool focused) { - if (g_app_running) { + if (g_app_running.load()) { ApplicationAndroid::Get()->SendAndroidCommand( focused ? AndroidCommand::kWindowFocusGained : AndroidCommand::kWindowFocusLost); @@ -317,14 +318,14 @@ void OnWindowFocusChanged(GameActivity* activity, bool focused) { } void OnNativeWindowCreated(GameActivity* activity, ANativeWindow* window) { - if (g_app_running) { + if (g_app_running.load()) { ApplicationAndroid::Get()->SendAndroidCommand( AndroidCommand::kNativeWindowCreated, window); } } void OnNativeWindowDestroyed(GameActivity* activity, ANativeWindow* window) { - if (g_app_running) { + if (g_app_running.load()) { ApplicationAndroid::Get()->SendAndroidCommand( AndroidCommand::kNativeWindowDestroyed); } @@ -380,7 +381,7 @@ extern "C" SB_EXPORT_PLATFORM void Java_dev_cobalt_coat_VolumeStateReceiver_nativeVolumeChanged(JNIEnv* env, jobject jcaller, jint volumeDelta) { - if (g_app_running) { + if (g_app_running.load()) { SbKey key = volumeDelta > 0 ? SbKey::kSbKeyVolumeUp : SbKey::kSbKeyVolumeDown; ApplicationAndroid::Get()->SendKeyboardInject(key); @@ -390,7 +391,7 @@ Java_dev_cobalt_coat_VolumeStateReceiver_nativeVolumeChanged(JNIEnv* env, extern "C" SB_EXPORT_PLATFORM void Java_dev_cobalt_coat_VolumeStateReceiver_nativeMuteChanged(JNIEnv* env, jobject jcaller) { - if (g_app_running) { + if (g_app_running.load()) { ApplicationAndroid::Get()->SendKeyboardInject(SbKey::kSbKeyVolumeMute); } } @@ -409,7 +410,7 @@ extern "C" int SbRunStarboardMain(int argc, // Mark the app running before signaling app created so there's no race to // allow sending the first AndroidCommand after onCreate() returns. - g_app_running = true; + g_app_running.store(true); // Signal GameActivity_onCreate() that it may proceed. g_app_created_semaphore->Put(); @@ -417,6 +418,12 @@ extern "C" int SbRunStarboardMain(int argc, // Enter the Starboard run loop until stopped. int error_level = app.Run(std::move(command_line), GetStartDeepLink().c_str()); + + // Mark the app not running before informing StarboardBridge that the app is + // stopped so that we won't send any more AndroidCommands as a result of + // shutting down the Activity. + g_app_running.store(false); + return error_level; } #endif // SB_API_VERSION >= 15