OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 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 from telemetry.timeline_event import TimelineEvent | |
5 from telemetry.timeline_model import TimelineModel | |
6 | |
7 class TabBackendException(Exception): | |
8 pass | |
9 | |
10 class InspectorTimeline(object): | |
11 """Implementation of dev tools timeline.""" | |
12 class Recorder(object): | |
13 """Utility class to Start / Stop recording timeline.""" | |
14 def __init__(self, tab): | |
15 self._tab = tab | |
16 | |
17 def __enter__(self): | |
18 self._tab.StartTimelineRecording() | |
19 | |
20 def __exit__(self, *args): | |
21 self._tab.StopTimelineRecording() | |
22 | |
23 def __init__(self, inspector_backend): | |
24 self._inspector_backend = inspector_backend | |
25 self._is_recording = False | |
26 self._timeline_model = None | |
27 | |
28 @property | |
29 def timeline_model(self): | |
30 return self._timeline_model | |
31 | |
32 def Start(self): | |
33 if self._is_recording: | |
34 return | |
35 self._is_recording = True | |
36 self._timeline_model = TimelineModel() | |
37 self._inspector_backend.RegisterDomain('Timeline', | |
38 self._OnNotification, self._OnClose) | |
39 req = {'method': 'Timeline.start'} | |
40 self._SendSyncRequest(req) | |
41 | |
42 def Stop(self): | |
43 if not self._is_recording: | |
44 raise TabBackendException('Stop() called but not started') | |
45 self._is_recording = False | |
46 self._timeline_model.DidFinishRecording() | |
47 req = {'method': 'Timeline.stop'} | |
48 self._SendSyncRequest(req) | |
49 self._inspector_backend.UnregisterDomain('Timeline') | |
50 | |
51 def _SendSyncRequest(self, req, timeout=60): | |
52 res = self._inspector_backend.SyncRequest(req, timeout) | |
53 if 'error' in res: | |
54 raise TabBackendException(res['error']['message']) | |
55 return res['result'] | |
56 | |
57 def _OnNotification(self, msg): | |
58 if not self._is_recording: | |
59 return | |
60 if 'method' in msg and msg['method'] == 'Timeline.eventRecorded': | |
61 self._OnEventRecorded(msg) | |
62 | |
63 def _OnEventRecorded(self, msg): | |
64 record = msg.get('params', {}).get('record') | |
65 if record: | |
66 newly_created_event = InspectorTimeline.RawEventToTimelineEvent(record) | |
67 if newly_created_event: | |
68 self._timeline_model.AddEvent(newly_created_event) | |
69 | |
70 @staticmethod | |
71 def RawEventToTimelineEvent(raw_inspector_event): | |
72 """Converts raw_inspector_event to TimelineEvent.""" | |
73 return InspectorTimeline._RawEventToTimelineEventRecursive( | |
74 None, raw_inspector_event) | |
75 | |
76 @staticmethod | |
77 def _RawEventToTimelineEventRecursive( | |
78 parent_for_created_events, raw_inspector_event): | |
79 """ | |
80 Creates a new TimelineEvent for the raw_inspector_event, if possible, adding | |
81 it to the provided parent_for_created_events. | |
82 | |
83 It then recurses on any child events found inside, building a tree of | |
84 TimelineEvents. | |
85 | |
86 Returns the root of the created tree, or None. | |
87 """ | |
88 # Create a TimelineEvent for this raw_inspector_event if possible. Only | |
89 # events with start-time and end-time get imported. | |
90 if ('startTime' in raw_inspector_event and | |
91 'endTime' in raw_inspector_event): | |
92 args = {} | |
93 for x in raw_inspector_event: | |
94 if x in ('startTime', 'endTime', 'children'): | |
95 continue | |
96 args[x] = raw_inspector_event[x] | |
97 if len(args) == 0: | |
98 args = None | |
99 newly_created_event = TimelineEvent( | |
100 name=raw_inspector_event['type'], | |
101 start_time_ms=raw_inspector_event['startTime'], | |
102 duration_ms=(raw_inspector_event['endTime'] - | |
103 raw_inspector_event['startTime']), | |
104 args=args) | |
105 if parent_for_created_events: | |
106 parent_for_created_events.children.append(newly_created_event) | |
107 else: | |
108 newly_created_event = None | |
109 | |
110 # Process any children events, creating TimelineEvents for them as well. | |
111 if newly_created_event: | |
112 parent_for_children = newly_created_event | |
113 else: | |
114 parent_for_children = parent_for_created_events | |
115 for child in raw_inspector_event.get('children', []): | |
116 InspectorTimeline._RawEventToTimelineEventRecursive( | |
117 parent_for_children, child) | |
118 return newly_created_event | |
119 | |
120 def _OnClose(self): | |
121 pass | |
OLD | NEW |