Skip to content

Commit

Permalink
Use an older version of SurfaceTexture.setOnFrameAvailableListener wh…
Browse files Browse the repository at this point in the history
…en running on pre-Lollipop devices (flutter#6489)

Fixes flutter/flutter#21730
  • Loading branch information
jason-simmons authored Oct 10, 2018
1 parent 81b5219 commit 155ba09
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -1041,24 +1041,33 @@ final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextur
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;
Expand Down

0 comments on commit 155ba09

Please sign in to comment.