blob: 5f18a0ead2d4b58a1467784de20229b217e89f90 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
Tim van der Lippecec9b762020-02-13 15:31:2232import * as Bindings from '../bindings/bindings.js';
33import * as Common from '../common/common.js';
34import * as Extensions from '../extensions/extensions.js';
35import * as Host from '../host/host.js';
36import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
37import * as PerfUI from '../perf_ui/perf_ui.js';
38import * as ProtocolModule from '../protocol/protocol.js';
39import * as SDK from '../sdk/sdk.js';
40import * as TimelineModel from '../timeline_model/timeline_model.js';
41import * as UI from '../ui/ui.js';
42
Tim van der Lippefced1b92020-02-17 12:33:5043import {Events, PerformanceModel, Window} from './PerformanceModel.js'; // eslint-disable-line no-unused-vars
44import {Client, TimelineController} from './TimelineController.js'; // eslint-disable-line no-unused-vars
Paul Lewis897ad8b2020-01-15 16:49:1745import {TimelineEventOverview, TimelineEventOverviewCoverage, TimelineEventOverviewCPUActivity, TimelineEventOverviewFrames, TimelineEventOverviewInput, TimelineEventOverviewMemory, TimelineEventOverviewNetwork, TimelineEventOverviewResponsiveness, TimelineFilmStripOverview,} from './TimelineEventOverview.js'; // eslint-disable-line no-unused-vars
46import {TimelineFlameChartView} from './TimelineFlameChartView.js';
47import {TimelineHistoryManager} from './TimelineHistoryManager.js';
48import {TimelineLoader} from './TimelineLoader.js';
49import {TimelineUIUtils} from './TimelineUIUtils.js';
50import {UIDevtoolsController} from './UIDevtoolsController.js';
51import {UIDevtoolsUtils} from './UIDevtoolsUtils.js';
52
Blink Reformat4c46d092018-04-07 15:32:3753/**
Paul Lewis897ad8b2020-01-15 16:49:1754 * @implements {Client}
Tim van der Lippe0176f6c2020-01-08 11:07:0155 * @implements {TimelineModeViewDelegate}
Blink Reformat4c46d092018-04-07 15:32:3756 * @unrestricted
57 */
Tim van der Lippecec9b762020-02-13 15:31:2258export class TimelinePanel extends UI.Panel.Panel {
Blink Reformat4c46d092018-04-07 15:32:3759 constructor() {
60 super('timeline');
61 this.registerRequiredCSS('timeline/timelinePanel.css');
62 this.element.addEventListener('contextmenu', this._contextMenu.bind(this), false);
Tim van der Lippecec9b762020-02-13 15:31:2263 this._dropTarget = new UI.DropTarget.DropTarget(
Blink Reformat4c46d092018-04-07 15:32:3764 this.element, [UI.DropTarget.Type.File, UI.DropTarget.Type.URI],
Tim van der Lippecec9b762020-02-13 15:31:2265 Common.UIString.UIString('Drop timeline file or URL here'), this._handleDrop.bind(this));
Blink Reformat4c46d092018-04-07 15:32:3766
Tim van der Lippecec9b762020-02-13 15:31:2267 /** @type {!Array<!UI.Toolbar.ToolbarItem>} */
Blink Reformat4c46d092018-04-07 15:32:3768 this._recordingOptionUIControls = [];
Tim van der Lippe0176f6c2020-01-08 11:07:0169 this._state = State.Idle;
Blink Reformat4c46d092018-04-07 15:32:3770 this._recordingPageReload = false;
71 this._millisecondsToRecordAfterLoadEvent = 3000;
72 this._toggleRecordAction =
Tim van der Lippecec9b762020-02-13 15:31:2273 /** @type {!UI.Action.Action }*/ (self.UI.actionRegistry.action('timeline.toggle-recording'));
Blink Reformat4c46d092018-04-07 15:32:3774 this._recordReloadAction =
Tim van der Lippecec9b762020-02-13 15:31:2275 /** @type {!UI.Action.Action }*/ (self.UI.actionRegistry.action('timeline.record-reload'));
Blink Reformat4c46d092018-04-07 15:32:3776
Paul Lewis897ad8b2020-01-15 16:49:1777 this._historyManager = new TimelineHistoryManager();
Blink Reformat4c46d092018-04-07 15:32:3778
Paul Lewis897ad8b2020-01-15 16:49:1779 /** @type {?PerformanceModel} */
Blink Reformat4c46d092018-04-07 15:32:3780 this._performanceModel = null;
81
Paul Lewis6bcdb182020-01-23 11:08:0582 this._viewModeSetting = self.Common.settings.createSetting('timelineViewMode', ViewMode.FlameChart);
Blink Reformat4c46d092018-04-07 15:32:3783
Paul Lewis6bcdb182020-01-23 11:08:0584 this._disableCaptureJSProfileSetting = self.Common.settings.createSetting('timelineDisableJSSampling', false);
Tim van der Lippecec9b762020-02-13 15:31:2285 this._disableCaptureJSProfileSetting.setTitle(Common.UIString.UIString('Disable JavaScript samples'));
Paul Lewis6bcdb182020-01-23 11:08:0586 this._captureLayersAndPicturesSetting =
87 self.Common.settings.createSetting('timelineCaptureLayersAndPictures', false);
Tim van der Lippecec9b762020-02-13 15:31:2288 this._captureLayersAndPicturesSetting.setTitle(
89 Common.UIString.UIString('Enable advanced paint instrumentation (slow)'));
Blink Reformat4c46d092018-04-07 15:32:3790
Paul Lewis6bcdb182020-01-23 11:08:0591 this._showScreenshotsSetting = self.Common.settings.createSetting('timelineShowScreenshots', true);
Tim van der Lippecec9b762020-02-13 15:31:2292 this._showScreenshotsSetting.setTitle(Common.UIString.UIString('Screenshots'));
Blink Reformat4c46d092018-04-07 15:32:3793 this._showScreenshotsSetting.addChangeListener(this._updateOverviewControls, this);
94
Paul Lewis6bcdb182020-01-23 11:08:0595 this._startCoverage = self.Common.settings.createSetting('timelineStartCoverage', false);
Jan Schefflerfc2f3832019-09-24 14:03:3296 this._startCoverage.setTitle(ls`Coverage`);
97
Tim van der Lippe99e59b82019-09-30 20:00:5998 if (!Root.Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')) {
Jan Schefflerfc2f3832019-09-24 14:03:3299 this._startCoverage.set(false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34100 }
Jan Schefflerfc2f3832019-09-24 14:03:32101
102
Paul Lewis6bcdb182020-01-23 11:08:05103 this._showMemorySetting = self.Common.settings.createSetting('timelineShowMemory', false);
Tim van der Lippecec9b762020-02-13 15:31:22104 this._showMemorySetting.setTitle(Common.UIString.UIString('Memory'));
Blink Reformat4c46d092018-04-07 15:32:37105 this._showMemorySetting.addChangeListener(this._onModeChanged, this);
106
Erik Luo6355f4d2018-06-01 03:32:24107 const timelineToolbarContainer = this.element.createChild('div', 'timeline-toolbar-container');
Tim van der Lippecec9b762020-02-13 15:31:22108 this._panelToolbar = new UI.Toolbar.Toolbar('timeline-main-toolbar', timelineToolbarContainer);
109 this._panelRightToolbar = new UI.Toolbar.Toolbar('', timelineToolbarContainer);
Blink Reformat4c46d092018-04-07 15:32:37110 this._createSettingsPane();
111 this._updateShowSettingsToolbarButton();
112
Tim van der Lippecec9b762020-02-13 15:31:22113 this._timelinePane = new UI.Widget.VBox();
Blink Reformat4c46d092018-04-07 15:32:37114 this._timelinePane.show(this.element);
115 const topPaneElement = this._timelinePane.element.createChild('div', 'hbox');
116 topPaneElement.id = 'timeline-overview-panel';
117
118 // Create top overview component.
Tim van der Lippecec9b762020-02-13 15:31:22119 this._overviewPane = new PerfUI.TimelineOverviewPane.TimelineOverviewPane('timeline');
Blink Reformat4c46d092018-04-07 15:32:37120 this._overviewPane.addEventListener(
Alexei Filippov2578eb02018-04-11 08:15:05121 PerfUI.TimelineOverviewPane.Events.WindowChanged, this._onOverviewWindowChanged.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37122 this._overviewPane.show(topPaneElement);
Paul Lewis897ad8b2020-01-15 16:49:17123 /** @type {!Array<!TimelineEventOverview>} */
Blink Reformat4c46d092018-04-07 15:32:37124 this._overviewControls = [];
125
126 this._statusPaneContainer = this._timelinePane.element.createChild('div', 'status-pane-container fill');
127
128 this._createFileSelector();
129
Paul Lewis4ae5f4f2020-01-23 10:19:33130 self.SDK.targetManager.addModelListener(
Tim van der Lippecec9b762020-02-13 15:31:22131 SDK.ResourceTreeModel.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
Blink Reformat4c46d092018-04-07 15:32:37132
Paul Lewis897ad8b2020-01-15 16:49:17133 this._flameChart = new TimelineFlameChartView(this);
Tim van der Lippecec9b762020-02-13 15:31:22134 this._searchableView = new UI.SearchableView.SearchableView(this._flameChart);
Blink Reformat4c46d092018-04-07 15:32:37135 this._searchableView.setMinimumSize(0, 100);
136 this._searchableView.element.classList.add('searchable-view');
137 this._searchableView.show(this._timelinePane.element);
138 this._flameChart.show(this._searchableView.element);
139 this._flameChart.setSearchableView(this._searchableView);
Jack Lynchd9a5b6e2020-02-24 20:35:19140 this._searchableView.hideWidget();
Blink Reformat4c46d092018-04-07 15:32:37141
142 this._onModeChanged();
143 this._populateToolbar();
144 this._showLandingPage();
145 this._updateTimelineControls();
146
Paul Lewis396d0b92020-01-24 16:08:30147 self.Extensions.extensionServer.addEventListener(
Blink Reformat4c46d092018-04-07 15:32:37148 Extensions.ExtensionServer.Events.TraceProviderAdded, this._appendExtensionsToToolbar, this);
Tim van der Lippecec9b762020-02-13 15:31:22149 self.SDK.targetManager.addEventListener(SDK.SDKModel.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
Blink Reformat4c46d092018-04-07 15:32:37150 }
151
152 /**
Tim van der Lippe0176f6c2020-01-08 11:07:01153 * @return {!TimelinePanel}
Blink Reformat4c46d092018-04-07 15:32:37154 */
155 static instance() {
Tim van der Lippe0176f6c2020-01-08 11:07:01156 return /** @type {!TimelinePanel} */ (self.runtime.sharedInstance(TimelinePanel));
Blink Reformat4c46d092018-04-07 15:32:37157 }
158
159 /**
160 * @override
Tim van der Lippecec9b762020-02-13 15:31:22161 * @return {?UI.SearchableView.SearchableView}
Blink Reformat4c46d092018-04-07 15:32:37162 */
163 searchableView() {
164 return this._searchableView;
165 }
166
167 /**
168 * @override
169 */
170 wasShown() {
Paul Lewisd9907342020-01-24 13:49:47171 self.UI.context.setFlavor(TimelinePanel, this);
Alex Chiem1c992512020-01-15 19:38:23172 // Record the performance tool load time.
173 Host.userMetrics.panelLoaded('timeline', 'DevTools.Launch.Timeline');
Blink Reformat4c46d092018-04-07 15:32:37174 }
175
176 /**
177 * @override
178 */
179 willHide() {
Paul Lewisd9907342020-01-24 13:49:47180 self.UI.context.setFlavor(TimelinePanel, null);
Blink Reformat4c46d092018-04-07 15:32:37181 this._historyManager.cancelIfShowing();
182 }
183
184 /**
185 * @param {!Array.<!SDK.TracingManager.EventPayload>} events
186 */
187 loadFromEvents(events) {
Tim van der Lippe0176f6c2020-01-08 11:07:01188 if (this._state !== State.Idle) {
Blink Reformat4c46d092018-04-07 15:32:37189 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34190 }
Blink Reformat4c46d092018-04-07 15:32:37191 this._prepareToLoadTimeline();
Paul Lewis897ad8b2020-01-15 16:49:17192 this._loader = TimelineLoader.loadFromEvents(events, this);
Blink Reformat4c46d092018-04-07 15:32:37193 }
194
195 /**
Tim van der Lippec02a97c2020-02-14 14:39:27196 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37197 */
Alexei Filippov2578eb02018-04-11 08:15:05198 _onOverviewWindowChanged(event) {
199 const left = event.data.startTime;
200 const right = event.data.endTime;
201 this._performanceModel.setWindow({left, right}, /* animate */ true);
Blink Reformat4c46d092018-04-07 15:32:37202 }
203
204 /**
Tim van der Lippec02a97c2020-02-14 14:39:27205 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37206 */
Alexei Filippov2578eb02018-04-11 08:15:05207 _onModelWindowChanged(event) {
Tim van der Lippefced1b92020-02-17 12:33:50208 const window = /** @type {!Window} */ (event.data.window);
Alexei Filippov2578eb02018-04-11 08:15:05209 this._overviewPane.setWindowTimes(window.left, window.right);
Blink Reformat4c46d092018-04-07 15:32:37210 }
211
212 /**
Tim van der Lippe0176f6c2020-01-08 11:07:01213 * @param {!State} state
Blink Reformat4c46d092018-04-07 15:32:37214 */
215 _setState(state) {
216 this._state = state;
217 this._updateTimelineControls();
218 }
219
220 /**
Tim van der Lippecec9b762020-02-13 15:31:22221 * @param {!Common.Settings.Setting} setting
Blink Reformat4c46d092018-04-07 15:32:37222 * @param {string} tooltip
Tim van der Lippecec9b762020-02-13 15:31:22223 * @return {!UI.Toolbar.ToolbarItem}
Blink Reformat4c46d092018-04-07 15:32:37224 */
225 _createSettingCheckbox(setting, tooltip) {
Tim van der Lippecec9b762020-02-13 15:31:22226 const checkboxItem = new UI.Toolbar.ToolbarSettingCheckbox(setting, tooltip);
Blink Reformat4c46d092018-04-07 15:32:37227 this._recordingOptionUIControls.push(checkboxItem);
228 return checkboxItem;
229 }
230
231 _populateToolbar() {
232 // Record
Tim van der Lippecec9b762020-02-13 15:31:22233 this._panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButton(this._toggleRecordAction));
234 this._panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButton(this._recordReloadAction));
235 this._clearButton = new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Clear'), 'largeicon-clear');
236 this._clearButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => this._onClearButton());
Blink Reformat4c46d092018-04-07 15:32:37237 this._panelToolbar.appendToolbarItem(this._clearButton);
238
239 // Load / Save
Mathias Bynens23ee1aa2020-03-02 12:06:38240 this._loadButton = new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Load profile…'), 'largeicon-load');
Tim van der Lippecec9b762020-02-13 15:31:22241 this._loadButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => this._selectFileToLoad());
Ella Ged09f6c82020-02-18 16:34:10242 this._saveButton =
Mathias Bynens23ee1aa2020-03-02 12:06:38243 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Save profile…'), 'largeicon-download');
Tim van der Lippecec9b762020-02-13 15:31:22244 this._saveButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => this._saveToFile());
Blink Reformat4c46d092018-04-07 15:32:37245 this._panelToolbar.appendSeparator();
246 this._panelToolbar.appendToolbarItem(this._loadButton);
247 this._panelToolbar.appendToolbarItem(this._saveButton);
248
249 // History
250 this._panelToolbar.appendSeparator();
251 this._panelToolbar.appendToolbarItem(this._historyManager.button());
252 this._panelToolbar.appendSeparator();
253
254 // View
255 this._panelToolbar.appendSeparator();
256 this._showScreenshotsToolbarCheckbox =
Tim van der Lippecec9b762020-02-13 15:31:22257 this._createSettingCheckbox(this._showScreenshotsSetting, Common.UIString.UIString('Capture screenshots'));
Blink Reformat4c46d092018-04-07 15:32:37258 this._panelToolbar.appendToolbarItem(this._showScreenshotsToolbarCheckbox);
259
260 this._showMemoryToolbarCheckbox =
Tim van der Lippecec9b762020-02-13 15:31:22261 this._createSettingCheckbox(this._showMemorySetting, Common.UIString.UIString('Show memory timeline'));
Blink Reformat4c46d092018-04-07 15:32:37262 this._panelToolbar.appendToolbarItem(this._showMemoryToolbarCheckbox);
263
Tim van der Lippe99e59b82019-09-30 20:00:59264 if (Root.Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')) {
Jan Schefflerfc2f3832019-09-24 14:03:32265 this._startCoverageCheckbox =
266 this._createSettingCheckbox(this._startCoverage, ls`Record coverage with performance trace`);
267 this._panelToolbar.appendToolbarItem(this._startCoverageCheckbox);
268 }
269
Blink Reformat4c46d092018-04-07 15:32:37270 // GC
Tim van der Lippecec9b762020-02-13 15:31:22271 this._panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButtonForId('components.collect-garbage'));
Blink Reformat4c46d092018-04-07 15:32:37272
273 // Settings
Erik Luo6355f4d2018-06-01 03:32:24274 this._panelRightToolbar.appendSeparator();
275 this._panelRightToolbar.appendToolbarItem(this._showSettingsPaneButton);
Blink Reformat4c46d092018-04-07 15:32:37276 }
277
278 _createSettingsPane() {
Paul Lewis6bcdb182020-01-23 11:08:05279 this._showSettingsPaneSetting = self.Common.settings.createSetting('timelineShowSettingsToolbar', false);
Tim van der Lippecec9b762020-02-13 15:31:22280 this._showSettingsPaneButton = new UI.Toolbar.ToolbarSettingToggle(
281 this._showSettingsPaneSetting, 'largeicon-settings-gear', Common.UIString.UIString('Capture settings'));
Paul Lewis5a922e72020-01-24 11:58:08282 self.SDK.multitargetNetworkManager.addEventListener(
Tim van der Lippecec9b762020-02-13 15:31:22283 SDK.NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged, this._updateShowSettingsToolbarButton,
284 this);
285 MobileThrottling.ThrottlingManager.throttlingManager().addEventListener(
Blink Reformat4c46d092018-04-07 15:32:37286 MobileThrottling.ThrottlingManager.Events.RateChanged, this._updateShowSettingsToolbarButton, this);
287 this._disableCaptureJSProfileSetting.addChangeListener(this._updateShowSettingsToolbarButton, this);
288 this._captureLayersAndPicturesSetting.addChangeListener(this._updateShowSettingsToolbarButton, this);
289
Tim van der Lippecec9b762020-02-13 15:31:22290 this._settingsPane = new UI.Widget.HBox();
Blink Reformat4c46d092018-04-07 15:32:37291 this._settingsPane.element.classList.add('timeline-settings-pane');
292 this._settingsPane.show(this.element);
293
Tim van der Lippecec9b762020-02-13 15:31:22294 const captureToolbar = new UI.Toolbar.Toolbar('', this._settingsPane.element);
Blink Reformat4c46d092018-04-07 15:32:37295 captureToolbar.element.classList.add('flex-auto');
296 captureToolbar.makeVertical();
297 captureToolbar.appendToolbarItem(this._createSettingCheckbox(
298 this._disableCaptureJSProfileSetting,
Tim van der Lippecec9b762020-02-13 15:31:22299 Common.UIString.UIString(
300 'Disables JavaScript sampling, reduces overhead when running against mobile devices')));
Blink Reformat4c46d092018-04-07 15:32:37301 captureToolbar.appendToolbarItem(this._createSettingCheckbox(
302 this._captureLayersAndPicturesSetting,
Tim van der Lippecec9b762020-02-13 15:31:22303 Common.UIString.UIString(
304 'Captures advanced paint instrumentation, introduces significant performance overhead')));
Blink Reformat4c46d092018-04-07 15:32:37305
Tim van der Lippecec9b762020-02-13 15:31:22306 const throttlingPane = new UI.Widget.VBox();
Blink Reformat4c46d092018-04-07 15:32:37307 throttlingPane.element.classList.add('flex-auto');
308 throttlingPane.show(this._settingsPane.element);
309
Tim van der Lippecec9b762020-02-13 15:31:22310 const networkThrottlingToolbar = new UI.Toolbar.Toolbar('', throttlingPane.element);
311 networkThrottlingToolbar.appendText(Common.UIString.UIString('Network:'));
Blink Reformat4c46d092018-04-07 15:32:37312 this._networkThrottlingSelect = this._createNetworkConditionsSelect();
313 networkThrottlingToolbar.appendToolbarItem(this._networkThrottlingSelect);
314
Tim van der Lippecec9b762020-02-13 15:31:22315 const cpuThrottlingToolbar = new UI.Toolbar.Toolbar('', throttlingPane.element);
316 cpuThrottlingToolbar.appendText(Common.UIString.UIString('CPU:'));
317 this._cpuThrottlingSelect = MobileThrottling.ThrottlingManager.throttlingManager().createCPUThrottlingSelector();
Blink Reformat4c46d092018-04-07 15:32:37318 cpuThrottlingToolbar.appendToolbarItem(this._cpuThrottlingSelect);
319
320 this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));
321 this._updateSettingsPaneVisibility();
322 }
323
324 /**
Tim van der Lippec02a97c2020-02-14 14:39:27325 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37326 */
327 _appendExtensionsToToolbar(event) {
Tim van der Lippecec9b762020-02-13 15:31:22328 const provider = /** @type {!Extensions.ExtensionTraceProvider.ExtensionTraceProvider} */ (event.data);
Tim van der Lippe0176f6c2020-01-08 11:07:01329 const setting = TimelinePanel._settingForTraceProvider(provider);
Blink Reformat4c46d092018-04-07 15:32:37330 const checkbox = this._createSettingCheckbox(setting, provider.longDisplayName());
331 this._panelToolbar.appendToolbarItem(checkbox);
332 }
333
334 /**
Tim van der Lippecec9b762020-02-13 15:31:22335 * @param {!Extensions.ExtensionTraceProvider.ExtensionTraceProvider} traceProvider
336 * @return {!Common.Settings.Setting<boolean>}
Blink Reformat4c46d092018-04-07 15:32:37337 */
338 static _settingForTraceProvider(traceProvider) {
Paul Lewis897ad8b2020-01-15 16:49:17339 let setting = traceProvider[traceProviderSettingSymbol];
Blink Reformat4c46d092018-04-07 15:32:37340 if (!setting) {
341 const providerId = traceProvider.persistentIdentifier();
Paul Lewis6bcdb182020-01-23 11:08:05342 setting = self.Common.settings.createSetting(providerId, false);
Blink Reformat4c46d092018-04-07 15:32:37343 setting.setTitle(traceProvider.shortDisplayName());
Paul Lewis897ad8b2020-01-15 16:49:17344 traceProvider[traceProviderSettingSymbol] = setting;
Blink Reformat4c46d092018-04-07 15:32:37345 }
346 return setting;
347 }
348
349 /**
Tim van der Lippecec9b762020-02-13 15:31:22350 * @return {!UI.Toolbar.ToolbarComboBox}
Blink Reformat4c46d092018-04-07 15:32:37351 */
352 _createNetworkConditionsSelect() {
Tim van der Lippecec9b762020-02-13 15:31:22353 const toolbarItem = new UI.Toolbar.ToolbarComboBox(null, ls`Network conditions`);
Blink Reformat4c46d092018-04-07 15:32:37354 toolbarItem.setMaxWidth(140);
Tim van der Lippecec9b762020-02-13 15:31:22355 MobileThrottling.ThrottlingManager.throttlingManager().decorateSelectWithNetworkThrottling(
356 toolbarItem.selectElement());
Blink Reformat4c46d092018-04-07 15:32:37357 return toolbarItem;
358 }
359
360 _prepareToLoadTimeline() {
Tim van der Lippe0176f6c2020-01-08 11:07:01361 console.assert(this._state === State.Idle);
362 this._setState(State.Loading);
Blink Reformat4c46d092018-04-07 15:32:37363 if (this._performanceModel) {
364 this._performanceModel.dispose();
365 this._performanceModel = null;
366 }
367 }
368
369 _createFileSelector() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34370 if (this._fileSelectorElement) {
Blink Reformat4c46d092018-04-07 15:32:37371 this._fileSelectorElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:34372 }
Tim van der Lippecec9b762020-02-13 15:31:22373 this._fileSelectorElement = UI.UIUtils.createFileSelectorElement(this._loadFromFile.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37374 this._timelinePane.element.appendChild(this._fileSelectorElement);
375 }
376
377 /**
378 * @param {!Event} event
379 */
380 _contextMenu(event) {
Tim van der Lippecec9b762020-02-13 15:31:22381 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37382 contextMenu.appendItemsAtLocation('timelineMenu');
383 contextMenu.show();
384 }
385
Tim van der Lippeffa78622019-09-16 12:07:12386 /**
387 * @suppress {deprecated}
388 */
Blink Reformat4c46d092018-04-07 15:32:37389 async _saveToFile() {
Tim van der Lippe0176f6c2020-01-08 11:07:01390 if (this._state !== State.Idle) {
Blink Reformat4c46d092018-04-07 15:32:37391 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34392 }
Blink Reformat4c46d092018-04-07 15:32:37393 const performanceModel = this._performanceModel;
Tim van der Lippe1d6e57a2019-09-30 11:55:34394 if (!performanceModel) {
Blink Reformat4c46d092018-04-07 15:32:37395 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34396 }
Blink Reformat4c46d092018-04-07 15:32:37397
398 const now = new Date();
399 const fileName = 'Profile-' + now.toISO8601Compact() + '.json';
Tim van der Lippecec9b762020-02-13 15:31:22400 const stream = new Bindings.FileUtils.FileOutputStream();
Blink Reformat4c46d092018-04-07 15:32:37401
402 const accepted = await stream.open(fileName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34403 if (!accepted) {
Blink Reformat4c46d092018-04-07 15:32:37404 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34405 }
Blink Reformat4c46d092018-04-07 15:32:37406
407 const error = await performanceModel.save(stream);
Tim van der Lippe1d6e57a2019-09-30 11:55:34408 if (!error) {
Blink Reformat4c46d092018-04-07 15:32:37409 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34410 }
Paul Lewis04ccecc2020-01-22 17:15:14411 self.Common.console.error(
Tim van der Lippecec9b762020-02-13 15:31:22412 Common.UIString.UIString('Failed to save timeline: %s (%s, %s)', error.message, error.name, error.code));
Blink Reformat4c46d092018-04-07 15:32:37413 }
414
415 async _showHistory() {
416 const model = await this._historyManager.showHistoryDropDown();
Tim van der Lippe1d6e57a2019-09-30 11:55:34417 if (model && model !== this._performanceModel) {
Blink Reformat4c46d092018-04-07 15:32:37418 this._setModel(model);
Tim van der Lippe1d6e57a2019-09-30 11:55:34419 }
Blink Reformat4c46d092018-04-07 15:32:37420 }
421
422 /**
423 * @param {number} direction
424 * @return {boolean}
425 */
426 _navigateHistory(direction) {
427 const model = this._historyManager.navigate(direction);
Tim van der Lippe1d6e57a2019-09-30 11:55:34428 if (model && model !== this._performanceModel) {
Blink Reformat4c46d092018-04-07 15:32:37429 this._setModel(model);
Tim van der Lippe1d6e57a2019-09-30 11:55:34430 }
Blink Reformat4c46d092018-04-07 15:32:37431 return true;
432 }
433
434 _selectFileToLoad() {
435 this._fileSelectorElement.click();
436 }
437
438 /**
439 * @param {!File} file
440 */
441 _loadFromFile(file) {
Tim van der Lippe0176f6c2020-01-08 11:07:01442 if (this._state !== State.Idle) {
Blink Reformat4c46d092018-04-07 15:32:37443 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34444 }
Blink Reformat4c46d092018-04-07 15:32:37445 this._prepareToLoadTimeline();
Paul Lewis897ad8b2020-01-15 16:49:17446 this._loader = TimelineLoader.loadFromFile(file, this);
Blink Reformat4c46d092018-04-07 15:32:37447 this._createFileSelector();
448 }
449
450 /**
451 * @param {string} url
452 */
453 _loadFromURL(url) {
Tim van der Lippe0176f6c2020-01-08 11:07:01454 if (this._state !== State.Idle) {
Blink Reformat4c46d092018-04-07 15:32:37455 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34456 }
Blink Reformat4c46d092018-04-07 15:32:37457 this._prepareToLoadTimeline();
Paul Lewis897ad8b2020-01-15 16:49:17458 this._loader = TimelineLoader.loadFromURL(url, this);
Blink Reformat4c46d092018-04-07 15:32:37459 }
460
461 _updateOverviewControls() {
462 this._overviewControls = [];
Paul Lewis897ad8b2020-01-15 16:49:17463 this._overviewControls.push(new TimelineEventOverviewResponsiveness());
Tim van der Lippe99e59b82019-09-30 20:00:59464 if (Root.Runtime.experiments.isEnabled('inputEventsOnTimelineOverview')) {
Paul Lewis897ad8b2020-01-15 16:49:17465 this._overviewControls.push(new TimelineEventOverviewInput());
Tim van der Lippe1d6e57a2019-09-30 11:55:34466 }
Paul Lewis897ad8b2020-01-15 16:49:17467 this._overviewControls.push(new TimelineEventOverviewFrames());
468 this._overviewControls.push(new TimelineEventOverviewCPUActivity());
469 this._overviewControls.push(new TimelineEventOverviewNetwork());
Alexei Filippoveddfd842018-04-28 01:01:13470 if (this._showScreenshotsSetting.get() && this._performanceModel &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34471 this._performanceModel.filmStripModel().frames().length) {
Paul Lewis897ad8b2020-01-15 16:49:17472 this._overviewControls.push(new TimelineFilmStripOverview());
Tim van der Lippe1d6e57a2019-09-30 11:55:34473 }
474 if (this._showMemorySetting.get()) {
Paul Lewis897ad8b2020-01-15 16:49:17475 this._overviewControls.push(new TimelineEventOverviewMemory());
Tim van der Lippe1d6e57a2019-09-30 11:55:34476 }
477 if (this._startCoverage.get()) {
Paul Lewis897ad8b2020-01-15 16:49:17478 this._overviewControls.push(new TimelineEventOverviewCoverage());
Tim van der Lippe1d6e57a2019-09-30 11:55:34479 }
480 for (const control of this._overviewControls) {
Blink Reformat4c46d092018-04-07 15:32:37481 control.setModel(this._performanceModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34482 }
Blink Reformat4c46d092018-04-07 15:32:37483 this._overviewPane.setOverviewControls(this._overviewControls);
484 }
485
486 _onModeChanged() {
487 this._updateOverviewControls();
488 this.doResize();
489 this.select(null);
490 }
491
492 _updateSettingsPaneVisibility() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34493 if (this._showSettingsPaneSetting.get()) {
Blink Reformat4c46d092018-04-07 15:32:37494 this._settingsPane.showWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34495 } else {
Blink Reformat4c46d092018-04-07 15:32:37496 this._settingsPane.hideWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34497 }
Blink Reformat4c46d092018-04-07 15:32:37498 }
499
500 _updateShowSettingsToolbarButton() {
501 const messages = [];
Tim van der Lippecec9b762020-02-13 15:31:22502 if (MobileThrottling.ThrottlingManager.throttlingManager().cpuThrottlingRate() !== 1) {
503 messages.push(Common.UIString.UIString('- CPU throttling is enabled'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34504 }
Paul Lewis5a922e72020-01-24 11:58:08505 if (self.SDK.multitargetNetworkManager.isThrottling()) {
Tim van der Lippecec9b762020-02-13 15:31:22506 messages.push(Common.UIString.UIString('- Network throttling is enabled'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34507 }
508 if (this._captureLayersAndPicturesSetting.get()) {
Tim van der Lippecec9b762020-02-13 15:31:22509 messages.push(Common.UIString.UIString('- Significant overhead due to paint instrumentation'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34510 }
511 if (this._disableCaptureJSProfileSetting.get()) {
Tim van der Lippecec9b762020-02-13 15:31:22512 messages.push(Common.UIString.UIString('- JavaScript sampling is disabled'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34513 }
Blink Reformat4c46d092018-04-07 15:32:37514
515 this._showSettingsPaneButton.setDefaultWithRedColor(messages.length);
516 this._showSettingsPaneButton.setToggleWithRedColor(messages.length);
517
518 if (messages.length) {
519 const tooltipElement = createElement('div');
520 messages.forEach(message => {
521 tooltipElement.createChild('div').textContent = message;
522 });
523 this._showSettingsPaneButton.setTitle(tooltipElement);
524 } else {
Tim van der Lippecec9b762020-02-13 15:31:22525 this._showSettingsPaneButton.setTitle(Common.UIString.UIString('Capture settings'));
Blink Reformat4c46d092018-04-07 15:32:37526 }
527 }
528
529 /**
530 * @param {boolean} enabled
531 */
532 _setUIControlsEnabled(enabled) {
533 this._recordingOptionUIControls.forEach(control => control.setEnabled(enabled));
534 }
535
Blink Reformat4c46d092018-04-07 15:32:37536 async _startRecording() {
537 console.assert(!this._statusPane, 'Status pane is already opened.');
Tim van der Lippe0176f6c2020-01-08 11:07:01538 this._setState(State.StartPending);
Blink Reformat4c46d092018-04-07 15:32:37539
540 const recordingOptions = {
541 enableJSSampling: !this._disableCaptureJSProfileSetting.get(),
542 capturePictures: this._captureLayersAndPicturesSetting.get(),
Jan Schefflerfc2f3832019-09-24 14:03:32543 captureFilmStrip: this._showScreenshotsSetting.get(),
544 startCoverage: this._startCoverage.get()
Blink Reformat4c46d092018-04-07 15:32:37545 };
546
Jan Schefflerfc2f3832019-09-24 14:03:32547 if (recordingOptions.startCoverage) {
Paul Lewis50993692020-01-23 15:22:26548 await self.UI.viewManager.showView('coverage')
549 .then(() => self.UI.viewManager.view('coverage').widget())
Jan Schefflerfc2f3832019-09-24 14:03:32550 .then(widget => widget.ensureRecordingStarted());
551 }
552
553 this._showRecordingStarted();
554
Paul Lewis396d0b92020-01-24 16:08:30555 const enabledTraceProviders = self.Extensions.extensionServer.traceProviders().filter(
Tim van der Lippe0176f6c2020-01-08 11:07:01556 provider => TimelinePanel._settingForTraceProvider(provider).get());
Jan Schefflerfc2f3832019-09-24 14:03:32557
Tim van der Lippecec9b762020-02-13 15:31:22558 const mainTarget = /** @type {!SDK.SDKModel.Target} */ (self.SDK.targetManager.mainTarget());
Paul Lewis897ad8b2020-01-15 16:49:17559 if (UIDevtoolsUtils.isUiDevTools()) {
560 this._controller = new UIDevtoolsController(mainTarget, this);
Yang Guo12254022019-10-01 19:20:44561 } else {
Paul Lewis897ad8b2020-01-15 16:49:17562 this._controller = new TimelineController(mainTarget, this);
Yang Guo12254022019-10-01 19:20:44563 }
Blink Reformat4c46d092018-04-07 15:32:37564 this._setUIControlsEnabled(false);
565 this._hideLandingPage();
Sigurd Schneider6eecdaa2019-08-20 07:47:10566 const response = await this._controller.startRecording(recordingOptions, enabledTraceProviders);
Tim van der Lippecec9b762020-02-13 15:31:22567 if (response[ProtocolModule.InspectorBackend.ProtocolError]) {
568 this._recordingFailed(response[ProtocolModule.InspectorBackend.ProtocolError]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34569 } else {
Sigurd Schneider6eecdaa2019-08-20 07:47:10570 this._recordingStarted();
Tim van der Lippe1d6e57a2019-09-30 11:55:34571 }
Blink Reformat4c46d092018-04-07 15:32:37572 }
573
574 async _stopRecording() {
575 if (this._statusPane) {
576 this._statusPane.finish();
Mathias Bynens23ee1aa2020-03-02 12:06:38577 this._statusPane.updateStatus(Common.UIString.UIString('Stopping timeline…'));
Tim van der Lippecec9b762020-02-13 15:31:22578 this._statusPane.updateProgressBar(Common.UIString.UIString('Received'), 0);
Blink Reformat4c46d092018-04-07 15:32:37579 }
Tim van der Lippe0176f6c2020-01-08 11:07:01580 this._setState(State.StopPending);
Sigurd Schneider759ef972020-01-28 09:46:06581 if (this._startCoverage.get()) {
Tim van der Lippecec9b762020-02-13 15:31:22582 await self.UI.viewManager.showView('coverage')
583 .then(() => self.UI.viewManager.view('coverage').widget())
Sigurd Schneider759ef972020-01-28 09:46:06584 .then(widget => widget.stopRecording());
585 }
Sigurd Schneider6eecdaa2019-08-20 07:47:10586 const model = await this._controller.stopRecording();
587 this._performanceModel = model;
Blink Reformat4c46d092018-04-07 15:32:37588 this._setUIControlsEnabled(true);
Alexei Filippove712dbc2018-05-30 22:31:33589 this._controller.dispose();
Blink Reformat4c46d092018-04-07 15:32:37590 this._controller = null;
591 }
592
Sigurd Schneider6eecdaa2019-08-20 07:47:10593 /**
594 * @param {string} error The error message to display
595 */
596 _recordingFailed(error) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34597 if (this._statusPane) {
Sigurd Schneider6eecdaa2019-08-20 07:47:10598 this._statusPane.hide();
Tim van der Lippe1d6e57a2019-09-30 11:55:34599 }
Tim van der Lippe0176f6c2020-01-08 11:07:01600 this._statusPane = new StatusPane({description: error}, () => this.loadingComplete(null));
Sigurd Schneider6eecdaa2019-08-20 07:47:10601 this._statusPane.showPane(this._statusPaneContainer);
602 this._statusPane.updateStatus(ls`Recording failed`);
603 this._statusPane.updateButton(ls`Close`);
604
Tim van der Lippe0176f6c2020-01-08 11:07:01605 this._setState(State.RecordingFailed);
Sigurd Schneider6eecdaa2019-08-20 07:47:10606 this._performanceModel = null;
607 this._setUIControlsEnabled(false);
608 this._controller.dispose();
609 this._controller = null;
610 }
611
Blink Reformat4c46d092018-04-07 15:32:37612 _onSuspendStateChanged() {
613 this._updateTimelineControls();
614 }
615
616 _updateTimelineControls() {
Tim van der Lippe0176f6c2020-01-08 11:07:01617 const state = State;
Blink Reformat4c46d092018-04-07 15:32:37618 this._toggleRecordAction.setToggled(this._state === state.Recording);
619 this._toggleRecordAction.setEnabled(this._state === state.Recording || this._state === state.Idle);
620 this._recordReloadAction.setEnabled(this._state === state.Idle);
621 this._historyManager.setEnabled(this._state === state.Idle);
622 this._clearButton.setEnabled(this._state === state.Idle);
623 this._panelToolbar.setEnabled(this._state !== state.Loading);
Erik Luo6355f4d2018-06-01 03:32:24624 this._panelRightToolbar.setEnabled(this._state !== state.Loading);
Blink Reformat4c46d092018-04-07 15:32:37625 this._dropTarget.setEnabled(this._state === state.Idle);
626 this._loadButton.setEnabled(this._state === state.Idle);
627 this._saveButton.setEnabled(this._state === state.Idle && !!this._performanceModel);
628 }
629
630 _toggleRecording() {
Tim van der Lippe0176f6c2020-01-08 11:07:01631 if (this._state === State.Idle) {
Blink Reformat4c46d092018-04-07 15:32:37632 this._recordingPageReload = false;
633 this._startRecording();
634 Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelineStarted);
Tim van der Lippe0176f6c2020-01-08 11:07:01635 } else if (this._state === State.Recording) {
Blink Reformat4c46d092018-04-07 15:32:37636 this._stopRecording();
637 }
638 }
639
640 _recordReload() {
Tim van der Lippe0176f6c2020-01-08 11:07:01641 if (this._state !== State.Idle) {
Blink Reformat4c46d092018-04-07 15:32:37642 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34643 }
Blink Reformat4c46d092018-04-07 15:32:37644 this._recordingPageReload = true;
645 this._startRecording();
646 Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelinePageReloadStarted);
647 }
648
649 _onClearButton() {
650 this._historyManager.clear();
651 this._clear();
652 }
653
654 _clear() {
655 this._showLandingPage();
656 this._reset();
657 }
658
659 _reset() {
Alexei Filippovf2e42e42019-04-04 21:40:45660 self.runtime.sharedInstance(PerfUI.LineLevelProfile.Performance).reset();
Blink Reformat4c46d092018-04-07 15:32:37661 this._setModel(null);
662 }
663
664 /**
Paul Lewis897ad8b2020-01-15 16:49:17665 * @param {!PerformanceModel} model
Alexei Filippov35f97d62018-04-28 01:02:31666 */
667 _applyFilters(model) {
Tim van der Lippe99e59b82019-09-30 20:00:59668 if (model.timelineModel().isGenericTrace() || Root.Runtime.experiments.isEnabled('timelineShowAllEvents')) {
Alexei Filippov35f97d62018-04-28 01:02:31669 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34670 }
Paul Lewis897ad8b2020-01-15 16:49:17671 model.setFilters([TimelineUIUtils.visibleEventsFilter()]);
Alexei Filippov35f97d62018-04-28 01:02:31672 }
673
674 /**
Paul Lewis897ad8b2020-01-15 16:49:17675 * @param {?PerformanceModel} model
Blink Reformat4c46d092018-04-07 15:32:37676 */
677 _setModel(model) {
Alexei Filippov2578eb02018-04-11 08:15:05678 if (this._performanceModel) {
Paul Lewis897ad8b2020-01-15 16:49:17679 this._performanceModel.removeEventListener(Events.WindowChanged, this._onModelWindowChanged, this);
Alexei Filippov2578eb02018-04-11 08:15:05680 }
Blink Reformat4c46d092018-04-07 15:32:37681 this._performanceModel = model;
Tim van der Lippe1d6e57a2019-09-30 11:55:34682 if (model) {
Jack Lynchd9a5b6e2020-02-24 20:35:19683 this._searchableView.showWidget();
Alexei Filippov35f97d62018-04-28 01:02:31684 this._applyFilters(model);
Jack Lynchd9a5b6e2020-02-24 20:35:19685 } else {
686 this._searchableView.hideWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34687 }
Blink Reformat4c46d092018-04-07 15:32:37688 this._flameChart.setModel(model);
689
Alexei Filippoveddfd842018-04-28 01:01:13690 this._updateOverviewControls();
Blink Reformat4c46d092018-04-07 15:32:37691 this._overviewPane.reset();
692 if (model) {
Paul Lewis897ad8b2020-01-15 16:49:17693 this._performanceModel.addEventListener(Events.WindowChanged, this._onModelWindowChanged, this);
Blink Reformat4c46d092018-04-07 15:32:37694 this._overviewPane.setBounds(
695 model.timelineModel().minimumRecordTime(), model.timelineModel().maximumRecordTime());
Alexei Filippovf2e42e42019-04-04 21:40:45696 const lineLevelProfile = self.runtime.sharedInstance(PerfUI.LineLevelProfile.Performance);
Alexei Filippov6c892822019-03-06 22:30:42697 lineLevelProfile.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:34698 for (const profile of model.timelineModel().cpuProfiles()) {
Alexei Filippov6c892822019-03-06 22:30:42699 lineLevelProfile.appendCPUProfile(profile);
Tim van der Lippe1d6e57a2019-09-30 11:55:34700 }
Alexei Filippov2578eb02018-04-11 08:15:05701 this._setMarkers(model.timelineModel());
702 this._flameChart.setSelection(null);
703 this._overviewPane.setWindowTimes(model.window().left, model.window().right);
Blink Reformat4c46d092018-04-07 15:32:37704 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34705 for (const control of this._overviewControls) {
Blink Reformat4c46d092018-04-07 15:32:37706 control.setModel(model);
Tim van der Lippe1d6e57a2019-09-30 11:55:34707 }
708 if (this._flameChart) {
Blink Reformat4c46d092018-04-07 15:32:37709 this._flameChart.resizeToPreferredHeights();
Tim van der Lippe1d6e57a2019-09-30 11:55:34710 }
Blink Reformat4c46d092018-04-07 15:32:37711 this._updateTimelineControls();
712 }
713
714 _recordingStarted() {
715 if (this._recordingPageReload) {
716 const target = this._controller.mainTarget();
Tim van der Lippecec9b762020-02-13 15:31:22717 const resourceModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34718 if (resourceModel) {
Blink Reformat4c46d092018-04-07 15:32:37719 resourceModel.reloadPage();
Tim van der Lippe1d6e57a2019-09-30 11:55:34720 }
Blink Reformat4c46d092018-04-07 15:32:37721 }
722 this._reset();
Tim van der Lippe0176f6c2020-01-08 11:07:01723 this._setState(State.Recording);
Blink Reformat4c46d092018-04-07 15:32:37724 this._showRecordingStarted();
Tony Rossba14dc62020-02-18 18:37:05725 this._statusPane.enableAndFocusStopButton();
Mathias Bynens23ee1aa2020-03-02 12:06:38726 this._statusPane.updateStatus(Common.UIString.UIString('Profiling…'));
Tim van der Lippecec9b762020-02-13 15:31:22727 this._statusPane.updateProgressBar(Common.UIString.UIString('Buffer usage'), 0);
Blink Reformat4c46d092018-04-07 15:32:37728 this._statusPane.startTimer();
729 this._hideLandingPage();
730 }
731
732 /**
733 * @override
734 * @param {number} usage
735 */
736 recordingProgress(usage) {
Tim van der Lippecec9b762020-02-13 15:31:22737 this._statusPane.updateProgressBar(Common.UIString.UIString('Buffer usage'), usage * 100);
Blink Reformat4c46d092018-04-07 15:32:37738 }
739
740 _showLandingPage() {
741 if (this._landingPage) {
742 this._landingPage.show(this._statusPaneContainer);
743 return;
744 }
745
746 /**
747 * @param {string} tagName
748 * @param {string} contents
749 */
750 function encloseWithTag(tagName, contents) {
751 const e = createElement(tagName);
752 e.textContent = contents;
753 return e;
754 }
755
Tim van der Lippecec9b762020-02-13 15:31:22756 const learnMoreNode = UI.XLink.XLink.create(
Blink Reformat4c46d092018-04-07 15:32:37757 'https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/',
Tim van der Lippecec9b762020-02-13 15:31:22758 Common.UIString.UIString('Learn\xa0more'));
Blink Reformat4c46d092018-04-07 15:32:37759
760 const recordKey =
Paul Lewis05eb37f2020-01-24 14:31:40761 encloseWithTag('b', self.UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording')[0].name);
Blink Reformat4c46d092018-04-07 15:32:37762 const reloadKey =
Paul Lewis05eb37f2020-01-24 14:31:40763 encloseWithTag('b', self.UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.record-reload')[0].name);
Tim van der Lippecec9b762020-02-13 15:31:22764 const navigateNode = encloseWithTag('b', Common.UIString.UIString('WASD'));
Blink Reformat4c46d092018-04-07 15:32:37765
Tim van der Lippecec9b762020-02-13 15:31:22766 this._landingPage = new UI.Widget.VBox();
Blink Reformat4c46d092018-04-07 15:32:37767 this._landingPage.contentElement.classList.add('timeline-landing-page', 'fill');
768 const centered = this._landingPage.contentElement.createChild('div');
769
Tim van der Lippecec9b762020-02-13 15:31:22770 const recordButton = UI.UIUtils.createInlineButton(UI.Toolbar.Toolbar.createActionButton(this._toggleRecordAction));
771 const reloadButton =
772 UI.UIUtils.createInlineButton(UI.Toolbar.Toolbar.createActionButtonForId('timeline.record-reload'));
Blink Reformat4c46d092018-04-07 15:32:37773
Tim van der Lippecec9b762020-02-13 15:31:22774 centered.createChild('p').appendChild(UI.UIUtils.formatLocalized(
Lorne Mitchell7aa2c6c2019-04-03 03:50:10775 'Click the record button %s or hit %s to start a new recording.\nClick the reload button %s or hit %s to record the page load.',
Blink Reformat4c46d092018-04-07 15:32:37776 [recordButton, recordKey, reloadButton, reloadKey]));
777
Tim van der Lippecec9b762020-02-13 15:31:22778 centered.createChild('p').appendChild(UI.UIUtils.formatLocalized(
Lorne Mitchell7aa2c6c2019-04-03 03:50:10779 'After recording, select an area of interest in the overview by dragging.\nThen, zoom and pan the timeline with the mousewheel or %s keys.\n%s',
Blink Reformat4c46d092018-04-07 15:32:37780 [navigateNode, learnMoreNode]));
781
782 this._landingPage.show(this._statusPaneContainer);
783 }
784
785 _hideLandingPage() {
786 this._landingPage.detach();
787 }
788
789 /**
790 * @override
791 */
792 loadingStarted() {
793 this._hideLandingPage();
794
Tim van der Lippe1d6e57a2019-09-30 11:55:34795 if (this._statusPane) {
Blink Reformat4c46d092018-04-07 15:32:37796 this._statusPane.hide();
Tim van der Lippe1d6e57a2019-09-30 11:55:34797 }
Tim van der Lippe0176f6c2020-01-08 11:07:01798 this._statusPane = new StatusPane({showProgress: true}, this._cancelLoading.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37799 this._statusPane.showPane(this._statusPaneContainer);
Mathias Bynens23ee1aa2020-03-02 12:06:38800 this._statusPane.updateStatus(Common.UIString.UIString('Loading profile…'));
Blink Reformat4c46d092018-04-07 15:32:37801 // FIXME: make loading from backend cancelable as well.
Tim van der Lippe1d6e57a2019-09-30 11:55:34802 if (!this._loader) {
Blink Reformat4c46d092018-04-07 15:32:37803 this._statusPane.finish();
Tim van der Lippe1d6e57a2019-09-30 11:55:34804 }
Blink Reformat4c46d092018-04-07 15:32:37805 this.loadingProgress(0);
806 }
807
808 /**
809 * @override
810 * @param {number=} progress
811 */
812 loadingProgress(progress) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34813 if (typeof progress === 'number') {
Tim van der Lippecec9b762020-02-13 15:31:22814 this._statusPane.updateProgressBar(Common.UIString.UIString('Received'), progress * 100);
Tim van der Lippe1d6e57a2019-09-30 11:55:34815 }
Blink Reformat4c46d092018-04-07 15:32:37816 }
817
818 /**
819 * @override
820 */
821 processingStarted() {
Mathias Bynens23ee1aa2020-03-02 12:06:38822 this._statusPane.updateStatus(Common.UIString.UIString('Processing profile…'));
Blink Reformat4c46d092018-04-07 15:32:37823 }
824
825 /**
826 * @override
Tim van der Lippecec9b762020-02-13 15:31:22827 * @param {?SDK.TracingModel.TracingModel} tracingModel
Blink Reformat4c46d092018-04-07 15:32:37828 */
829 loadingComplete(tracingModel) {
830 delete this._loader;
Tim van der Lippe0176f6c2020-01-08 11:07:01831 this._setState(State.Idle);
Blink Reformat4c46d092018-04-07 15:32:37832
Tim van der Lippe1d6e57a2019-09-30 11:55:34833 if (this._statusPane) {
Blink Reformat4c46d092018-04-07 15:32:37834 this._statusPane.hide();
Tim van der Lippe1d6e57a2019-09-30 11:55:34835 }
Blink Reformat4c46d092018-04-07 15:32:37836 delete this._statusPane;
837
838 if (!tracingModel) {
839 this._clear();
840 return;
841 }
842
Tim van der Lippe1d6e57a2019-09-30 11:55:34843 if (!this._performanceModel) {
Paul Lewis897ad8b2020-01-15 16:49:17844 this._performanceModel = new PerformanceModel();
Tim van der Lippe1d6e57a2019-09-30 11:55:34845 }
Blink Reformat4c46d092018-04-07 15:32:37846 this._performanceModel.setTracingModel(tracingModel);
847 this._setModel(this._performanceModel);
848 this._historyManager.addRecording(this._performanceModel);
Jan Schefflerfc2f3832019-09-24 14:03:32849
850 if (this._startCoverage.get()) {
Tim van der Lippecec9b762020-02-13 15:31:22851 self.UI.viewManager.showView('coverage')
852 .then(() => self.UI.viewManager.view('coverage').widget())
Sigurd Schneider759ef972020-01-28 09:46:06853 .then(widget => widget.processBacklog())
Sigurd Schneider89d42ef2019-09-25 15:08:40854 .then(() => this._updateOverviewControls());
Jan Schefflerfc2f3832019-09-24 14:03:32855 }
Blink Reformat4c46d092018-04-07 15:32:37856 }
857
858 _showRecordingStarted() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34859 if (this._statusPane) {
Blink Reformat4c46d092018-04-07 15:32:37860 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34861 }
Tim van der Lippe0176f6c2020-01-08 11:07:01862 this._statusPane = new StatusPane({showTimer: true, showProgress: true}, this._stopRecording.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37863 this._statusPane.showPane(this._statusPaneContainer);
Mathias Bynens23ee1aa2020-03-02 12:06:38864 this._statusPane.updateStatus(Common.UIString.UIString('Initializing profiler…'));
Blink Reformat4c46d092018-04-07 15:32:37865 }
866
867 _cancelLoading() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34868 if (this._loader) {
Blink Reformat4c46d092018-04-07 15:32:37869 this._loader.cancel();
Tim van der Lippe1d6e57a2019-09-30 11:55:34870 }
Blink Reformat4c46d092018-04-07 15:32:37871 }
872
873 /**
Tim van der Lippecec9b762020-02-13 15:31:22874 * @param {!TimelineModel.TimelineModel.TimelineModelImpl} timelineModel
Blink Reformat4c46d092018-04-07 15:32:37875 */
876 _setMarkers(timelineModel) {
877 const markers = new Map();
878 const recordTypes = TimelineModel.TimelineModel.RecordType;
879 const zeroTime = timelineModel.minimumRecordTime();
Alexei Filippov45dbf982018-05-01 22:51:52880 for (const event of timelineModel.timeMarkerEvents()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34881 if (event.name === recordTypes.TimeStamp || event.name === recordTypes.ConsoleTime) {
Blink Reformat4c46d092018-04-07 15:32:37882 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34883 }
Paul Lewis897ad8b2020-01-15 16:49:17884 markers.set(event.startTime, TimelineUIUtils.createEventDivider(event, zeroTime));
Blink Reformat4c46d092018-04-07 15:32:37885 }
886 this._overviewPane.setMarkers(markers);
887 }
888
889 /**
Tim van der Lippec02a97c2020-02-14 14:39:27890 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37891 */
892 async _loadEventFired(event) {
Tim van der Lippe0176f6c2020-01-08 11:07:01893 if (this._state !== State.Recording || !this._recordingPageReload ||
Tim van der Lippe1d6e57a2019-09-30 11:55:34894 this._controller.mainTarget() !== event.data.resourceTreeModel.target()) {
Blink Reformat4c46d092018-04-07 15:32:37895 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34896 }
Blink Reformat4c46d092018-04-07 15:32:37897 const controller = this._controller;
898 await new Promise(r => setTimeout(r, this._millisecondsToRecordAfterLoadEvent));
899
900 // Check if we're still in the same recording session.
Tim van der Lippe0176f6c2020-01-08 11:07:01901 if (controller !== this._controller || this._state !== State.Recording) {
Blink Reformat4c46d092018-04-07 15:32:37902 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34903 }
Blink Reformat4c46d092018-04-07 15:32:37904 this._stopRecording();
905 }
906
907 /**
Tim van der Lippe0176f6c2020-01-08 11:07:01908 * @param {!TimelineSelection} selection
Tim van der Lippecec9b762020-02-13 15:31:22909 * @return {?TimelineModel.TimelineFrameModel.TimelineFrame}
Blink Reformat4c46d092018-04-07 15:32:37910 */
911 _frameForSelection(selection) {
912 switch (selection.type()) {
Tim van der Lippe0176f6c2020-01-08 11:07:01913 case TimelineSelection.Type.Frame:
Tim van der Lippecec9b762020-02-13 15:31:22914 return /** @type {!TimelineModel.TimelineFrameModel.TimelineFrame} */ (selection.object());
Tim van der Lippe0176f6c2020-01-08 11:07:01915 case TimelineSelection.Type.Range:
Blink Reformat4c46d092018-04-07 15:32:37916 return null;
Tim van der Lippe0176f6c2020-01-08 11:07:01917 case TimelineSelection.Type.TraceEvent:
Alexei Filippoveddfd842018-04-28 01:01:13918 return this._performanceModel.frameModel().frames(selection._endTime, selection._endTime)[0];
Blink Reformat4c46d092018-04-07 15:32:37919 default:
920 console.assert(false, 'Should never be reached');
921 return null;
922 }
923 }
924
925 /**
926 * @param {number} offset
927 */
928 _jumpToFrame(offset) {
Alexei Filippov2578eb02018-04-11 08:15:05929 const currentFrame = this._selection && this._frameForSelection(this._selection);
Tim van der Lippe1d6e57a2019-09-30 11:55:34930 if (!currentFrame) {
Blink Reformat4c46d092018-04-07 15:32:37931 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34932 }
Blink Reformat4c46d092018-04-07 15:32:37933 const frames = this._performanceModel.frames();
934 let index = frames.indexOf(currentFrame);
935 console.assert(index >= 0, 'Can\'t find current frame in the frame list');
936 index = Number.constrain(index + offset, 0, frames.length - 1);
937 const frame = frames[index];
938 this._revealTimeRange(frame.startTime, frame.endTime);
Tim van der Lippe0176f6c2020-01-08 11:07:01939 this.select(TimelineSelection.fromFrame(frame));
Blink Reformat4c46d092018-04-07 15:32:37940 return true;
941 }
942
943 /**
944 * @override
Tim van der Lippe0176f6c2020-01-08 11:07:01945 * @param {?TimelineSelection} selection
Blink Reformat4c46d092018-04-07 15:32:37946 */
947 select(selection) {
Alexei Filippov2578eb02018-04-11 08:15:05948 this._selection = selection;
Blink Reformat4c46d092018-04-07 15:32:37949 this._flameChart.setSelection(selection);
950 }
951
952 /**
953 * @override
954 * @param {?Array<!SDK.TracingModel.Event>} events
955 * @param {number} time
956 */
957 selectEntryAtTime(events, time) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34958 if (!events) {
Blink Reformat4c46d092018-04-07 15:32:37959 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34960 }
Blink Reformat4c46d092018-04-07 15:32:37961 // Find best match, then backtrack to the first visible entry.
962 for (let index = events.upperBound(time, (time, event) => time - event.startTime) - 1; index >= 0; --index) {
963 const event = events[index];
964 const endTime = event.endTime || event.startTime;
Tim van der Lippecec9b762020-02-13 15:31:22965 if (SDK.TracingModel.TracingModel.isTopLevelEvent(event) && endTime < time) {
Blink Reformat4c46d092018-04-07 15:32:37966 break;
Tim van der Lippe1d6e57a2019-09-30 11:55:34967 }
Alexei Filippov35f97d62018-04-28 01:02:31968 if (this._performanceModel.isVisible(event) && endTime >= time) {
Tim van der Lippe0176f6c2020-01-08 11:07:01969 this.select(TimelineSelection.fromTraceEvent(event));
Blink Reformat4c46d092018-04-07 15:32:37970 return;
971 }
972 }
973 this.select(null);
974 }
975
976 /**
977 * @override
978 * @param {?SDK.TracingModel.Event} event
979 */
980 highlightEvent(event) {
981 this._flameChart.highlightEvent(event);
982 }
983
984 /**
985 * @param {number} startTime
986 * @param {number} endTime
987 */
988 _revealTimeRange(startTime, endTime) {
Alexei Filippov2578eb02018-04-11 08:15:05989 const window = this._performanceModel.window();
990 let offset = 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:34991 if (window.right < endTime) {
Alexei Filippov2578eb02018-04-11 08:15:05992 offset = endTime - window.right;
Tim van der Lippe1d6e57a2019-09-30 11:55:34993 } else if (window.left > startTime) {
Alexei Filippov2578eb02018-04-11 08:15:05994 offset = startTime - window.left;
Tim van der Lippe1d6e57a2019-09-30 11:55:34995 }
Alexei Filippov2578eb02018-04-11 08:15:05996 this._performanceModel.setWindow({left: window.left + offset, right: window.right + offset}, /* animate */ true);
Blink Reformat4c46d092018-04-07 15:32:37997 }
998
999 /**
1000 * @param {!DataTransfer} dataTransfer
1001 */
1002 _handleDrop(dataTransfer) {
1003 const items = dataTransfer.items;
Tim van der Lippe1d6e57a2019-09-30 11:55:341004 if (!items.length) {
Blink Reformat4c46d092018-04-07 15:32:371005 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341006 }
Blink Reformat4c46d092018-04-07 15:32:371007 const item = items[0];
1008 if (item.kind === 'string') {
1009 const url = dataTransfer.getData('text/uri-list');
Tim van der Lippecec9b762020-02-13 15:31:221010 if (new Common.ParsedURL.ParsedURL(url).isValid) {
Blink Reformat4c46d092018-04-07 15:32:371011 this._loadFromURL(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341012 }
Blink Reformat4c46d092018-04-07 15:32:371013 } else if (item.kind === 'file') {
1014 const entry = items[0].webkitGetAsEntry();
Tim van der Lippe1d6e57a2019-09-30 11:55:341015 if (!entry.isFile) {
Blink Reformat4c46d092018-04-07 15:32:371016 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341017 }
Blink Reformat4c46d092018-04-07 15:32:371018 entry.file(this._loadFromFile.bind(this));
1019 }
1020 }
Tim van der Lippe0176f6c2020-01-08 11:07:011021}
Blink Reformat4c46d092018-04-07 15:32:371022
1023/**
1024 * @enum {symbol}
1025 */
Tim van der Lippe0176f6c2020-01-08 11:07:011026export const State = {
Blink Reformat4c46d092018-04-07 15:32:371027 Idle: Symbol('Idle'),
1028 StartPending: Symbol('StartPending'),
1029 Recording: Symbol('Recording'),
1030 StopPending: Symbol('StopPending'),
Sigurd Schneider6eecdaa2019-08-20 07:47:101031 Loading: Symbol('Loading'),
1032 RecordingFailed: Symbol('RecordingFailed')
Blink Reformat4c46d092018-04-07 15:32:371033};
1034
1035/**
1036 * @enum {string}
1037 */
Tim van der Lippe0176f6c2020-01-08 11:07:011038export const ViewMode = {
Blink Reformat4c46d092018-04-07 15:32:371039 FlameChart: 'FlameChart',
1040 BottomUp: 'BottomUp',
1041 CallTree: 'CallTree',
1042 EventLog: 'EventLog'
1043};
1044
1045// Define row and header height, should be in sync with styles for timeline graphs.
Tim van der Lippe0176f6c2020-01-08 11:07:011046export const rowHeight = 18;
Blink Reformat4c46d092018-04-07 15:32:371047
Tim van der Lippe0176f6c2020-01-08 11:07:011048export const headerHeight = 20;
Blink Reformat4c46d092018-04-07 15:32:371049
Tim van der Lippe0176f6c2020-01-08 11:07:011050export class TimelineSelection {
Blink Reformat4c46d092018-04-07 15:32:371051 /**
Tim van der Lippe0176f6c2020-01-08 11:07:011052 * @param {!TimelineSelection.Type} type
Blink Reformat4c46d092018-04-07 15:32:371053 * @param {number} startTime
1054 * @param {number} endTime
1055 * @param {!Object=} object
1056 */
1057 constructor(type, startTime, endTime, object) {
1058 this._type = type;
1059 this._startTime = startTime;
1060 this._endTime = endTime;
1061 this._object = object || null;
1062 }
1063
1064 /**
Tim van der Lippecec9b762020-02-13 15:31:221065 * @param {!TimelineModel.TimelineFrameModel.TimelineFrame} frame
Tim van der Lippe0176f6c2020-01-08 11:07:011066 * @return {!TimelineSelection}
Blink Reformat4c46d092018-04-07 15:32:371067 */
1068 static fromFrame(frame) {
Tim van der Lippe0176f6c2020-01-08 11:07:011069 return new TimelineSelection(TimelineSelection.Type.Frame, frame.startTime, frame.endTime, frame);
Blink Reformat4c46d092018-04-07 15:32:371070 }
1071
1072 /**
1073 * @param {!TimelineModel.TimelineModel.NetworkRequest} request
Tim van der Lippe0176f6c2020-01-08 11:07:011074 * @return {!TimelineSelection}
Blink Reformat4c46d092018-04-07 15:32:371075 */
1076 static fromNetworkRequest(request) {
Tim van der Lippe0176f6c2020-01-08 11:07:011077 return new TimelineSelection(
1078 TimelineSelection.Type.NetworkRequest, request.startTime, request.endTime || request.startTime, request);
Blink Reformat4c46d092018-04-07 15:32:371079 }
1080
1081 /**
1082 * @param {!SDK.TracingModel.Event} event
Tim van der Lippe0176f6c2020-01-08 11:07:011083 * @return {!TimelineSelection}
Blink Reformat4c46d092018-04-07 15:32:371084 */
1085 static fromTraceEvent(event) {
Tim van der Lippe0176f6c2020-01-08 11:07:011086 return new TimelineSelection(
1087 TimelineSelection.Type.TraceEvent, event.startTime, event.endTime || (event.startTime + 1), event);
Blink Reformat4c46d092018-04-07 15:32:371088 }
1089
1090 /**
1091 * @param {number} startTime
1092 * @param {number} endTime
Tim van der Lippe0176f6c2020-01-08 11:07:011093 * @return {!TimelineSelection}
Blink Reformat4c46d092018-04-07 15:32:371094 */
1095 static fromRange(startTime, endTime) {
Tim van der Lippe0176f6c2020-01-08 11:07:011096 return new TimelineSelection(TimelineSelection.Type.Range, startTime, endTime);
Blink Reformat4c46d092018-04-07 15:32:371097 }
1098
1099 /**
Tim van der Lippe0176f6c2020-01-08 11:07:011100 * @return {!TimelineSelection.Type}
Blink Reformat4c46d092018-04-07 15:32:371101 */
1102 type() {
1103 return this._type;
1104 }
1105
1106 /**
1107 * @return {?Object}
1108 */
1109 object() {
1110 return this._object;
1111 }
1112
1113 /**
1114 * @return {number}
1115 */
1116 startTime() {
1117 return this._startTime;
1118 }
1119
1120 /**
1121 * @return {number}
1122 */
1123 endTime() {
1124 return this._endTime;
1125 }
Tim van der Lippe0176f6c2020-01-08 11:07:011126}
Blink Reformat4c46d092018-04-07 15:32:371127
1128/**
1129 * @enum {string}
1130 */
Tim van der Lippe0176f6c2020-01-08 11:07:011131TimelineSelection.Type = {
Blink Reformat4c46d092018-04-07 15:32:371132 Frame: 'Frame',
1133 NetworkRequest: 'NetworkRequest',
1134 TraceEvent: 'TraceEvent',
1135 Range: 'Range'
1136};
1137
Blink Reformat4c46d092018-04-07 15:32:371138/**
1139 * @interface
1140 */
Tim van der Lippe0176f6c2020-01-08 11:07:011141export class TimelineModeViewDelegate {
Blink Reformat4c46d092018-04-07 15:32:371142 /**
Tim van der Lippe0176f6c2020-01-08 11:07:011143 * @param {?TimelineSelection} selection
Blink Reformat4c46d092018-04-07 15:32:371144 */
Tim van der Lippe0176f6c2020-01-08 11:07:011145 select(selection) {
1146 }
Blink Reformat4c46d092018-04-07 15:32:371147
1148 /**
1149 * @param {?Array<!SDK.TracingModel.Event>} events
1150 * @param {number} time
1151 */
Tim van der Lippe0176f6c2020-01-08 11:07:011152 selectEntryAtTime(events, time) {
1153 }
Blink Reformat4c46d092018-04-07 15:32:371154
1155 /**
1156 * @param {?SDK.TracingModel.Event} event
1157 */
Tim van der Lippe0176f6c2020-01-08 11:07:011158 highlightEvent(event) {
1159 }
1160}
Blink Reformat4c46d092018-04-07 15:32:371161
1162/**
1163 * @unrestricted
1164 */
Tim van der Lippecec9b762020-02-13 15:31:221165export class StatusPane extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:371166 /**
Sigurd Schneider6eecdaa2019-08-20 07:47:101167 * @param {!{showTimer: (boolean|undefined), showProgress: (boolean|undefined), description: (string|undefined)}} options - a collection of options controlling the appearance of the pane.
1168 * The options object can have the following properties:
1169 * - **showTimer** - `{boolean}` - Display seconds since dialog opened
1170 * - **showProgress** - `{boolean}` - Display a progress bar
1171 * - **description** - `{string}` - Display this string in a description line
Blink Reformat4c46d092018-04-07 15:32:371172 * @param {function()} stopCallback
1173 */
Sigurd Schneider6eecdaa2019-08-20 07:47:101174 constructor(options, stopCallback) {
Blink Reformat4c46d092018-04-07 15:32:371175 super(true);
1176 this.registerRequiredCSS('timeline/timelineStatusDialog.css');
1177 this.contentElement.classList.add('timeline-status-dialog');
1178
1179 const statusLine = this.contentElement.createChild('div', 'status-dialog-line status');
Tim van der Lippecec9b762020-02-13 15:31:221180 statusLine.createChild('div', 'label').textContent = Common.UIString.UIString('Status');
Blink Reformat4c46d092018-04-07 15:32:371181 this._status = statusLine.createChild('div', 'content');
Chandani Shrestha19ee3a22019-07-18 18:10:391182 UI.ARIAUtils.markAsStatus(this._status);
Blink Reformat4c46d092018-04-07 15:32:371183
Sigurd Schneider6eecdaa2019-08-20 07:47:101184 if (options.showTimer) {
Blink Reformat4c46d092018-04-07 15:32:371185 const timeLine = this.contentElement.createChild('div', 'status-dialog-line time');
Tim van der Lippecec9b762020-02-13 15:31:221186 timeLine.createChild('div', 'label').textContent = Common.UIString.UIString('Time');
Blink Reformat4c46d092018-04-07 15:32:371187 this._time = timeLine.createChild('div', 'content');
1188 }
Sigurd Schneider6eecdaa2019-08-20 07:47:101189
1190 if (options.showProgress) {
1191 const progressLine = this.contentElement.createChild('div', 'status-dialog-line progress');
1192 this._progressLabel = progressLine.createChild('div', 'label');
1193 this._progressBar = progressLine.createChild('div', 'indicator-container').createChild('div', 'indicator');
1194 UI.ARIAUtils.markAsProgressBar(this._progressBar);
1195 }
1196
1197 if (typeof options.description === 'string') {
1198 const descriptionLine = this.contentElement.createChild('div', 'status-dialog-line description');
1199 descriptionLine.createChild('div', 'label').textContent = ls`Description`;
1200 this._description = descriptionLine.createChild('div', 'content');
1201 this._description.innerText = options.description;
1202 }
Blink Reformat4c46d092018-04-07 15:32:371203
Tim van der Lippecec9b762020-02-13 15:31:221204 this._stopButton = UI.UIUtils.createTextButton(Common.UIString.UIString('Stop'), stopCallback, '', true);
Sigurd Schneiderce8ef942019-12-18 14:11:451205 // Profiling can't be stopped during initialization.
1206 this._stopButton.disabled = true;
Blink Reformat4c46d092018-04-07 15:32:371207 this.contentElement.createChild('div', 'stop-button').appendChild(this._stopButton);
1208 }
1209
1210 finish() {
1211 this._stopTimer();
1212 this._stopButton.disabled = true;
1213 }
1214
1215 hide() {
1216 this.element.parentNode.classList.remove('tinted');
1217 this.element.remove();
1218 }
1219
1220 /**
1221 * @param {!Element} parent
1222 */
1223 showPane(parent) {
1224 this.show(parent);
1225 parent.classList.add('tinted');
Blink Reformat4c46d092018-04-07 15:32:371226 }
1227
Tony Rossba14dc62020-02-18 18:37:051228 enableAndFocusStopButton() {
Sigurd Schneiderce8ef942019-12-18 14:11:451229 this._stopButton.disabled = false;
Tony Rossba14dc62020-02-18 18:37:051230 this._stopButton.focus();
Sigurd Schneiderce8ef942019-12-18 14:11:451231 }
1232
Blink Reformat4c46d092018-04-07 15:32:371233 /**
1234 * @param {string} text
1235 */
1236 updateStatus(text) {
1237 this._status.textContent = text;
1238 }
1239
1240 /**
1241 * @param {string} activity
1242 * @param {number} percent
1243 */
1244 updateProgressBar(activity, percent) {
1245 this._progressLabel.textContent = activity;
1246 this._progressBar.style.width = percent.toFixed(1) + '%';
Chandani Shrestha20bddac2019-11-27 19:11:001247 UI.ARIAUtils.setValueNow(this._progressBar, percent);
Blink Reformat4c46d092018-04-07 15:32:371248 this._updateTimer();
1249 }
1250
Sigurd Schneider6eecdaa2019-08-20 07:47:101251 /**
1252 * @param {string} caption
1253 */
1254 updateButton(caption) {
1255 this._stopButton.innerText = caption;
1256 }
1257
Blink Reformat4c46d092018-04-07 15:32:371258 startTimer() {
1259 this._startTime = Date.now();
1260 this._timeUpdateTimer = setInterval(this._updateTimer.bind(this, false), 1000);
1261 this._updateTimer();
1262 }
1263
1264 _stopTimer() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341265 if (!this._timeUpdateTimer) {
Blink Reformat4c46d092018-04-07 15:32:371266 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341267 }
Blink Reformat4c46d092018-04-07 15:32:371268 clearInterval(this._timeUpdateTimer);
1269 this._updateTimer(true);
1270 delete this._timeUpdateTimer;
1271 }
1272
1273 /**
1274 * @param {boolean=} precise
1275 */
1276 _updateTimer(precise) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341277 if (!this._timeUpdateTimer) {
Blink Reformat4c46d092018-04-07 15:32:371278 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341279 }
Blink Reformat4c46d092018-04-07 15:32:371280 const elapsed = (Date.now() - this._startTime) / 1000;
Tim van der Lippecec9b762020-02-13 15:31:221281 this._time.textContent = Common.UIString.UIString('%s\xa0sec', elapsed.toFixed(precise ? 1 : 0));
Blink Reformat4c46d092018-04-07 15:32:371282 }
Tim van der Lippe0176f6c2020-01-08 11:07:011283}
Blink Reformat4c46d092018-04-07 15:32:371284
1285
1286/**
Tim van der Lippecec9b762020-02-13 15:31:221287 * @implements {Common.QueryParamHandler.QueryParamHandler}
Blink Reformat4c46d092018-04-07 15:32:371288 * @unrestricted
1289 */
Tim van der Lippe0176f6c2020-01-08 11:07:011290export class LoadTimelineHandler {
Blink Reformat4c46d092018-04-07 15:32:371291 /**
1292 * @override
1293 * @param {string} value
1294 */
1295 handleQueryParam(value) {
Paul Lewis50993692020-01-23 15:22:261296 self.UI.viewManager.showView('timeline').then(() => {
Tim van der Lippe0176f6c2020-01-08 11:07:011297 TimelinePanel.instance()._loadFromURL(window.decodeURIComponent(value));
Blink Reformat4c46d092018-04-07 15:32:371298 });
1299 }
Tim van der Lippe0176f6c2020-01-08 11:07:011300}
Blink Reformat4c46d092018-04-07 15:32:371301
1302/**
Tim van der Lippecec9b762020-02-13 15:31:221303 * @implements {UI.ActionDelegate.ActionDelegate}
Blink Reformat4c46d092018-04-07 15:32:371304 * @unrestricted
1305 */
Tim van der Lippe0176f6c2020-01-08 11:07:011306export class ActionDelegate {
Blink Reformat4c46d092018-04-07 15:32:371307 /**
1308 * @override
Tim van der Lippecec9b762020-02-13 15:31:221309 * @param {!UI.Context.Context} context
Blink Reformat4c46d092018-04-07 15:32:371310 * @param {string} actionId
1311 * @return {boolean}
1312 */
1313 handleAction(context, actionId) {
Paul Lewisd9907342020-01-24 13:49:471314 const panel = self.UI.context.flavor(TimelinePanel);
Tim van der Lippe0176f6c2020-01-08 11:07:011315 console.assert(panel && panel instanceof TimelinePanel);
Blink Reformat4c46d092018-04-07 15:32:371316 switch (actionId) {
1317 case 'timeline.toggle-recording':
1318 panel._toggleRecording();
1319 return true;
1320 case 'timeline.record-reload':
1321 panel._recordReload();
1322 return true;
1323 case 'timeline.save-to-file':
1324 panel._saveToFile();
1325 return true;
1326 case 'timeline.load-from-file':
1327 panel._selectFileToLoad();
1328 return true;
1329 case 'timeline.jump-to-previous-frame':
1330 panel._jumpToFrame(-1);
1331 return true;
1332 case 'timeline.jump-to-next-frame':
1333 panel._jumpToFrame(1);
1334 return true;
1335 case 'timeline.show-history':
1336 panel._showHistory();
1337 return true;
1338 case 'timeline.previous-recording':
1339 panel._navigateHistory(1);
1340 return true;
1341 case 'timeline.next-recording':
1342 panel._navigateHistory(-1);
1343 return true;
1344 }
1345 return false;
1346 }
Tim van der Lippe0176f6c2020-01-08 11:07:011347}
Blink Reformat4c46d092018-04-07 15:32:371348
Paul Lewis897ad8b2020-01-15 16:49:171349export const traceProviderSettingSymbol = Symbol('traceProviderSetting');