| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 /** | 5 /** |
| 6 * @constructor | 6 * @constructor |
| 7 * @param {!WebInspector.Target} target |
| 7 * @param {!WebInspector.TimelineLifecycleDelegate} delegate | 8 * @param {!WebInspector.TimelineLifecycleDelegate} delegate |
| 8 * @param {!WebInspector.TracingModel} tracingModel | 9 * @param {!WebInspector.TracingModel} tracingModel |
| 9 * @implements {WebInspector.TargetManager.Observer} | 10 * @implements {WebInspector.TargetManager.Observer} |
| 10 * @implements {WebInspector.TracingManagerClient} | 11 * @implements {WebInspector.TracingManagerClient} |
| 11 */ | 12 */ |
| 12 WebInspector.TimelineController = function(delegate, tracingModel) | 13 WebInspector.TimelineController = function(target, delegate, tracingModel) |
| 13 { | 14 { |
| 14 this._delegate = delegate; | 15 this._delegate = delegate; |
| 16 this._target = target; |
| 15 this._tracingModel = tracingModel; | 17 this._tracingModel = tracingModel; |
| 16 this._targets = []; | 18 this._targets = []; |
| 17 WebInspector.targetManager.observeTargets(this); | 19 WebInspector.targetManager.observeTargets(this); |
| 18 } | 20 } |
| 19 | 21 |
| 20 WebInspector.TimelineController.prototype = { | 22 WebInspector.TimelineController.prototype = { |
| 21 /** | 23 /** |
| 22 * @param {boolean} captureCauses | 24 * @param {boolean} captureCauses |
| 23 * @param {boolean} enableJSSampling | 25 * @param {boolean} enableJSSampling |
| 24 * @param {boolean} captureMemory | 26 * @param {boolean} captureMemory |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 } | 65 } |
| 64 if (captureFilmStrip) | 66 if (captureFilmStrip) |
| 65 categoriesArray.push(disabledByDefault("devtools.screenshot")); | 67 categoriesArray.push(disabledByDefault("devtools.screenshot")); |
| 66 | 68 |
| 67 var categories = categoriesArray.join(","); | 69 var categories = categoriesArray.join(","); |
| 68 this._startRecordingWithCategories(categories, enableJSSampling); | 70 this._startRecordingWithCategories(categories, enableJSSampling); |
| 69 }, | 71 }, |
| 70 | 72 |
| 71 stopRecording: function() | 73 stopRecording: function() |
| 72 { | 74 { |
| 75 this._allProfilesStoppedPromise = this._stopProfilingOnAllTargets(); |
| 76 this._target.tracingManager.stop(); |
| 73 WebInspector.targetManager.resumeAllTargets(); | 77 WebInspector.targetManager.resumeAllTargets(); |
| 74 this._allProfilesStoppedPromise = this._stopProfilingOnAllTargets(); | |
| 75 if (this._targets[0]) | |
| 76 this._targets[0].tracingManager.stop(); | |
| 77 this._delegate.loadingStarted(); | 78 this._delegate.loadingStarted(); |
| 78 }, | 79 }, |
| 79 | 80 |
| 80 /** | 81 /** |
| 81 * @override | 82 * @override |
| 82 * @param {!WebInspector.Target} target | 83 * @param {!WebInspector.Target} target |
| 83 */ | 84 */ |
| 84 targetAdded: function(target) | 85 targetAdded: function(target) |
| 85 { | 86 { |
| 86 this._targets.push(target); | 87 this._targets.push(target); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 107 { | 108 { |
| 108 return target.profilerAgent().start(); | 109 return target.profilerAgent().start(); |
| 109 }, | 110 }, |
| 110 | 111 |
| 111 /** | 112 /** |
| 112 * @return {!Promise} | 113 * @return {!Promise} |
| 113 */ | 114 */ |
| 114 _startProfilingOnAllTargets: function() | 115 _startProfilingOnAllTargets: function() |
| 115 { | 116 { |
| 116 var intervalUs = WebInspector.moduleSetting("highResolutionCpuProfiling"
).get() ? 100 : 1000; | 117 var intervalUs = WebInspector.moduleSetting("highResolutionCpuProfiling"
).get() ? 100 : 1000; |
| 117 this._targets[0].profilerAgent().setSamplingInterval(intervalUs); | 118 this._target.profilerAgent().setSamplingInterval(intervalUs); |
| 118 this._profiling = true; | 119 this._profiling = true; |
| 119 return Promise.all(this._targets.map(this._startProfilingOnTarget)); | 120 return Promise.all(this._targets.map(this._startProfilingOnTarget)); |
| 120 }, | 121 }, |
| 121 | 122 |
| 122 /** | 123 /** |
| 123 * @param {!WebInspector.Target} target | 124 * @param {!WebInspector.Target} target |
| 124 * @return {!Promise} | 125 * @return {!Promise} |
| 125 */ | 126 */ |
| 126 _stopProfilingOnTarget: function(target) | 127 _stopProfilingOnTarget: function(target) |
| 127 { | 128 { |
| 128 /** | 129 return target.profilerAgent().stop(this._addCpuProfile.bind(this, target
.id())); |
| 129 * @param {?Protocol.Error} error | |
| 130 * @param {?ProfilerAgent.CPUProfile} profile | |
| 131 * @return {?ProfilerAgent.CPUProfile} | |
| 132 */ | |
| 133 function extractProfile(error, profile) | |
| 134 { | |
| 135 return !error && profile ? profile : null; | |
| 136 } | |
| 137 return target.profilerAgent().stop(extractProfile).then(this._addCpuProf
ile.bind(this, target.id())); | |
| 138 }, | 130 }, |
| 139 | 131 |
| 140 /** | 132 /** |
| 133 * @param {number} targetId |
| 134 * @param {?Protocol.Error} error |
| 135 * @param {?ProfilerAgent.CPUProfile} cpuProfile |
| 136 */ |
| 137 _addCpuProfile: function(targetId, error, cpuProfile) |
| 138 { |
| 139 if (!cpuProfile) { |
| 140 WebInspector.console.warn(WebInspector.UIString("CPU profile for a t
arget is not available. %s", error || "")); |
| 141 return; |
| 142 } |
| 143 if (!this._cpuProfiles) |
| 144 this._cpuProfiles = new Map(); |
| 145 this._cpuProfiles.set(targetId, cpuProfile); |
| 146 }, |
| 147 |
| 148 /** |
| 141 * @return {!Promise} | 149 * @return {!Promise} |
| 142 */ | 150 */ |
| 143 _stopProfilingOnAllTargets: function() | 151 _stopProfilingOnAllTargets: function() |
| 144 { | 152 { |
| 145 var targets = this._profiling ? this._targets : []; | 153 var targets = this._profiling ? this._targets : []; |
| 146 this._profiling = false; | 154 this._profiling = false; |
| 147 return Promise.all(targets.map(this._stopProfilingOnTarget, this)); | 155 return Promise.all(targets.map(this._stopProfilingOnTarget, this)); |
| 148 }, | 156 }, |
| 149 | 157 |
| 150 /** | 158 /** |
| 151 * @param {string} categories | 159 * @param {string} categories |
| 152 * @param {boolean=} enableJSSampling | 160 * @param {boolean=} enableJSSampling |
| 153 * @param {function(?string)=} callback | 161 * @param {function(?string)=} callback |
| 154 */ | 162 */ |
| 155 _startRecordingWithCategories: function(categories, enableJSSampling, callba
ck) | 163 _startRecordingWithCategories: function(categories, enableJSSampling, callba
ck) |
| 156 { | 164 { |
| 157 if (!this._targets.length) | |
| 158 return; | |
| 159 WebInspector.targetManager.suspendAllTargets(); | 165 WebInspector.targetManager.suspendAllTargets(); |
| 160 var profilingStartedPromise = enableJSSampling && !Runtime.experiments.i
sEnabled("timelineTracingJSProfile") ? | 166 var profilingStartedPromise = enableJSSampling && !Runtime.experiments.i
sEnabled("timelineTracingJSProfile") ? |
| 161 this._startProfilingOnAllTargets() : Promise.resolve(); | 167 this._startProfilingOnAllTargets() : Promise.resolve(); |
| 162 var samplingFrequencyHz = WebInspector.moduleSetting("highResolutionCpuP
rofiling").get() ? 10000 : 1000; | 168 var samplingFrequencyHz = WebInspector.moduleSetting("highResolutionCpuP
rofiling").get() ? 10000 : 1000; |
| 163 var options = "sampling-frequency=" + samplingFrequencyHz; | 169 var options = "sampling-frequency=" + samplingFrequencyHz; |
| 164 var mainTarget = this._targets[0]; | 170 var target = this._target; |
| 165 var tracingManager = mainTarget.tracingManager; | 171 var tracingManager = target.tracingManager; |
| 166 mainTarget.resourceTreeModel.suspendReload(); | 172 target.resourceTreeModel.suspendReload(); |
| 167 profilingStartedPromise.then(tracingManager.start.bind(tracingManager, t
his, categories, options, onTraceStarted)); | 173 profilingStartedPromise.then(tracingManager.start.bind(tracingManager, t
his, categories, options, onTraceStarted)); |
| 168 /** | 174 /** |
| 169 * @param {?string} error | 175 * @param {?string} error |
| 170 */ | 176 */ |
| 171 function onTraceStarted(error) | 177 function onTraceStarted(error) |
| 172 { | 178 { |
| 173 mainTarget.resourceTreeModel.resumeReload(); | 179 target.resourceTreeModel.resumeReload(); |
| 174 if (callback) | 180 if (callback) |
| 175 callback(error); | 181 callback(error); |
| 176 } | 182 } |
| 177 }, | 183 }, |
| 178 | 184 |
| 179 /** | 185 /** |
| 180 * @override | 186 * @override |
| 181 */ | 187 */ |
| 182 tracingStarted: function() | 188 tracingStarted: function() |
| 183 { | 189 { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 if (!this._cpuProfiles) | 246 if (!this._cpuProfiles) |
| 241 return; | 247 return; |
| 242 | 248 |
| 243 var metadataEventTypes = WebInspector.TimelineModel.DevToolsMetadataEven
t; | 249 var metadataEventTypes = WebInspector.TimelineModel.DevToolsMetadataEven
t; |
| 244 var metadataEvents = this._tracingModel.devToolsMetadataEvents(); | 250 var metadataEvents = this._tracingModel.devToolsMetadataEvents(); |
| 245 var mainMetaEvent = metadataEvents.filter(event => event.name === metada
taEventTypes.TracingStartedInPage).peekLast(); | 251 var mainMetaEvent = metadataEvents.filter(event => event.name === metada
taEventTypes.TracingStartedInPage).peekLast(); |
| 246 if (!mainMetaEvent) | 252 if (!mainMetaEvent) |
| 247 return; | 253 return; |
| 248 | 254 |
| 249 var pid = mainMetaEvent.thread.process().id(); | 255 var pid = mainMetaEvent.thread.process().id(); |
| 250 var mainTarget = this._targets[0]; | 256 var mainCpuProfile = this._cpuProfiles.get(this._target.id()); |
| 251 var mainCpuProfile = this._cpuProfiles.get(mainTarget.id()); | |
| 252 this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfi
le); | 257 this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfi
le); |
| 253 | 258 |
| 254 var workerMetaEvents = metadataEvents.filter(event => event.name === met
adataEventTypes.TracingSessionIdForWorker); | 259 var workerMetaEvents = metadataEvents.filter(event => event.name === met
adataEventTypes.TracingSessionIdForWorker); |
| 255 for (var metaEvent of workerMetaEvents) { | 260 for (var metaEvent of workerMetaEvents) { |
| 256 var workerId = metaEvent.args["data"]["workerId"]; | 261 var workerId = metaEvent.args["data"]["workerId"]; |
| 257 var target = mainTarget.workerManager ? mainTarget.workerManager.tar
getByWorkerId(workerId) : null; | 262 var workerTarget = this._target.workerManager ? this._target.workerM
anager.targetByWorkerId(workerId) : null; |
| 258 if (!target) | 263 if (!workerTarget) |
| 259 continue; | 264 continue; |
| 260 var cpuProfile = this._cpuProfiles.get(target.id()); | 265 var cpuProfile = this._cpuProfiles.get(workerTarget.id()); |
| 261 this._injectCpuProfileEvent(pid, metaEvent.args["data"]["workerThrea
dId"], cpuProfile); | 266 this._injectCpuProfileEvent(pid, metaEvent.args["data"]["workerThrea
dId"], cpuProfile); |
| 262 } | 267 } |
| 263 this._cpuProfiles = null; | 268 this._cpuProfiles = null; |
| 264 }, | 269 }, |
| 265 | 270 |
| 266 /** | 271 /** |
| 267 * @param {number} usage | 272 * @param {number} usage |
| 268 * @override | 273 * @override |
| 269 */ | 274 */ |
| 270 tracingBufferUsage: function(usage) | 275 tracingBufferUsage: function(usage) |
| 271 { | 276 { |
| 272 this._delegate.recordingProgress(usage); | 277 this._delegate.recordingProgress(usage); |
| 273 }, | 278 }, |
| 274 | 279 |
| 275 /** | 280 /** |
| 276 * @param {number} progress | 281 * @param {number} progress |
| 277 * @override | 282 * @override |
| 278 */ | 283 */ |
| 279 eventsRetrievalProgress: function(progress) | 284 eventsRetrievalProgress: function(progress) |
| 280 { | 285 { |
| 281 this._delegate.loadingProgress(progress); | 286 this._delegate.loadingProgress(progress); |
| 282 }, | |
| 283 | |
| 284 /** | |
| 285 * @param {number} targetId | |
| 286 * @param {?ProfilerAgent.CPUProfile} cpuProfile | |
| 287 */ | |
| 288 _addCpuProfile: function(targetId, cpuProfile) | |
| 289 { | |
| 290 if (!cpuProfile) | |
| 291 return; | |
| 292 if (!this._cpuProfiles) | |
| 293 this._cpuProfiles = new Map(); | |
| 294 this._cpuProfiles.set(targetId, cpuProfile); | |
| 295 } | 287 } |
| 296 } | 288 } |
| OLD | NEW |