Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 5e58548

Browse files
committed
Fix the SurfaceTexture related crash by Replacing the JNI weak global reference with a WeakReference<SurfaceTexture>
1 parent 2c45b6e commit 5e58548

File tree

9 files changed

+92
-50
lines changed

9 files changed

+92
-50
lines changed

shell/platform/android/android_external_texture_gl.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace flutter {
1313

1414
AndroidExternalTextureGL::AndroidExternalTextureGL(
1515
int64_t id,
16-
const fml::jni::JavaObjectWeakGlobalRef& surface_texture,
16+
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
1717
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
1818
: Texture(id),
1919
jni_facade_(jni_facade),
@@ -74,7 +74,8 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
7474
}
7575

7676
void AndroidExternalTextureGL::UpdateTransform() {
77-
jni_facade_->SurfaceTextureGetTransformMatrix(surface_texture_, transform);
77+
jni_facade_->SurfaceTextureGetTransformMatrix(
78+
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), transform);
7879
}
7980

8081
void AndroidExternalTextureGL::OnGrContextDestroyed() {
@@ -86,16 +87,19 @@ void AndroidExternalTextureGL::OnGrContextDestroyed() {
8687
}
8788

8889
void AndroidExternalTextureGL::Attach(jint textureName) {
89-
jni_facade_->SurfaceTextureAttachToGLContext(surface_texture_, textureName);
90+
jni_facade_->SurfaceTextureAttachToGLContext(
91+
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), textureName);
9092
}
9193

9294
void AndroidExternalTextureGL::Update() {
93-
jni_facade_->SurfaceTextureUpdateTexImage(surface_texture_);
95+
jni_facade_->SurfaceTextureUpdateTexImage(
96+
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
9497
UpdateTransform();
9598
}
9699

97100
void AndroidExternalTextureGL::Detach() {
98-
jni_facade_->SurfaceTextureDetachFromGLContext(surface_texture_);
101+
jni_facade_->SurfaceTextureDetachFromGLContext(
102+
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
99103
}
100104

101105
void AndroidExternalTextureGL::OnTextureUnregistered() {}

shell/platform/android/android_external_texture_gl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <GLES/gl.h>
99

1010
#include "flutter/common/graphics/texture.h"
11-
#include "flutter/fml/platform/android/jni_weak_ref.h"
1211
#include "flutter/shell/platform/android/platform_view_android_jni_impl.h"
1312

1413
namespace flutter {
@@ -17,7 +16,7 @@ class AndroidExternalTextureGL : public flutter::Texture {
1716
public:
1817
AndroidExternalTextureGL(
1918
int64_t id,
20-
const fml::jni::JavaObjectWeakGlobalRef& surface_texture,
19+
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
2120
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
2221

2322
~AndroidExternalTextureGL() override;
@@ -49,7 +48,7 @@ class AndroidExternalTextureGL : public flutter::Texture {
4948

5049
std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
5150

52-
fml::jni::JavaObjectWeakGlobalRef surface_texture_;
51+
fml::jni::ScopedJavaGlobalRef<jobject> surface_texture_;
5352

5453
AttachmentState state_ = AttachmentState::uninitialized;
5554

shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import io.flutter.view.AccessibilityBridge;
3535
import io.flutter.view.FlutterCallbackInformation;
3636
import java.io.IOException;
37+
import java.lang.ref.WeakReference;
3738
import java.nio.ByteBuffer;
3839
import java.util.ArrayList;
3940
import java.util.List;
@@ -756,11 +757,14 @@ public void setAccessibilityFeatures(int flags) {
756757
public void registerTexture(long textureId, @NonNull SurfaceTextureWrapper textureWrapper) {
757758
ensureRunningOnMainThread();
758759
ensureAttachedToNative();
759-
nativeRegisterTexture(nativeShellHolderId, textureId, textureWrapper);
760+
nativeRegisterTexture(
761+
nativeShellHolderId, textureId, new WeakReference<SurfaceTextureWrapper>(textureWrapper));
760762
}
761763

762764
private native void nativeRegisterTexture(
763-
long nativeShellHolderId, long textureId, @NonNull SurfaceTextureWrapper textureWrapper);
765+
long nativeShellHolderId,
766+
long textureId,
767+
@NonNull WeakReference<SurfaceTextureWrapper> textureWrapper);
764768

765769
/**
766770
* Call this method to inform Flutter that a texture previously registered with {@link

shell/platform/android/jni/jni_mock.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,22 @@ class JNIMock final : public PlatformViewAndroidJNI {
4646

4747
MOCK_METHOD(void,
4848
SurfaceTextureAttachToGLContext,
49-
(JavaWeakGlobalRef surface_texture, int textureId),
49+
(JavaLocalRef surface_texture, int textureId),
5050
(override));
5151

5252
MOCK_METHOD(void,
5353
SurfaceTextureUpdateTexImage,
54-
(JavaWeakGlobalRef surface_texture),
54+
(JavaLocalRef surface_texture),
5555
(override));
5656

5757
MOCK_METHOD(void,
5858
SurfaceTextureGetTransformMatrix,
59-
(JavaWeakGlobalRef surface_texture, SkMatrix& transform),
59+
(JavaLocalRef surface_texture, SkMatrix& transform),
6060
(override));
6161

6262
MOCK_METHOD(void,
6363
SurfaceTextureDetachFromGLContext,
64-
(JavaWeakGlobalRef surface_texture),
64+
(JavaLocalRef surface_texture),
6565
(override));
6666

6767
MOCK_METHOD(void,

shell/platform/android/jni/platform_view_android_jni.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414
#include "third_party/skia/include/core/SkMatrix.h"
1515

1616
#if OS_ANDROID
17-
#include "flutter/fml/platform/android/jni_weak_ref.h"
17+
#include "flutter/fml/platform/android/scoped_java_ref.h"
1818
#endif
1919

2020
namespace flutter {
2121

2222
#if OS_ANDROID
23-
using JavaWeakGlobalRef = fml::jni::JavaObjectWeakGlobalRef;
23+
using JavaLocalRef = fml::jni::ScopedJavaLocalRef<jobject>;
2424
#else
25-
using JavaWeakGlobalRef = std::nullptr_t;
25+
using JavaLocalRef = std::nullptr_t;
2626
#endif
2727

2828
//------------------------------------------------------------------------------
@@ -86,31 +86,28 @@ class PlatformViewAndroidJNI {
8686
/// @brief Attach the SurfaceTexture to the OpenGL ES context that is
8787
/// current on the calling thread.
8888
///
89-
virtual void SurfaceTextureAttachToGLContext(
90-
JavaWeakGlobalRef surface_texture,
91-
int textureId) = 0;
89+
virtual void SurfaceTextureAttachToGLContext(JavaLocalRef surface_texture,
90+
int textureId) = 0;
9291

9392
//----------------------------------------------------------------------------
9493
/// @brief Updates the texture image to the most recent frame from the
9594
/// image stream.
9695
///
97-
virtual void SurfaceTextureUpdateTexImage(
98-
JavaWeakGlobalRef surface_texture) = 0;
96+
virtual void SurfaceTextureUpdateTexImage(JavaLocalRef surface_texture) = 0;
9997

10098
//----------------------------------------------------------------------------
10199
/// @brief Gets the transform matrix from the SurfaceTexture.
102100
/// Then, it updates the `transform` matrix, so it fill the canvas
103101
/// and preserve the aspect ratio.
104102
///
105-
virtual void SurfaceTextureGetTransformMatrix(
106-
JavaWeakGlobalRef surface_texture,
107-
SkMatrix& transform) = 0;
103+
virtual void SurfaceTextureGetTransformMatrix(JavaLocalRef surface_texture,
104+
SkMatrix& transform) = 0;
108105

109106
//----------------------------------------------------------------------------
110107
/// @brief Detaches a SurfaceTexture from the OpenGL ES context.
111108
///
112109
virtual void SurfaceTextureDetachFromGLContext(
113-
JavaWeakGlobalRef surface_texture) = 0;
110+
JavaLocalRef surface_texture) = 0;
114111

115112
//----------------------------------------------------------------------------
116113
/// @brief Positions and sizes a platform view if using hybrid

shell/platform/android/platform_view_android.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ void PlatformViewAndroid::UpdateSemantics(
291291

292292
void PlatformViewAndroid::RegisterExternalTexture(
293293
int64_t texture_id,
294-
const fml::jni::JavaObjectWeakGlobalRef& surface_texture) {
294+
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
295295
RegisterTexture(std::make_shared<AndroidExternalTextureGL>(
296296
texture_id, surface_texture, std::move(jni_facade_)));
297297
}

shell/platform/android/platform_view_android.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <vector>
1212

1313
#include "flutter/fml/memory/weak_ptr.h"
14-
#include "flutter/fml/platform/android/jni_weak_ref.h"
1514
#include "flutter/fml/platform/android/scoped_java_ref.h"
1615
#include "flutter/lib/ui/window/platform_message.h"
1716
#include "flutter/shell/common/platform_view.h"
@@ -97,7 +96,7 @@ class PlatformViewAndroid final : public PlatformView {
9796

9897
void RegisterExternalTexture(
9998
int64_t texture_id,
100-
const fml::jni::JavaObjectWeakGlobalRef& surface_texture);
99+
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture);
101100

102101
// |PlatformView|
103102
void LoadDartDeferredLibrary(

shell/platform/android/platform_view_android_jni_impl.cc

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ static fml::jni::ScopedJavaGlobalRef<jclass>* g_flutter_callback_info_class =
4242

4343
static fml::jni::ScopedJavaGlobalRef<jclass>* g_flutter_jni_class = nullptr;
4444

45+
static fml::jni::ScopedJavaGlobalRef<jclass>* g_java_weak_reference_class =
46+
nullptr;
47+
4548
static fml::jni::ScopedJavaGlobalRef<jclass>* g_texture_wrapper_class = nullptr;
4649

4750
static fml::jni::ScopedJavaGlobalRef<jclass>* g_java_long_class = nullptr;
@@ -87,6 +90,8 @@ static jmethodID g_on_begin_frame_method = nullptr;
8790

8891
static jmethodID g_on_end_frame_method = nullptr;
8992

93+
static jmethodID g_java_weak_reference_get_method = nullptr;
94+
9095
static jmethodID g_attach_to_gl_context_method = nullptr;
9196

9297
static jmethodID g_update_tex_image_method = nullptr;
@@ -452,8 +457,8 @@ static void RegisterTexture(JNIEnv* env,
452457
jlong texture_id,
453458
jobject surface_texture) {
454459
ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(
455-
static_cast<int64_t>(texture_id), //
456-
fml::jni::JavaObjectWeakGlobalRef(env, surface_texture) //
460+
static_cast<int64_t>(texture_id), //
461+
fml::jni::ScopedJavaGlobalRef<jobject>(env, surface_texture) //
457462
);
458463
}
459464

@@ -714,8 +719,8 @@ bool RegisterApi(JNIEnv* env) {
714719
},
715720
{
716721
.name = "nativeRegisterTexture",
717-
.signature = "(JJLio/flutter/embedding/engine/renderer/"
718-
"SurfaceTextureWrapper;)V",
722+
.signature = "(JJLjava/lang/ref/"
723+
"WeakReference;)V",
719724
.fnPtr = reinterpret_cast<void*>(&RegisterTexture),
720725
},
721726
{
@@ -1007,6 +1012,20 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
10071012
return false;
10081013
}
10091014

1015+
g_java_weak_reference_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
1016+
env, env->FindClass("java/lang/ref/WeakReference"));
1017+
if (g_java_weak_reference_class->is_null()) {
1018+
FML_LOG(ERROR) << "Could not locate WeakReference class";
1019+
return false;
1020+
}
1021+
1022+
g_java_weak_reference_get_method = env->GetMethodID(
1023+
g_java_weak_reference_class->obj(), "get", "()Ljava/lang/Object;");
1024+
if (g_java_weak_reference_get_method == nullptr) {
1025+
FML_LOG(ERROR) << "Could not locate WeakReference.get method";
1026+
return false;
1027+
}
1028+
10101029
g_texture_wrapper_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
10111030
env, env->FindClass(
10121031
"io/flutter/embedding/engine/renderer/SurfaceTextureWrapper"));
@@ -1215,12 +1234,18 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnPreEngineRestart() {
12151234
}
12161235

12171236
void PlatformViewAndroidJNIImpl::SurfaceTextureAttachToGLContext(
1218-
JavaWeakGlobalRef surface_texture,
1237+
JavaLocalRef surface_texture,
12191238
int textureId) {
12201239
JNIEnv* env = fml::jni::AttachCurrentThread();
12211240

1222-
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
1223-
surface_texture.get(env);
1241+
if (surface_texture.is_null()) {
1242+
return;
1243+
}
1244+
1245+
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1246+
env, env->CallObjectMethod(surface_texture.obj(),
1247+
g_java_weak_reference_get_method));
1248+
12241249
if (surface_texture_local_ref.is_null()) {
12251250
return;
12261251
}
@@ -1232,11 +1257,16 @@ void PlatformViewAndroidJNIImpl::SurfaceTextureAttachToGLContext(
12321257
}
12331258

12341259
void PlatformViewAndroidJNIImpl::SurfaceTextureUpdateTexImage(
1235-
JavaWeakGlobalRef surface_texture) {
1260+
JavaLocalRef surface_texture) {
12361261
JNIEnv* env = fml::jni::AttachCurrentThread();
12371262

1238-
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
1239-
surface_texture.get(env);
1263+
if (surface_texture.is_null()) {
1264+
return;
1265+
}
1266+
1267+
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1268+
env, env->CallObjectMethod(surface_texture.obj(),
1269+
g_java_weak_reference_get_method));
12401270
if (surface_texture_local_ref.is_null()) {
12411271
return;
12421272
}
@@ -1260,12 +1290,17 @@ SkSize ScaleToFill(float scaleX, float scaleY) {
12601290
}
12611291

12621292
void PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
1263-
JavaWeakGlobalRef surface_texture,
1293+
JavaLocalRef surface_texture,
12641294
SkMatrix& transform) {
12651295
JNIEnv* env = fml::jni::AttachCurrentThread();
12661296

1267-
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
1268-
surface_texture.get(env);
1297+
if (surface_texture.is_null()) {
1298+
return;
1299+
}
1300+
1301+
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1302+
env, env->CallObjectMethod(surface_texture.obj(),
1303+
g_java_weak_reference_get_method));
12691304
if (surface_texture_local_ref.is_null()) {
12701305
return;
12711306
}
@@ -1290,11 +1325,16 @@ void PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
12901325
}
12911326

12921327
void PlatformViewAndroidJNIImpl::SurfaceTextureDetachFromGLContext(
1293-
JavaWeakGlobalRef surface_texture) {
1328+
JavaLocalRef surface_texture) {
12941329
JNIEnv* env = fml::jni::AttachCurrentThread();
12951330

1296-
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
1297-
surface_texture.get(env);
1331+
if (surface_texture.is_null()) {
1332+
return;
1333+
}
1334+
1335+
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1336+
env, env->CallObjectMethod(surface_texture.obj(),
1337+
g_java_weak_reference_get_method));
12981338
if (surface_texture_local_ref.is_null()) {
12991339
return;
13001340
}

shell/platform/android/platform_view_android_jni_impl.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,15 @@ class PlatformViewAndroidJNIImpl final : public PlatformViewAndroidJNI {
4141

4242
void FlutterViewOnPreEngineRestart() override;
4343

44-
void SurfaceTextureAttachToGLContext(JavaWeakGlobalRef surface_texture,
44+
void SurfaceTextureAttachToGLContext(JavaLocalRef surface_texture,
4545
int textureId) override;
4646

47-
void SurfaceTextureUpdateTexImage(JavaWeakGlobalRef surface_texture) override;
47+
void SurfaceTextureUpdateTexImage(JavaLocalRef surface_texture) override;
4848

49-
void SurfaceTextureGetTransformMatrix(JavaWeakGlobalRef surface_texture,
49+
void SurfaceTextureGetTransformMatrix(JavaLocalRef surface_texture,
5050
SkMatrix& transform) override;
5151

52-
void SurfaceTextureDetachFromGLContext(
53-
JavaWeakGlobalRef surface_texture) override;
52+
void SurfaceTextureDetachFromGLContext(JavaLocalRef surface_texture) override;
5453

5554
void FlutterViewOnDisplayPlatformView(int view_id,
5655
int x,

0 commit comments

Comments
 (0)