diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index c009574cabab4..ea2449d5485c3 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -799,6 +799,17 @@ public void onDisplayOverlaySurface(int id, int x, int y, int width, int height) } platformViewsController.onDisplayOverlaySurface(id, x, y, width, height); } + + @SuppressWarnings("unused") + @UiThread + public void onBeginFrame() { + ensureRunningOnMainThread(); + if (platformViewsController == null) { + throw new RuntimeException( + "platformViewsController must be set before attempting to begin the frame"); + } + platformViewsController.onBeginFrame(); + } // ----- End Engine Lifecycle Support ---- // @SuppressWarnings("unused") diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 43568fe9de051..ff5747bd5dcf1 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -541,4 +541,8 @@ public void onDisplayPlatformView(int viewId, int x, int y, int width, int heigh public void onDisplayOverlaySurface(int id, int x, int y, int width, int height) { // TODO: Implement this method. https://github.com/flutter/flutter/issues/58288 } + + public void onBeginFrame() { + // TODO: Implement this method. https://github.com/flutter/flutter/issues/58288 + } } diff --git a/shell/platform/android/jni/platform_view_android_jni.h b/shell/platform/android/jni/platform_view_android_jni.h index eed89a1347845..ff87ee382cb11 100644 --- a/shell/platform/android/jni/platform_view_android_jni.h +++ b/shell/platform/android/jni/platform_view_android_jni.h @@ -130,6 +130,13 @@ class PlatformViewAndroidJNI { int y, int width, int height) = 0; + //---------------------------------------------------------------------------- + /// @brief Initiates a frame if using hybrid composition. + /// + /// + /// @note Must be called from the platform thread. + /// + virtual void FlutterViewBeginFrame() = 0; }; } // namespace flutter diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index b791f120f7dcf..331f0350230d0 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -80,6 +80,8 @@ static jmethodID g_on_first_frame_method = nullptr; static jmethodID g_on_engine_restart_method = nullptr; +static jmethodID g_on_begin_frame_method = nullptr; + static jmethodID g_attach_to_gl_context_method = nullptr; static jmethodID g_update_tex_image_method = nullptr; @@ -718,6 +720,14 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { return false; } + g_on_begin_frame_method = + env->GetMethodID(g_flutter_jni_class->obj(), "onBeginFrame", "()V"); + + if (g_on_begin_frame_method == nullptr) { + FML_LOG(ERROR) << "Could not locate onBeginFrame method"; + return false; + } + g_on_display_overlay_surface_method = env->GetMethodID( g_flutter_jni_class->obj(), "onDisplayOverlaySurface", "(IIIII)V"); @@ -1034,4 +1044,17 @@ void PlatformViewAndroidJNIImpl::FlutterViewDisplayOverlaySurface( FML_CHECK(CheckException(env)); } +void PlatformViewAndroidJNIImpl::FlutterViewBeginFrame() { + JNIEnv* env = fml::jni::AttachCurrentThread(); + + auto java_object = java_object_.get(env); + if (java_object.is_null()) { + return; + } + + env->CallVoidMethod(java_object.obj(), g_on_begin_frame_method); + + FML_CHECK(CheckException(env)); +} + } // namespace flutter diff --git a/shell/platform/android/platform_view_android_jni_impl.h b/shell/platform/android/platform_view_android_jni_impl.h index db0441036b6f1..2a53e307ca12a 100644 --- a/shell/platform/android/platform_view_android_jni_impl.h +++ b/shell/platform/android/platform_view_android_jni_impl.h @@ -62,6 +62,8 @@ class PlatformViewAndroidJNIImpl final : public PlatformViewAndroidJNI { int width, int height) override; + void FlutterViewBeginFrame() override; + private: // Reference to FlutterJNI object. const fml::jni::JavaObjectWeakGlobalRef java_object_; diff --git a/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java b/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java index 3bb26ce7578d2..cee3e985d4224 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java @@ -81,4 +81,19 @@ public void onDisplayOverlaySurface__callsPlatformViewsController() { verify(platformViewsController, times(1)) .onDisplayOverlaySurface(/*id=*/ 1, /*x=*/ 10, /*y=*/ 20, /*width=*/ 100, /*height=*/ 200); } + + @Test + public void onBeginFrame__callsPlatformViewsController() { + PlatformViewsController platformViewsController = mock(PlatformViewsController.class); + + // --- Test Setup --- + FlutterJNI flutterJNI = new FlutterJNI(); + flutterJNI.setPlatformViewsController(platformViewsController); + + // --- Execute Test --- + flutterJNI.onBeginFrame(); + + // --- Verify Results --- + verify(platformViewsController, times(1)).onBeginFrame(); + } }