1<!DOCTYPE html> 2<!-- 3Copyright (c) 2013 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" 9 href="/tracing/ui/extras/about_tracing/tracing_controller_client.html"> 10<link rel="import" href="/tracing/ui/extras/about_tracing/inspector_connection.html"> 11 12<script> 13'use strict'; 14 15tr.exportTo('tr.ui.e.about_tracing', function() { 16 function createResolvedPromise(data) { 17 var promise = new Promise(function(resolve, reject) { 18 if (data) 19 resolve(data); 20 else 21 resolve(); 22 }); 23 return promise; 24 } 25 26 function appendTraceChunksTo(chunks, messageString) { 27 if (typeof messageString !== 'string') 28 throw new Error('Invalid data'); 29 var re = /"params":\s*\{\s*"value":\s*\[([^]+)\]\s*\}\s*\}/; 30 var m = re.exec(messageString); 31 if (!m) 32 throw new Error('Malformed response'); 33 34 if (chunks.length > 1) 35 chunks.push(','); 36 chunks.push(m[1]); 37 } 38 39 /** 40 * Controls tracing using the inspector's FrontendAgentHost APIs. 41 * 42 * @constructor 43 */ 44 function InspectorTracingControllerClient() { 45 this.recording_ = false; 46 this.bufferUsage_ = 0; 47 this.conn_ = tr.ui.e.about_tracing.InspectorConnection.instance; 48 this.currentTraceTextChunks_ = undefined; 49 } 50 51 InspectorTracingControllerClient.prototype = { 52 __proto__: tr.ui.e.about_tracing.TracingControllerClient.prototype, 53 54 beginMonitoring: function(monitoringOptions) { 55 throw new Error('Not implemented'); 56 }, 57 58 endMonitoring: function() { 59 throw new Error('Not implemented'); 60 }, 61 62 captureMonitoring: function() { 63 throw new Error('Not implemented'); 64 }, 65 66 getMonitoringStatus: function() { 67 return createResolvedPromise({ 68 isMonitoring: false, 69 categoryFilter: '', 70 useSystemTracing: false, 71 useContinuousTracing: false, 72 useSampling: false 73 }); 74 }, 75 76 getCategories: function() { 77 var res = this.conn_.req('Tracing.getCategories', {}); 78 return res.then(function(result) { 79 return result.categories; 80 }, function(err) { 81 return []; 82 }); 83 }, 84 85 beginRecording: function(recordingOptions) { 86 if (this.recording_) 87 throw new Error('Already recording'); 88 this.recording_ = 'starting'; 89 var res = this.conn_.req( 90 'Tracing.start', 91 { 92 categories: recordingOptions.categoryFilter, 93 options: 94 [recordingOptions.tracingRecordMode, 95 (recordingOptions.useSampling ? 'enable-sampling' : '') 96 ].join(','), 97 bufferUsageReportingInterval: 1000 98 }); 99 res = res.then( 100 function ok() { 101 this.conn_.setNotificationListener( 102 'Tracing.bufferUsage', 103 this.onBufferUsageUpdateFromInspector_.bind(this)); 104 this.recording_ = true; 105 }.bind(this), 106 function error() { 107 this.recording_ = false; 108 }.bind(this)); 109 return res; 110 }, 111 112 onBufferUsageUpdateFromInspector_: function(params) { 113 this.bufferUsage_ = params.value || params.percentFull; 114 }, 115 116 beginGetBufferPercentFull: function() { 117 var that = this; 118 return new Promise(function(resolve, reject) { 119 setTimeout(function() { 120 resolve(that.bufferUsage_); 121 }, 100); 122 }); 123 }, 124 125 onDataCollected_: function(messageString) { 126 appendTraceChunksTo(this.currentTraceTextChunks_, messageString); 127 }, 128 129 endRecording: function() { 130 if (this.recording_ === false) 131 return createResolvedPromise(); 132 133 if (this.recording_ !== true) 134 throw new Error('Cannot end'); 135 136 this.currentTraceTextChunks_ = ['[']; 137 this.conn_.setNotificationListener( 138 'Tracing.dataCollected', this.onDataCollected_.bind(this)); 139 140 var clearListeners = function() { 141 this.conn_.setNotificationListener( 142 'Tracing.bufferUsage', undefined); 143 this.conn_.setNotificationListener( 144 'Tracing.tracingComplete', undefined); 145 this.conn_.setNotificationListener( 146 'Tracing.dataCollected', undefined); 147 }.bind(this); 148 149 this.recording_ = 'stopping'; 150 return new Promise(function(resolve, reject) { 151 function tracingComplete() { 152 clearListeners(); 153 this.recording_ = false; 154 this.currentTraceTextChunks_.push(']'); 155 var traceText = this.currentTraceTextChunks_.join(''); 156 this.currentTraceTextChunks_ = undefined; 157 resolve(traceText); 158 } 159 160 function tracingFailed(err) { 161 clearListeners(); 162 this.recording_ = false; 163 reject(err); 164 } 165 166 this.conn_.setNotificationListener( 167 'Tracing.tracingComplete', tracingComplete.bind(this)); 168 this.conn_.req('Tracing.end', {}).then( 169 function end() { 170 // Nothing happens here. We're really waiting for 171 // Tracing.tracingComplete. 172 }.bind(this), 173 tracingFailed.bind(this)); 174 }.bind(this)); 175 }, 176 177 defaultTraceName: function() { 178 return 'trace.json'; 179 } 180 }; 181 182 return { 183 InspectorTracingControllerClient: InspectorTracingControllerClient, 184 appendTraceChunksTo: appendTraceChunksTo 185 }; 186}); 187</script> 188