timeline.dart 4.27 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// Timeline data recorded by the Flutter runtime.
class Timeline {
7 8 9 10 11 12
  /// Creates a timeline given JSON-encoded timeline data.
  ///
  /// [json] is in the `chrome://tracing` format. It can be saved to a file
  /// and loaded in Chrome for visual inspection.
  ///
  /// See https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
13
  factory Timeline.fromJson(Map<String, dynamic> json) {
14
    return Timeline._(json, _parseEvents(json));
15 16 17 18 19 20 21 22
  }

  Timeline._(this.json, this.events);

  /// The original timeline JSON.
  final Map<String, dynamic> json;

  /// List of all timeline events.
23 24 25
  ///
  /// This is parsed from "traceEvents" data within [json] and sorted by
  /// timestamp. Anything without a valid timestamp is put in the beginning.
26
  ///
nt4f04uNd's avatar
nt4f04uNd committed
27
  /// This will be null if there are no "traceEvents" in the [json].
28
  final List<TimelineEvent>? events;
29 30 31 32
}

/// A single timeline event.
class TimelineEvent {
33
  /// Creates a timeline event given JSON-encoded event data.
34
  TimelineEvent(this.json)
35 36 37 38 39
      : name = json['name'] as String?,
        category = json['cat'] as String?,
        phase = json['ph'] as String?,
        processId = json['pid'] as int?,
        threadId = json['tid'] as int?,
40 41 42 43 44 45
        duration = json['dur'] != null
            ? Duration(microseconds: json['dur'] as int)
            : null,
        threadDuration = json['tdur'] != null
            ? Duration(microseconds: json['tdur'] as int)
            : null,
46 47 48
        timestampMicros = json['ts'] as int?,
        threadTimestampMicros = json['tts'] as int?,
        arguments = json['args'] as Map<String, dynamic>?;
49 50 51 52 53 54 55

  /// The original event JSON.
  final Map<String, dynamic> json;

  /// The name of the event.
  ///
  /// Corresponds to the "name" field in the JSON event.
56
  final String? name;
57 58 59 60

  /// Event category. Events with different names may share the same category.
  ///
  /// Corresponds to the "cat" field in the JSON event.
61
  final String? category;
62 63 64 65 66

  /// For a given long lasting event, denotes the phase of the event, such as
  /// "B" for "event began", and "E" for "event ended".
  ///
  /// Corresponds to the "ph" field in the JSON event.
67
  final String? phase;
68 69 70 71

  /// ID of process that emitted the event.
  ///
  /// Corresponds to the "pid" field in the JSON event.
72
  final int? processId;
73 74 75 76

  /// ID of thread that issues the event.
  ///
  /// Corresponds to the "tid" field in the JSON event.
77
  final int? threadId;
78 79 80 81 82 83 84

  /// The duration of the event.
  ///
  /// Note, some events are reported with duration. Others are reported as a
  /// pair of begin/end events.
  ///
  /// Corresponds to the "dur" field in the JSON event.
85
  final Duration? duration;
86

87 88 89 90 91 92
  /// The thread duration of the event.
  ///
  /// Note, some events are reported with duration. Others are reported as a
  /// pair of begin/end events.
  ///
  /// Corresponds to the "tdur" field in the JSON event.
93
  final Duration? threadDuration;
94

95 96 97
  /// Time passed since tracing was enabled, in microseconds.
  ///
  /// Corresponds to the "ts" field in the JSON event.
98
  final int? timestampMicros;
99 100 101 102

  /// Thread clock time, in microseconds.
  ///
  /// Corresponds to the "tts" field in the JSON event.
103
  final int? threadTimestampMicros;
104 105 106 107

  /// Arbitrary data attached to the event.
  ///
  /// Corresponds to the "args" field in the JSON event.
108
  final Map<String, dynamic>? arguments;
109 110
}

111 112
List<TimelineEvent>? _parseEvents(Map<String, dynamic> json) {
  final List<dynamic>? jsonEvents = json['traceEvents'] as List<dynamic>?;
113

114
  if (jsonEvents == null) {
115
    return null;
116
  }
117

118 119 120 121 122 123 124
  final List<TimelineEvent> timelineEvents =
      Iterable.castFrom<dynamic, Map<String, dynamic>>(jsonEvents)
          .map<TimelineEvent>(
              (Map<String, dynamic> eventJson) => TimelineEvent(eventJson))
          .toList();

  timelineEvents.sort((TimelineEvent e1, TimelineEvent e2) {
125 126
    final int? ts1 = e1.timestampMicros;
    final int? ts2 = e2.timestampMicros;
127 128 129 130 131 132 133 134 135 136 137 138 139 140
    if (ts1 == null) {
      if (ts2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (ts2 == null) {
      return 1;
    } else {
      return ts1.compareTo(ts2);
    }
  });

  return timelineEvents;
141
}