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:
Jason Simmons
2018-10-10 15:01:48 -07:00
committed by GitHub
parent b1f2799090
commit 065769e2e5

View File

@@ -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;