| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| |
| /** |
| * @fileoverview State and UI for trace data collection. |
| */ |
| cr.define('tracing', function() { |
| |
| function TracingController() { |
| this.overlay_ = document.createElement('div'); |
| this.overlay_.className = 'tracing-overlay'; |
| |
| cr.ui.decorate(this.overlay_, tracing.Overlay); |
| |
| this.statusDiv_ = document.createElement('div'); |
| this.overlay_.appendChild(this.statusDiv_); |
| |
| this.bufferPercentDiv_ = document.createElement('div'); |
| this.overlay_.appendChild(this.bufferPercentDiv_); |
| |
| this.stopButton_ = document.createElement('button'); |
| this.stopButton_.onclick = this.endTracing.bind(this); |
| this.stopButton_.textContent = 'Stop tracing'; |
| this.overlay_.appendChild(this.stopButton_); |
| |
| this.traceEvents_ = []; |
| |
| this.onKeydownBoundToThis_ = this.onKeydown_.bind(this); |
| this.onKeypressBoundToThis_ = this.onKeypress_.bind(this); |
| |
| chrome.send('tracingControllerInitialized'); |
| } |
| |
| TracingController.prototype = { |
| __proto__: cr.EventTarget.prototype, |
| |
| gpuInfo_: undefined, |
| clientInfo_: undefined, |
| tracingEnabled_: false, |
| tracingEnding_: false, |
| |
| onRequestBufferPercentFullComplete: function(percent_full) { |
| if (!this.overlay_.visible) |
| return; |
| |
| window.setTimeout(this.beginRequestBufferPercentFull_.bind(this), 250); |
| |
| this.bufferPercentDiv_.textContent = 'Buffer usage: ' + |
| Math.round(100 * percent_full) + '%'; |
| }, |
| |
| /** |
| * Begin requesting the buffer fullness |
| */ |
| beginRequestBufferPercentFull_: function() { |
| chrome.send('beginRequestBufferPercentFull'); |
| }, |
| |
| /** |
| * Called by info_view to empty the trace buffer |
| */ |
| beginTracing: function() { |
| if (this.tracingEnabled_) |
| throw Error('Tracing already begun.'); |
| |
| this.stopButton_.hidden = false; |
| this.statusDiv_.textContent = 'Tracing active.'; |
| this.overlay_.visible = true; |
| |
| this.tracingEnabled_ = true; |
| console.log('Beginning to trace...'); |
| this.statusDiv_.textContent = 'Tracing active.'; |
| |
| this.traceEvents_ = []; |
| chrome.send('beginTracing'); |
| this.beginRequestBufferPercentFull_(); |
| |
| this.tracingEnabled_ = true; |
| |
| var e = new cr.Event('traceBegun'); |
| e.events = this.traceEvents_; |
| this.dispatchEvent(e); |
| |
| e = new cr.Event('traceEventsChanged'); |
| e.numEvents = this.traceEvents_.length; |
| this.dispatchEvent(e); |
| |
| window.addEventListener('keypress', this.onKeypressBoundToThis_); |
| window.addEventListener('keydown', this.onKeydownBoundToThis_); |
| }, |
| |
| onKeydown_: function(e) { |
| if (e.keyCode == 27) { |
| this.endTracing(); |
| } |
| }, |
| |
| onKeypress_: function(e) { |
| if (e.keyIdentifier == 'Enter') { |
| this.endTracing(); |
| } |
| }, |
| |
| /** |
| * Called from gpu c++ code when ClientInfo is updated. |
| */ |
| onClientInfoUpdate: function(clientInfo) { |
| this.clientInfo_ = clientInfo; |
| }, |
| |
| /** |
| * Called from gpu c++ code when GPU Info is updated. |
| */ |
| onGpuInfoUpdate: function(gpuInfo) { |
| this.gpuInfo_ = gpuInfo; |
| }, |
| |
| /** |
| * Checks whether tracing is enabled |
| */ |
| get isTracingEnabled() { |
| return this.tracingEnabled_; |
| }, |
| |
| /** |
| * Gets the currently traced events. If tracing is active, then |
| * this can change on the fly. |
| */ |
| get traceEvents() { |
| return this.traceEvents_; |
| }, |
| |
| /** |
| * Called by tracing c++ code when new trace data arrives. |
| */ |
| onTraceDataCollected: function(events) { |
| this.statusDiv_.textContent = 'Processing trace...'; |
| this.traceEvents_.push.apply(this.traceEvents_, events); |
| }, |
| |
| /** |
| * Called by info_view to finish tracing and update all views. |
| */ |
| endTracing: function() { |
| if (!this.tracingEnabled_) throw new Error('Tracing not begun.'); |
| if (this.tracingEnding_) return; |
| this.tracingEnding_ = true; |
| |
| this.statusDiv_.textContent = 'Ending trace...'; |
| console.log('Finishing trace'); |
| this.statusDiv_.textContent = 'Downloading trace data...'; |
| this.stopButton_.hidden = true; |
| // delay sending endTracingAsync until we get a chance to |
| // update the screen... |
| window.setTimeout(function() { |
| chrome.send('endTracingAsync'); |
| }, 100); |
| }, |
| |
| /** |
| * Called by the browser when all processes complete tracing. |
| */ |
| onEndTracingComplete: function() { |
| window.removeEventListener('keydown', this.onKeydownBoundToThis_); |
| window.removeEventListener('keypress', this.onKeypressBoundToThis_); |
| this.overlay_.visible = false; |
| this.tracingEnabled_ = false; |
| this.tracingEnding_ = false; |
| console.log('onEndTracingComplete p1 with ' + |
| this.traceEvents_.length + ' events.'); |
| var e = new cr.Event('traceEnded'); |
| e.events = this.traceEvents_; |
| this.dispatchEvent(e); |
| }, |
| |
| /** |
| * Tells browser to put up a load dialog and load the trace file |
| */ |
| beginLoadTraceFile: function() { |
| chrome.send('loadTraceFile'); |
| }, |
| |
| /** |
| * Called by the browser when a trace file is loaded. |
| */ |
| onLoadTraceFileComplete: function(data) { |
| if (data.traceEvents) { |
| this.traceEvents_ = data.traceEvents; |
| } else { // path for loading traces saved without metadata |
| if (!data.length) |
| console.log('Expected an array when loading the trace file'); |
| else |
| this.traceEvents_ = data; |
| } |
| var e = new cr.Event('loadTraceFileComplete'); |
| e.events = this.traceEvents_; |
| this.dispatchEvent(e); |
| }, |
| |
| /** |
| * Called by the browser when loading a trace file was canceled. |
| */ |
| onLoadTraceFileCanceled: function() { |
| cr.dispatchSimpleEvent(this, 'loadTraceFileCanceled'); |
| }, |
| |
| /** |
| * Tells browser to put up a save dialog and save the trace file |
| */ |
| beginSaveTraceFile: function(traceEvents) { |
| var data = { |
| traceEvents: traceEvents, |
| clientInfo: this.clientInfo_, |
| gpuInfo: this.gpuInfo_ |
| }; |
| chrome.send('saveTraceFile', [JSON.stringify(data)]); |
| }, |
| |
| /** |
| * Called by the browser when a trace file is saveed. |
| */ |
| onSaveTraceFileComplete: function() { |
| cr.dispatchSimpleEvent(this, 'saveTraceFileComplete'); |
| }, |
| |
| /** |
| * Called by the browser when saving a trace file was canceled. |
| */ |
| onSaveTraceFileCanceled: function() { |
| cr.dispatchSimpleEvent(this, 'saveTraceFileCanceled'); |
| }, |
| |
| selfTest: function() { |
| this.beginTracing(); |
| window.setTimeout(this.endTracing.bind(This), 500); |
| } |
| }; |
| return { |
| TracingController: TracingController |
| }; |
| }); |
| |