|
4 | 4 |
|
5 | 5 | import 'dart:async';
|
6 | 6 | import 'dart:developer' as developer;
|
| 7 | +import 'dart:ui'; |
7 | 8 |
|
8 | 9 | import 'package:flutter/rendering.dart';
|
9 | 10 | import 'package:flutter_test/flutter_test.dart';
|
@@ -81,6 +82,10 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
|
81 | 82 |
|
82 | 83 | Size _surfaceSize;
|
83 | 84 |
|
| 85 | + // This flag is used to print warning messages when tracking performance |
| 86 | + // under debug mode. |
| 87 | + static bool _firstRun = false; |
| 88 | + |
84 | 89 | /// Artificially changes the surface size to `size` on the Widget binding,
|
85 | 90 | /// then flushes microtasks.
|
86 | 91 | ///
|
@@ -282,4 +287,43 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
|
282 | 287 | reportData ??= <String, dynamic>{};
|
283 | 288 | reportData[reportKey] = timeline.toJson();
|
284 | 289 | }
|
| 290 | + |
| 291 | + /// Watches the [FrameTiming] during `action` and report it to the binding |
| 292 | + /// with key `reportKey`. |
| 293 | + /// |
| 294 | + /// This can be used to implement performance tests previously using |
| 295 | + /// [traceAction] and [TimelineSummary] from [flutter_driver] |
| 296 | + Future<void> watchPerformance( |
| 297 | + Future<void> action(), { |
| 298 | + String reportKey = 'performance', |
| 299 | + }) async { |
| 300 | + assert(() { |
| 301 | + if (_firstRun) { |
| 302 | + debugPrint(kDebugWarning); |
| 303 | + _firstRun = false; |
| 304 | + } |
| 305 | + return true; |
| 306 | + }()); |
| 307 | + |
| 308 | + // The engine could batch FrameTimings and send them only once per second. |
| 309 | + // Delay for a sufficient time so either old FrameTimings are flushed and not |
| 310 | + // interfering our measurements here, or new FrameTimings are all reported. |
| 311 | + // TODO(CareF): remove this when flush FrameTiming is readly in engine. |
| 312 | + // See https://github.com/flutter/flutter/issues/64808 |
| 313 | + // and https://github.com/flutter/flutter/issues/67593 |
| 314 | + Future<void> delayForFrameTimings() => |
| 315 | + Future<void>.delayed(const Duration(seconds: 2)); |
| 316 | + |
| 317 | + await delayForFrameTimings(); // flush old FrameTimings |
| 318 | + final List<FrameTiming> frameTimings = <FrameTiming>[]; |
| 319 | + final TimingsCallback watcher = frameTimings.addAll; |
| 320 | + addTimingsCallback(watcher); |
| 321 | + await action(); |
| 322 | + await delayForFrameTimings(); // make sure all FrameTimings are reported |
| 323 | + removeTimingsCallback(watcher); |
| 324 | + final FrameTimingSummarizer frameTimes = |
| 325 | + FrameTimingSummarizer(frameTimings); |
| 326 | + reportData ??= <String, dynamic>{}; |
| 327 | + reportData[reportKey] = frameTimes.summary; |
| 328 | + } |
285 | 329 | }
|
0 commit comments