diff --git a/fml/platform/android/message_loop_android.cc b/fml/platform/android/message_loop_android.cc index 79a59ba25032d..b4c5982181a54 100644 --- a/fml/platform/android/message_loop_android.cc +++ b/fml/platform/android/message_loop_android.cc @@ -13,31 +13,6 @@ namespace fml { static constexpr int kClockType = CLOCK_MONOTONIC; -static fml::jni::ScopedJavaGlobalRef* g_looper_class = nullptr; -static jmethodID g_looper_prepare_method_ = nullptr; -static jmethodID g_looper_loop_method_ = nullptr; -static jmethodID g_looper_my_looper_method_ = nullptr; -static jmethodID g_looper_quit_method_ = nullptr; - -static void LooperPrepare() { - JNIEnv* env = fml::jni::AttachCurrentThread(); - env->CallStaticVoidMethod(g_looper_class->obj(), g_looper_prepare_method_); -} - -static void LooperLoop() { - JNIEnv* env = fml::jni::AttachCurrentThread(); - env->CallStaticVoidMethod(g_looper_class->obj(), g_looper_loop_method_); -} - -static void LooperQuit() { - JNIEnv* env = fml::jni::AttachCurrentThread(); - auto my_looper = env->CallStaticObjectMethod(g_looper_class->obj(), - g_looper_my_looper_method_); - if (my_looper != nullptr) { - env->CallVoidMethod(my_looper, g_looper_quit_method_); - } -} - static ALooper* AcquireLooperForThread() { ALooper* looper = ALooper_forThread(); @@ -88,15 +63,23 @@ void MessageLoopAndroid::Run() { FML_DCHECK(looper_.get() == ALooper_forThread()); running_ = true; - // Initialize the current thread as a looper. - LooperPrepare(); - // Run the message queue in this thread. - LooperLoop(); + + while (running_) { + int result = ::ALooper_pollOnce(-1, // infinite timeout + nullptr, // out fd, + nullptr, // out events, + nullptr // out data + ); + if (result == ALOOPER_POLL_TIMEOUT || result == ALOOPER_POLL_ERROR) { + // This handles the case where the loop is terminated using ALooper APIs. + running_ = false; + } + } } void MessageLoopAndroid::Terminate() { running_ = false; - LooperQuit(); + ALooper_wake(looper_.get()); } void MessageLoopAndroid::WakeUp(fml::TimePoint time_point) { @@ -110,30 +93,4 @@ void MessageLoopAndroid::OnEventFired() { } } -bool MessageLoopAndroid::Register(JNIEnv* env) { - jclass clazz = env->FindClass("android/os/Looper"); - FML_CHECK(clazz != nullptr); - - g_looper_class = new fml::jni::ScopedJavaGlobalRef(env, clazz); - FML_CHECK(!g_looper_class->is_null()); - - g_looper_prepare_method_ = - env->GetStaticMethodID(g_looper_class->obj(), "prepare", "()V"); - FML_CHECK(g_looper_prepare_method_ != nullptr); - - g_looper_loop_method_ = - env->GetStaticMethodID(g_looper_class->obj(), "loop", "()V"); - FML_CHECK(g_looper_loop_method_ != nullptr); - - g_looper_my_looper_method_ = env->GetStaticMethodID( - g_looper_class->obj(), "myLooper", "()Landroid/os/Looper;"); - FML_CHECK(g_looper_my_looper_method_ != nullptr); - - g_looper_quit_method_ = - env->GetMethodID(g_looper_class->obj(), "quit", "()V"); - FML_CHECK(g_looper_quit_method_ != nullptr); - - return true; -} - } // namespace fml diff --git a/fml/platform/android/message_loop_android.h b/fml/platform/android/message_loop_android.h index d1af3b9352be1..6ff26be0fd373 100644 --- a/fml/platform/android/message_loop_android.h +++ b/fml/platform/android/message_loop_android.h @@ -11,7 +11,6 @@ #include "flutter/fml/macros.h" #include "flutter/fml/message_loop_impl.h" -#include "flutter/fml/platform/android/jni_util.h" #include "flutter/fml/unique_fd.h" namespace fml { @@ -27,9 +26,6 @@ struct UniqueLooperTraits { /// This implemenation wraps usage of Android's \p looper. /// \see https://developer.android.com/ndk/reference/group/looper class MessageLoopAndroid : public MessageLoopImpl { - public: - static bool Register(JNIEnv* env); - private: fml::UniqueObject looper_; fml::UniqueFD timer_fd_; diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 41230ac273573..128eb5c6a8e8d 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -261,10 +261,9 @@ public void setRefreshRateFPS(float refreshRateFPS) { /** * The Android vsync waiter implementation in C++ needs to know when a vsync signal arrives, which - * is obtained via Java API. The delegate set here is called on the C++ side on the ui thread when - * the engine is ready to wait for the next vsync signal. The delegate is expected to add a - * postFrameCallback to the {@link android.view.Choreographer}, and call {@link onVsync} to notify - * the engine. + * is obtained via Java API. The delegate set here is called on the C++ side when the engine is + * ready to wait for the next vsync signal. The delegate is expected to add a postFrameCallback to + * the {@link android.view.Choreographer}, and call {@link onVsync} to notify the engine. * * @param delegate The delegate that will call the engine back on the next vsync signal. */ @@ -273,7 +272,7 @@ public void setAsyncWaitForVsyncDelegate(@Nullable AsyncWaitForVsyncDelegate del } // TODO(mattcarroll): add javadocs - // Called by native on the ui thread. + // Called by native. private static void asyncWaitForVsync(final long cookie) { if (asyncWaitForVsyncDelegate != null) { asyncWaitForVsyncDelegate.asyncWaitForVsync(cookie); diff --git a/shell/platform/android/library_loader.cc b/shell/platform/android/library_loader.cc index 5a4d444da7309..644bd5de3b8ec 100644 --- a/shell/platform/android/library_loader.cc +++ b/shell/platform/android/library_loader.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/fml/platform/android/jni_util.h" -#include "flutter/fml/platform/android/message_loop_android.h" #include "flutter/shell/platform/android/android_image_generator.h" #include "flutter/shell/platform/android/flutter_main.h" #include "flutter/shell/platform/android/platform_view_android.h" @@ -33,9 +32,5 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { result = flutter::AndroidImageGenerator::Register(env); FML_CHECK(result); - // Register MessageLoopAndroid. - result = fml::MessageLoopAndroid::Register(env); - FML_CHECK(result); - return JNI_VERSION_1_4; } diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc index fa3630e08e168..1a69705f634d4 100644 --- a/shell/platform/android/vsync_waiter_android.cc +++ b/shell/platform/android/vsync_waiter_android.cc @@ -29,11 +29,13 @@ void VsyncWaiterAndroid::AwaitVSync() { auto* weak_this = new std::weak_ptr(shared_from_this()); jlong java_baton = reinterpret_cast(weak_this); - JNIEnv* env = fml::jni::AttachCurrentThread(); - env->CallStaticVoidMethod(g_vsync_waiter_class->obj(), // - g_async_wait_for_vsync_method_, // - java_baton // - ); + task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() { + JNIEnv* env = fml::jni::AttachCurrentThread(); + env->CallStaticVoidMethod(g_vsync_waiter_class->obj(), // + g_async_wait_for_vsync_method_, // + java_baton // + ); + }); } // static