Skip to content

Commit

Permalink
Unregister onFrameAvailable callbacks when a TextureEntry is released. (
Browse files Browse the repository at this point in the history
#6079)

Otherwise the callbacks may be called after FlutterNativeView is destroyed and is null.

Also defensively check for whether the texture is already released in the callback because the callback may be called from another thread by a stale reference (see the comment).

This closes flutter/flutter#20951.
  • Loading branch information
nichtverstehen authored and mehmetf committed Sep 4, 2018
1 parent 2dc8271 commit b0b8daa
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -997,9 +997,19 @@ final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextur
this.surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
@Override
public void onFrameAvailable(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.
return;
}
nativeMarkTextureFrameAvailable(mNativeView.get(), SurfaceTextureRegistryEntry.this.id);
}
});
},
// The callback relies on being executed on the UI thread (unsynchronised read of mNativeView
// and also the engine code check for platform thread in Shell::OnPlatformViewMarkTextureFrameAvailable),
// so we explicitly pass a Handler for the current thread.
new Handler());
}

@Override
Expand All @@ -1019,6 +1029,9 @@ public void release() {
}
released = true;
nativeUnregisterTexture(mNativeView.get(), id);
// Otherwise onFrameAvailableListener might be called after mNativeView==null
// (https://github.com/flutter/flutter/issues/20951). See also the check in onFrameAvailable.
surfaceTexture.setOnFrameAvailableListener(null);
surfaceTexture.release();
}
}
Expand Down

0 comments on commit b0b8daa

Please sign in to comment.