Replace deprecated onReportTimings w/ frameTimings (#38861)

This is the continuation of https://github.com/flutter/engine/pull/11041 and https://github.com/flutter/flutter/pull/38574

This is not a breaking change as we're not removing `onReportTimings` API.
We're simply removing the use of it in our framework.
diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart
index 2e47923..9dd261c 100644
--- a/packages/flutter/lib/src/scheduler/binding.dart
+++ b/packages/flutter/lib/src/scheduler/binding.dart
@@ -202,14 +202,10 @@
     if (!kReleaseMode) {
       int frameNumber = 0;
 
-      // use frameTimings. https://github.com/flutter/flutter/issues/38838
-      // ignore: deprecated_member_use
-      window.onReportTimings = (List<FrameTiming> timings) {
-        for (FrameTiming frameTiming in timings) {
-          frameNumber += 1;
-          _profileFramePostEvent(frameNumber, frameTiming);
-        }
-      };
+      window.frameTimings.listen((FrameTiming frameTiming) {
+        frameNumber += 1;
+        _profileFramePostEvent(frameNumber, frameTiming);
+      });
     }
   }
 
diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart
index 8e708af..1ebed98 100644
--- a/packages/flutter/lib/src/widgets/binding.dart
+++ b/packages/flutter/lib/src/widgets/binding.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async';
 import 'dart:developer' as developer;
-import 'dart:ui' show AppLifecycleState, Locale, AccessibilityFeatures, FrameTiming, TimingsCallback;
+import 'dart:ui' show AppLifecycleState, Locale, AccessibilityFeatures, FrameTiming;
 
 import 'package:flutter/foundation.dart';
 import 'package:flutter/gestures.dart';
@@ -747,25 +747,13 @@
 
     if (_needToReportFirstFrame && _reportFirstFrame) {
       assert(!_firstFrameCompleter.isCompleted);
-      // TODO(liyuqian): use a broadcast stream approach
-      // use frameTimings. https://github.com/flutter/flutter/issues/38838
-      // ignore: deprecated_member_use
-      final TimingsCallback oldCallback = WidgetsBinding.instance.window.onReportTimings;
-      // use frameTimings. https://github.com/flutter/flutter/issues/38838
-      // ignore: deprecated_member_use
-      WidgetsBinding.instance.window.onReportTimings = (List<FrameTiming> timings) {
+      WidgetsBinding.instance.window.frameTimings.first.then((FrameTiming _) {
         if (!kReleaseMode) {
           developer.Timeline.instantSync('Rasterized first useful frame');
           developer.postEvent('Flutter.FirstFrame', <String, dynamic>{});
         }
-        if (oldCallback != null) {
-          oldCallback(timings);
-        }
-        // use frameTimings. https://github.com/flutter/flutter/issues/38838
-        // ignore: deprecated_member_use
-        WidgetsBinding.instance.window.onReportTimings = oldCallback;
         _firstFrameCompleter.complete();
-      };
+      });
     }
 
     try {
diff --git a/packages/flutter/test/foundation/service_extensions_test.dart b/packages/flutter/test/foundation/service_extensions_test.dart
index 8e4661b..a5f0ec2 100644
--- a/packages/flutter/test/foundation/service_extensions_test.dart
+++ b/packages/flutter/test/foundation/service_extensions_test.dart
@@ -79,12 +79,11 @@
     await flushMicrotasks();
     if (ui.window.onDrawFrame != null)
       ui.window.onDrawFrame();
-    // use frameTimings. https://github.com/flutter/flutter/issues/38838
-    // ignore: deprecated_member_use
-    if (ui.window.onReportTimings != null)
-      // use frameTimings. https://github.com/flutter/flutter/issues/38838
-      // ignore: deprecated_member_use
-      ui.window.onReportTimings(<ui.FrameTiming>[]);
+    final Future<ui.FrameTiming> firstFrameEventFired = window.frameTimings.first;
+    ui.window.debugReportTimings(<ui.FrameTiming>[
+      ui.FrameTiming(List<int>.filled(ui.FramePhase.values.length, 0)),
+    ]);
+    await firstFrameEventFired;
   }
 
   @override
diff --git a/packages/flutter/test/scheduler/scheduler_test.dart b/packages/flutter/test/scheduler/scheduler_test.dart
index c62fcf8d..8beeab5 100644
--- a/packages/flutter/test/scheduler/scheduler_test.dart
+++ b/packages/flutter/test/scheduler/scheduler_test.dart
@@ -132,15 +132,18 @@
   });
 
   test('Flutter.Frame event fired', () async {
-    // use frameTimings. https://github.com/flutter/flutter/issues/38838
-    // ignore: deprecated_member_use
-    window.onReportTimings(<FrameTiming>[FrameTiming(<int>[
+    // We can't use Future in scheduler_test so we'll use dynamic instead.
+    final dynamic firstFrameEventFired = window.frameTimings.first;
+
+    window.debugReportTimings(<FrameTiming>[FrameTiming(<int>[
       // build start, build finish
       10000, 15000,
       // raster start, raster finish
       16000, 20000,
     ])]);
 
+    await firstFrameEventFired;
+
     final List<Map<String, dynamic>> events = scheduler.getEventsDispatched('Flutter.Frame');
     expect(events, hasLength(1));
 
diff --git a/packages/flutter_test/lib/src/window.dart b/packages/flutter_test/lib/src/window.dart
index 1a8dc5d..1f4a99d 100644
--- a/packages/flutter_test/lib/src/window.dart
+++ b/packages/flutter_test/lib/src/window.dart
@@ -286,15 +286,7 @@
   }
 
   @override
-  // use frameTimings. https://github.com/flutter/flutter/issues/38838
-  // ignore: deprecated_member_use
-  TimingsCallback get onReportTimings => _window.onReportTimings;
-  @override
-  set onReportTimings(TimingsCallback callback) {
-    // use frameTimings. https://github.com/flutter/flutter/issues/38838
-    // ignore: deprecated_member_use
-    _window.onReportTimings = callback;
-  }
+  Stream<FrameTiming> get frameTimings => _window.frameTimings;
 
   @override
   PointerDataPacketCallback get onPointerDataPacket => _window.onPointerDataPacket;