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 |