diff --git a/packages/flutter/lib/src/painting/image_stream.dart b/packages/flutter/lib/src/painting/image_stream.dart index 2f5537a353..0d5dde6751 100644 --- a/packages/flutter/lib/src/painting/image_stream.dart +++ b/packages/flutter/lib/src/painting/image_stream.dart @@ -8,6 +8,8 @@ import 'dart:ui' as ui show Codec, FrameInfo, Image; import 'package:flutter/foundation.dart'; import 'package:flutter/scheduler.dart'; +const String _flutterWidgetsLibrary = 'package:flutter/widgets.dart'; + /// A [dart:ui.Image] object with its corresponding scale. /// /// ImageInfo objects are used by [ImageStream] objects to represent the @@ -437,6 +439,15 @@ class ImageStream with Diagnosticable { class ImageStreamCompleterHandle { ImageStreamCompleterHandle._(ImageStreamCompleter this._completer) { _completer!._keepAliveHandles += 1; + // TODO(polina-c): stop duplicating code across disposables + // https://github.com/flutter/flutter/issues/137435 + if (kFlutterMemoryAllocationsEnabled) { + MemoryAllocations.instance.dispatchObjectCreated( + library: _flutterWidgetsLibrary, + className: '$ImageStreamCompleterHandle', + object: this, + ); + } } ImageStreamCompleter? _completer; @@ -453,6 +464,11 @@ class ImageStreamCompleterHandle { _completer!._keepAliveHandles -= 1; _completer!._maybeDispose(); _completer = null; + // TODO(polina-c): stop duplicating code across disposables + // https://github.com/flutter/flutter/issues/137435 + if (kFlutterMemoryAllocationsEnabled) { + MemoryAllocations.instance.dispatchObjectDisposed(object: this); + } } } diff --git a/packages/flutter/test/painting/image_stream_test.dart b/packages/flutter/test/painting/image_stream_test.dart index 141ed20040..7567522315 100644 --- a/packages/flutter/test/painting/image_stream_test.dart +++ b/packages/flutter/test/painting/image_stream_test.dart @@ -871,4 +871,21 @@ void main() { expect(synchronouslyCalled, false); }); + + test('ImageStreamCompleterHandle dispatches memory events', () async { + await expectLater( + await memoryEvents( + () { + final StreamController streamController = StreamController(); + addTearDown(streamController.close); + final ImageStreamCompleterHandle imageStreamCompleterHandle = FakeEventReportingImageStreamCompleter( + chunkEvents: streamController.stream, + ).keepAlive(); + imageStreamCompleterHandle.dispose(); + }, + ImageStreamCompleterHandle, + ), + areCreateAndDispose, + ); + }); }