1
1
import 'dart:ui' ;
2
-
3
2
import 'package:flutter/widgets.dart' ;
4
3
import 'package:sentry/sentry.dart' ;
5
4
@@ -11,66 +10,61 @@ class FrameTracker {
11
10
}) : _binding = binding;
12
11
13
12
final WidgetsBinding _binding;
14
- bool ? _isSupported;
15
-
16
- // Checks wether [FrameTracker] is supported on this Flutter version
17
- bool get isSupported {
18
- // TODO: Check if this works on web
19
- try {
20
- (_binding.window as dynamic ).frameData.frameNumber as int ;
21
- } on NoSuchMethodError catch (_) {
22
- return _isSupported ?? = false ;
23
- }
24
- return _isSupported ?? = true ;
25
- }
26
13
27
14
SingletonFlutterWindow get window => _binding.window;
28
15
29
16
final Duration slowFrameThreshold;
30
17
final Duration frozenFrameThreshold;
31
18
32
- var startFrameNumber = - 1 ;
33
- var endFrameNumber = - 1 ;
19
+ DateTime ? _timeStamp;
34
20
35
- void start () {
36
- if (! isSupported) {
21
+ var _frameCount = 0 ;
22
+ var _slowCount = 0 ;
23
+ var _frozenCount = 0 ;
24
+
25
+ void _frameCallback (Duration _) {
26
+ final timeStamp = _timeStamp;
27
+ if (timeStamp == null ) {
37
28
return ;
38
29
}
39
- startFrameNumber = window.currentFrameNumber;
40
- }
41
30
42
- List <SentryMeasurement >? finish () {
43
- if (! isSupported || startFrameNumber == - 1 ) {
44
- // Either the current Flutter version doesn't support frame numbers yet
45
- // or frame tracking hasn't started.
46
- return null ;
31
+ // postFrameCallbacks are called just once,
32
+ // so we have to add it each frame.
33
+ _binding.addPostFrameCallback (_frameCallback);
34
+
35
+ final now = DateTime .now ();
36
+ _timeStamp = now;
37
+ final duration = timeStamp.difference (now).abs ();
38
+
39
+ if (duration > frozenFrameThreshold) {
40
+ _frozenCount++ ;
41
+ } else if (duration > slowFrameThreshold) {
42
+ _slowCount++ ;
47
43
}
48
- endFrameNumber = window.currentFrameNumber;
49
44
50
- final metrics = _listToMetrics (
51
- startFrameNumber,
52
- endFrameNumber,
53
- );
54
- _reset ();
55
- return metrics;
45
+ _frameCount++ ;
56
46
}
57
47
58
- void _reset () {
59
- startFrameNumber = - 1 ;
60
- endFrameNumber = - 1 ;
48
+ void start () {
49
+ _timeStamp = DateTime . now () ;
50
+ _binding. addPostFrameCallback (_frameCallback) ;
61
51
}
62
52
63
- static List <SentryMeasurement > _listToMetrics (
64
- int startFrameNumber,
65
- int endFrameNumber,
66
- ) {
67
- final frameCount = endFrameNumber - startFrameNumber;
53
+ List <SentryMeasurement > finish () {
54
+ final metrics = [
55
+ SentryMeasurement .totalFrames (_frameCount),
56
+ SentryMeasurement .frozenFrames (_frozenCount),
57
+ SentryMeasurement .slowFrames (_slowCount),
58
+ ];
68
59
69
- return [SentryMeasurement .totalFrames (frameCount.toDouble ())];
60
+ _reset ();
61
+ return metrics;
70
62
}
71
- }
72
63
73
- extension _SingletonFlutterWindowExtension on SingletonFlutterWindow {
74
- // Code to make this compatible with Flutter < 2.8
75
- int get currentFrameNumber => (this as dynamic ).frameData.frameNumber as int ;
64
+ void _reset () {
65
+ _timeStamp = null ;
66
+ _frameCount = 0 ;
67
+ _slowCount = 0 ;
68
+ _frozenCount = 0 ;
69
+ }
76
70
}
0 commit comments