1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4'''Imports event data obtained from the inspector's timeline.'''
5
6import telemetry.timeline.slice as tracing_slice
7import telemetry.timeline.thread as timeline_thread
8from telemetry.timeline import importer
9from telemetry.timeline import inspector_timeline_data
10
11
12class InspectorTimelineImporter(importer.TimelineImporter):
13  def __init__(self, model, timeline_data):
14    super(InspectorTimelineImporter, self).__init__(model, timeline_data)
15
16  @staticmethod
17  def CanImport(timeline_data):
18    ''' Checks if timeline_data is from the inspector timeline. We assume
19    that if the first event is a valid inspector event, we can import the
20    entire list.
21    '''
22    if not isinstance(timeline_data,
23                      inspector_timeline_data.InspectorTimelineData):
24      return False
25
26    event_data = timeline_data.EventData()
27
28    if isinstance(event_data, list) and len(event_data):
29      event_datum = event_data[0]
30      return 'startTime' in event_datum and 'type' in event_datum
31    return False
32
33  def ImportEvents(self):
34    render_process = self._model.GetOrCreateProcess(0)
35    for raw_event in self._timeline_data.EventData():
36      thread = render_process.GetOrCreateThread(raw_event.get('thread', 0))
37      InspectorTimelineImporter.AddRawEventToThreadRecursive(thread, raw_event)
38
39  def FinalizeImport(self):
40    pass
41
42  @staticmethod
43  def AddRawEventToThreadRecursive(thread, raw_inspector_event):
44    pending_slice = None
45    if ('startTime' in raw_inspector_event and
46        'type' in raw_inspector_event):
47      args = {}
48      for x in raw_inspector_event:
49        if x in ('startTime', 'endTime', 'children'):
50          continue
51        args[x] = raw_inspector_event[x]
52      if len(args) == 0:
53        args = None
54      start_time = raw_inspector_event['startTime']
55      end_time = raw_inspector_event.get('endTime', start_time)
56
57      pending_slice = tracing_slice.Slice(
58        thread, 'inspector',
59        raw_inspector_event['type'],
60        start_time,
61        thread_timestamp=None,
62        args=args)
63
64    for child in raw_inspector_event.get('children', []):
65      InspectorTimelineImporter.AddRawEventToThreadRecursive(
66          thread, child)
67
68    if pending_slice:
69      pending_slice.duration = end_time - pending_slice.start
70      thread.PushSlice(pending_slice)
71
72  @staticmethod
73  def RawEventToTimelineEvent(raw_inspector_event):
74    """Converts raw_inspector_event to TimelineEvent."""
75    thread = timeline_thread.Thread(None, 0)
76    InspectorTimelineImporter.AddRawEventToThreadRecursive(
77        thread, raw_inspector_event)
78    thread.FinalizeImport()
79    assert len(thread.toplevel_slices) <= 1
80    if len(thread.toplevel_slices) == 0:
81      return None
82    return thread.toplevel_slices[0]
83