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
6from telemetry.timeline import importer
7import telemetry.timeline.slice as tracing_slice
8import telemetry.timeline.thread as timeline_thread
9from telemetry.timeline import trace_data as trace_data_module
10
11
12class InspectorTimelineImporter(importer.TimelineImporter):
13  def __init__(self, model, trace_data):
14    super(InspectorTimelineImporter, self).__init__(model,
15                                                    trace_data,
16                                                    import_order=1)
17    self._events = trace_data.GetEventsFor(
18      trace_data_module.INSPECTOR_TRACE_PART)
19
20  @staticmethod
21  def GetSupportedPart():
22    return trace_data_module.INSPECTOR_TRACE_PART
23
24  def ImportEvents(self):
25    render_process = self._model.GetOrCreateProcess(0)
26    for raw_event in self._events:
27      thread = render_process.GetOrCreateThread(raw_event.get('thread', 0))
28      InspectorTimelineImporter.AddRawEventToThreadRecursive(thread, raw_event)
29
30  def FinalizeImport(self):
31    pass
32
33  @staticmethod
34  def AddRawEventToThreadRecursive(thread, raw_inspector_event):
35    pending_slice = None
36    if ('startTime' in raw_inspector_event and
37        'type' in raw_inspector_event):
38      args = {}
39      for x in raw_inspector_event:
40        if x in ('startTime', 'endTime', 'children'):
41          continue
42        args[x] = raw_inspector_event[x]
43      if len(args) == 0:
44        args = None
45      start_time = raw_inspector_event['startTime']
46      end_time = raw_inspector_event.get('endTime', start_time)
47
48      pending_slice = tracing_slice.Slice(
49        thread, 'inspector',
50        raw_inspector_event['type'],
51        start_time,
52        thread_timestamp=None,
53        args=args)
54
55    for child in raw_inspector_event.get('children', []):
56      InspectorTimelineImporter.AddRawEventToThreadRecursive(
57          thread, child)
58
59    if pending_slice:
60      pending_slice.duration = end_time - pending_slice.start
61      thread.PushSlice(pending_slice)
62
63  @staticmethod
64  def RawEventToTimelineEvent(raw_inspector_event):
65    """Converts raw_inspector_event to TimelineEvent."""
66    thread = timeline_thread.Thread(None, 0)
67    InspectorTimelineImporter.AddRawEventToThreadRecursive(
68        thread, raw_inspector_event)
69    thread.FinalizeImport()
70    assert len(thread.toplevel_slices) <= 1
71    if len(thread.toplevel_slices) == 0:
72      return None
73    return thread.toplevel_slices[0]
74