watchPerformance method Null safety

Future<void> watchPerformance(
  1. Future<void> action(
      ),
    1. {String reportKey = 'performance'}
    )

    Watches the FrameTiming during action and report it to the binding with key reportKey.

    This can be used to implement performance tests previously using traceAction and TimelineSummary from flutter_driver

    Implementation

    Future<void> watchPerformance(
      Future<void> Function() action, {
      String reportKey = 'performance',
    }) async {
      assert(() {
        if (_firstRun) {
          debugPrint(kDebugWarning);
          _firstRun = false;
        }
        return true;
      }());
    
      // The engine could batch FrameTimings and send them only once per second.
      // Delay for a sufficient time so either old FrameTimings are flushed and not
      // interfering our measurements here, or new FrameTimings are all reported.
      // TODO(CareF): remove this when flush FrameTiming is readly in engine.
      //              See https://github.com/flutter/flutter/issues/64808
      //              and https://github.com/flutter/flutter/issues/67593
      final List<FrameTiming> frameTimings = <FrameTiming>[];
      Future<void> delayForFrameTimings() async {
        int count = 0;
        while (frameTimings.isEmpty) {
          count++;
          await Future<void>.delayed(const Duration(seconds: 2));
          if (count > 20) {
            debugPrint('delayForFrameTimings is taking longer than expected...');
          }
        }
      }
    
      await Future<void>.delayed(const Duration(seconds: 2)); // flush old FrameTimings
      final TimingsCallback watcher = frameTimings.addAll;
      addTimingsCallback(watcher);
      final _GarbageCollectionInfo gcInfo = await _runAndGetGCInfo(action);
    
      await delayForFrameTimings(); // make sure all FrameTimings are reported
      removeTimingsCallback(watcher);
    
      final FrameTimingSummarizer frameTimes = FrameTimingSummarizer(
        frameTimings,
        newGenGCCount: gcInfo.newCount,
        oldGenGCCount: gcInfo.oldCount,
      );
      reportData ??= <String, dynamic>{};
      reportData![reportKey] = frameTimes.summary;
    }