Fix crash when a MultiFrameImageStreamCompleter is disposed during frame decoding (#69219)
This commit is contained in:
parent
324b78eb12
commit
1fad8acb10
@ -920,6 +920,12 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_codec!.frameCount == 1) {
|
if (_codec!.frameCount == 1) {
|
||||||
|
// ImageStreamCompleter listeners removed while waiting for next frame to
|
||||||
|
// be decoded.
|
||||||
|
// There's no reason to emit the frame without active listeners.
|
||||||
|
if (!hasListeners) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// This is not an animated image, just return it and don't schedule more
|
// This is not an animated image, just return it and don't schedule more
|
||||||
// frames.
|
// frames.
|
||||||
_emitFrame(ImageInfo(
|
_emitFrame(ImageInfo(
|
||||||
|
@ -130,6 +130,31 @@ void main() {
|
|||||||
expect(mockCodec.numFramesAsked, 1);
|
expect(mockCodec.numFramesAsked, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Decoding does not crash when disposed', (WidgetTester tester) async {
|
||||||
|
final Completer<Codec> completer = Completer<Codec>();
|
||||||
|
final MockCodec mockCodec = MockCodec();
|
||||||
|
mockCodec.frameCount = 1;
|
||||||
|
final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
|
||||||
|
codec: completer.future,
|
||||||
|
scale: 1.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
completer.complete(mockCodec);
|
||||||
|
await tester.idle();
|
||||||
|
expect(mockCodec.numFramesAsked, 0);
|
||||||
|
|
||||||
|
final ImageListener listener = (ImageInfo image, bool synchronousCall) { };
|
||||||
|
final ImageStreamListener streamListener = ImageStreamListener(listener);
|
||||||
|
imageStream.addListener(streamListener);
|
||||||
|
await tester.idle();
|
||||||
|
expect(mockCodec.numFramesAsked, 1);
|
||||||
|
|
||||||
|
final FrameInfo frame = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
|
||||||
|
mockCodec.completeNextFrame(frame);
|
||||||
|
imageStream.removeListener(streamListener);
|
||||||
|
await tester.idle();
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Chunk events of base ImageStreamCompleter are delivered', (WidgetTester tester) async {
|
testWidgets('Chunk events of base ImageStreamCompleter are delivered', (WidgetTester tester) async {
|
||||||
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
|
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
|
||||||
final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
|
final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user