OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
| 5 import cStringIO |
5 import json | 6 import json |
6 import logging | 7 import logging |
7 import socket | 8 import socket |
8 import threading | 9 import threading |
9 | 10 |
| 11 |
| 12 from telemetry import trace_event_importer |
| 13 from telemetry import trace_result |
10 from telemetry import util | 14 from telemetry import util |
11 from telemetry import websocket | 15 from telemetry import websocket |
12 | 16 |
13 | 17 |
14 class TracingUnsupportedException(Exception): | 18 class TracingUnsupportedException(Exception): |
15 pass | 19 pass |
16 | 20 |
| 21 class TraceResultImpl(object): |
| 22 def __init__(self, tracing_data): |
| 23 self._tracing_data = tracing_data |
17 | 24 |
| 25 def Serialize(self, f): |
| 26 f.write('{"traceEvents": [') |
| 27 d = self._tracing_data |
| 28 # Note: we're not using ','.join here because the strings that are in the |
| 29 # tracing data are typically many megabytes in size. In the fast case, f is |
| 30 # just a file, so by skipping the in memory step we keep our memory |
| 31 # footprint low and avoid additional processing. |
| 32 if len(d) == 0: |
| 33 pass |
| 34 elif len(d) == 1: |
| 35 f.write(d[0]) |
| 36 else: |
| 37 f.write(d[0]) |
| 38 for i in range(1, len(d)): |
| 39 f.write(',') |
| 40 f.write(d[i]) |
| 41 f.write(']}') |
| 42 |
| 43 def AsTimelineModel(self): |
| 44 f = cStringIO.StringIO() |
| 45 self.Serialize(f) |
| 46 return trace_event_importer.Import( |
| 47 f.getvalue()) |
18 | 48 |
19 class TracingBackend(object): | 49 class TracingBackend(object): |
20 def __init__(self, devtools_port): | 50 def __init__(self, devtools_port): |
21 debugger_url = 'ws://localhost:%i/devtools/browser' % devtools_port | 51 debugger_url = 'ws://localhost:%i/devtools/browser' % devtools_port |
22 self._socket = websocket.create_connection(debugger_url) | 52 self._socket = websocket.create_connection(debugger_url) |
23 self._next_request_id = 0 | 53 self._next_request_id = 0 |
24 self._cur_socket_timeout = 0 | 54 self._cur_socket_timeout = 0 |
25 self._thread = None | 55 self._thread = None |
26 self._tracing_data = [] | 56 self._tracing_data = [] |
27 | 57 |
28 def BeginTracing(self): | 58 def BeginTracing(self): |
29 self._CheckNotificationSupported() | 59 self._CheckNotificationSupported() |
30 req = {'method': 'Tracing.start'} | 60 req = {'method': 'Tracing.start'} |
31 self._SyncRequest(req) | 61 self._SyncRequest(req) |
32 # Tracing.start will send asynchronous notifications containing trace | 62 # Tracing.start will send asynchronous notifications containing trace |
33 # data, until Tracing.end is called. | 63 # data, until Tracing.end is called. |
34 self._thread = threading.Thread(target=self._TracingReader) | 64 self._thread = threading.Thread(target=self._TracingReader) |
35 self._thread.start() | 65 self._thread.start() |
36 | 66 |
37 def EndTracing(self): | 67 def EndTracing(self): |
38 req = {'method': 'Tracing.end'} | 68 req = {'method': 'Tracing.end'} |
39 self._SyncRequest(req) | 69 self._SyncRequest(req) |
40 self._thread.join() | 70 self._thread.join() |
41 self._thread = None | 71 self._thread = None |
42 | 72 |
43 def GetTraceAndReset(self): | 73 def GetTraceResultAndReset(self): |
44 assert not self._thread | 74 assert not self._thread |
45 ret = '{"traceEvents": [' + ','.join(self._tracing_data) + ']}' | 75 ret = trace_result.TraceResult( |
| 76 TraceResultImpl(self._tracing_data)) |
46 self._tracing_data = [] | 77 self._tracing_data = [] |
47 return ret | 78 return ret |
48 | 79 |
49 def Close(self): | 80 def Close(self): |
50 if self._socket: | 81 if self._socket: |
51 self._socket.close() | 82 self._socket.close() |
52 self._socket = None | 83 self._socket = None |
53 | 84 |
54 def _TracingReader(self): | 85 def _TracingReader(self): |
55 while self._socket: | 86 while self._socket: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 logging.debug('got [%s]', data) | 124 logging.debug('got [%s]', data) |
94 res = json.loads(data) | 125 res = json.loads(data) |
95 if res['id'] != req['id']: | 126 if res['id'] != req['id']: |
96 logging.debug('Dropped reply: %s', json.dumps(res)) | 127 logging.debug('Dropped reply: %s', json.dumps(res)) |
97 continue | 128 continue |
98 if res.get('response'): | 129 if res.get('response'): |
99 raise TracingUnsupportedException( | 130 raise TracingUnsupportedException( |
100 'Tracing not supported for this browser') | 131 'Tracing not supported for this browser') |
101 elif res.get('error', {}).get('code') == -1: | 132 elif res.get('error', {}).get('code') == -1: |
102 return | 133 return |
OLD | NEW |