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" href="/tracing/ui/extras/about_tracing/record_selection_dialog.html"> 9 10<script> 11'use strict'; 12 13tr.exportTo('tr.ui.e.about_tracing', function() { 14 function beginRecording(tracingControllerClient) { 15 var finalPromiseResolver; 16 var finalPromise = new Promise(function(resolve, reject) { 17 finalPromiseResolver = { 18 resolve: resolve, 19 reject: reject 20 }; 21 }); 22 finalPromise.selectionDlg = undefined; 23 finalPromise.progressDlg = undefined; 24 25 function beginRecordingError(err) { 26 finalPromiseResolver.reject(err); 27 } 28 29 // Step 0: End recording. This is necessary when the user reloads the 30 // about:tracing page when we are recording. Window.onbeforeunload is not 31 // reliable to end recording on reload. 32 endRecording(tracingControllerClient).then( 33 getCategories, 34 getCategories); // Ignore error. 35 36 // But just in case, bind onbeforeunload anyway. 37 window.onbeforeunload = function(e) { 38 endRecording(tracingControllerClient); 39 }; 40 41 // Step 1: Get categories. 42 function getCategories() { 43 var p = tracingControllerClient.getCategories().then( 44 showTracingDialog, 45 beginRecordingError); 46 p.catch(function(err) { 47 beginRecordingError(err); 48 }); 49 } 50 51 // Step 2: Show tracing dialog. 52 var selectionDlg; 53 function showTracingDialog(categories) { 54 selectionDlg = new tr.ui.e.about_tracing.RecordSelectionDialog(); 55 selectionDlg.categories = categories; 56 selectionDlg.settings_key = 57 'tr.ui.e.about_tracing.record_selection_dialog'; 58 selectionDlg.addEventListener('recordclick', startTracing); 59 selectionDlg.addEventListener('closeclick', cancelRecording); 60 selectionDlg.visible = true; 61 62 finalPromise.selectionDlg = selectionDlg; 63 } 64 65 function cancelRecording() { 66 finalPromise.selectionDlg = undefined; 67 finalPromiseResolver.reject(new UserCancelledError()); 68 } 69 70 // Step 2: Do the actual tracing dialog. 71 var progressDlg; 72 var bufferPercentFullDiv; 73 function startTracing() { 74 progressDlg = new tr.ui.b.Overlay(); 75 progressDlg.textContent = 'Recording...'; 76 progressDlg.userCanClose = false; 77 78 bufferPercentFullDiv = document.createElement('div'); 79 progressDlg.appendChild(bufferPercentFullDiv); 80 81 var stopButton = document.createElement('button'); 82 stopButton.textContent = 'Stop'; 83 progressDlg.clickStopButton = function() { 84 stopButton.click(); 85 }; 86 progressDlg.appendChild(stopButton); 87 88 var recordingOptions = { 89 categoryFilter: selectionDlg.categoryFilter(), 90 useSystemTracing: selectionDlg.useSystemTracing, 91 tracingRecordMode: selectionDlg.tracingRecordMode, 92 useSampling: selectionDlg.useSampling 93 }; 94 95 96 var requestPromise = tracingControllerClient.beginRecording( 97 recordingOptions); 98 requestPromise.then( 99 function() { 100 progressDlg.visible = true; 101 stopButton.focus(); 102 updateBufferPercentFull('0'); 103 }, 104 recordFailed); 105 106 stopButton.addEventListener('click', function() { 107 // TODO(chrishenry): Currently, this only dismiss the progress 108 // dialog when tracingComplete event is received. When performing 109 // remote debugging, the tracingComplete event may be delayed 110 // considerable. We should indicate to user that we are waiting 111 // for tracingComplete event instead of being unresponsive. (For 112 // now, I disable the "stop" button, since clicking on the button 113 // again now cause exception.) 114 var recordingPromise = endRecording(tracingControllerClient); 115 recordingPromise.then( 116 recordFinished, 117 recordFailed); 118 stopButton.disabled = true; 119 bufferPercentFullDiv = undefined; 120 }); 121 finalPromise.progressDlg = progressDlg; 122 } 123 124 function recordFinished(tracedData) { 125 progressDlg.visible = false; 126 finalPromise.progressDlg = undefined; 127 finalPromiseResolver.resolve(tracedData); 128 } 129 130 function recordFailed(err) { 131 progressDlg.visible = false; 132 finalPromise.progressDlg = undefined; 133 finalPromiseResolver.reject(err); 134 } 135 136 function getBufferPercentFull() { 137 if (!bufferPercentFullDiv) 138 return; 139 140 tracingControllerClient.beginGetBufferPercentFull().then( 141 updateBufferPercentFull); 142 } 143 144 function updateBufferPercentFull(percent_full) { 145 if (!bufferPercentFullDiv) 146 return; 147 148 percent_full = Math.round(100 * parseFloat(percent_full)); 149 var newText = 'Buffer usage: ' + percent_full + '%'; 150 if (bufferPercentFullDiv.textContent != newText) 151 bufferPercentFullDiv.textContent = newText; 152 153 window.setTimeout(getBufferPercentFull, 500); 154 } 155 156 // Thats it! We're done. 157 return finalPromise; 158 }; 159 160 function endRecording(tracingControllerClient) { 161 return tracingControllerClient.endRecording(); 162 } 163 164 function defaultTraceName(tracingControllerClient) { 165 return tracingControllerClient.defaultTraceName(); 166 } 167 168 function UserCancelledError() { 169 Error.apply(this, arguments); 170 } 171 UserCancelledError.prototype = { 172 __proto__: Error.prototype 173 }; 174 175 return { 176 beginRecording: beginRecording, 177 UserCancelledError: UserCancelledError, 178 defaultTraceName: defaultTraceName 179 }; 180}); 181</script> 182