Use an older version of SurfaceTexture.setOnFrameAvailableListener when running on pre-Lollipop devices (flutter/engine#6489)
Fixes https://github.com/flutter/flutter/issues/21730
This commit is contained in:
@@ -1041,24 +1041,33 @@ public class FlutterView extends SurfaceView
|
||||
SurfaceTextureRegistryEntry(long id, SurfaceTexture surfaceTexture) {
|
||||
this.id = id;
|
||||
this.surfaceTexture = surfaceTexture;
|
||||
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());
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// 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.
|
||||
this.surfaceTexture.setOnFrameAvailableListener(onFrameListener, new Handler());
|
||||
} else {
|
||||
// Android documentation states that the listener can be called on an arbitrary thread.
|
||||
// But in practice, versions of Android that predate the newer API will call the listener
|
||||
// on the thread where the SurfaceTexture was constructed.
|
||||
this.surfaceTexture.setOnFrameAvailableListener(onFrameListener);
|
||||
}
|
||||
}
|
||||
|
||||
private SurfaceTexture.OnFrameAvailableListener onFrameListener = 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);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public SurfaceTexture surfaceTexture() {
|
||||
return surfaceTexture;
|
||||
|
||||
Reference in New Issue
Block a user