From 8d241e492624118ef023a6eeb62f4bdb7d429ae5 Mon Sep 17 00:00:00 2001 From: Gary Qian Date: Mon, 13 Jul 2020 06:29:30 -0700 Subject: [PATCH] [Android] Prevent FlutterRenderer listener from calling JNI after detach (#19558) --- .../engine/renderer/FlutterRenderer.java | 10 +++++----- .../engine/renderer/FlutterRendererTest.java | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 8dec2a05052dc..f0cd24adea675 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -131,11 +131,11 @@ final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextur new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(@NonNull SurfaceTexture texture) { - if (released) { - // Even though we make sure to unregister the callback before releasing, as of Android - // O - // SurfaceTexture has a data race when accessing the callback, so the callback may - // still be called by a stale reference after released==true and mNativeView==null. + if (released || !flutterJNI.isAttached()) { + // Even though we make sure to unregister the callback before releasing, as of + // Android O, SurfaceTexture has a data race when accessing the callback, so the + // callback may still be called by a stale reference after released==true and + // mNativeView==null. return; } markTextureFrameAvailable(id); diff --git a/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java b/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java index 4b3884085b93b..185ed43fa08c2 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java @@ -97,4 +97,23 @@ public void itStopsRenderingToSurfaceWhenRequested() { // Verify behavior under test. verify(fakeFlutterJNI, times(1)).onSurfaceDestroyed(); } + + @Test + public void itStopsSurfaceTextureCallbackWhenDetached() { + // Setup the test. + FlutterRenderer flutterRenderer = new FlutterRenderer(fakeFlutterJNI); + + fakeFlutterJNI.detachFromNativeAndReleaseResources(); + + FlutterRenderer.SurfaceTextureRegistryEntry entry = + (FlutterRenderer.SurfaceTextureRegistryEntry) flutterRenderer.createSurfaceTexture(); + + flutterRenderer.startRenderingToSurface(fakeSurface); + + // Execute the behavior under test. + flutterRenderer.stopRenderingToSurface(); + + // Verify behavior under test. + verify(fakeFlutterJNI, times(0)).markTextureFrameAvailable(eq(entry.id())); + } }