mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-07-20 22:18:29 +00:00
05aa84c996
- Bug 1219711 - Let fake stream take precedence in testing. r=jib (a52bad675a)
- Bug 1207288. Enable the ANGLE shader validator for WebGL 2. r=jgilbert (9583083fe3)
- Bug 1218944. Transform feedback linking should use varyings intead of attribs. r=jgilbert (37742a04e0)
- Bug 1218939. Fixup GetTransformFeedbackVarying. r=jgilbert (5e4ffd63e5)
- Bug 1218559. Implement FindUniformBlockByMappedName. r=jgilbert (0eefbc1012)
- Bug 1215296. Map uniforms from blocks. r=jgilbert (f87ecddafa)
- more byRef to getter_AddRefs (2f5f474265)
- Bug 1217304: P1. Only fire loadeddata once the first frame has been decoded. r=jwwang (8382426465)
- Bug 1217304: P2. Do not transition to HAVE_ENOUGH_DATA readyState until we do have data. r=jwwang (b17554f65f)
- Bug 1207887 - Fix AsyncPanZoomAnimation, WheelScrollAnimation and TextureHost doesn't compile in non-unified build. r=nical (9f893b3584)
- Bug 1145004 - Fix MSE Telemetry VIDEO_MSE_BUFFERING_COUNT - r=cpearce (bdcab5af5a)
- Bug 1205156 - Add telemetry to measure how often getUserMedia is used over non-secure origins r=jib (f456298e6e)
- Bug 1206900: Add telemetry for device types captured with getUserMedia() r=jib,smaug (5e278764dd)
- Bug 1144975 - Video dimensions for tab mirroring can be smaller than the devices display. r=snorp (c5781eca2d)
- Bug 1193075 - add viewport constraints for independent scrolling in tab sharing. r=smaug, r=jesup (f9243c0e97)
- bug 1221855 null-check mInputBuffer in SizeOfExcludingThis() r=padenot (d3cd52cfda)
- Bug 1193075 - make { scrollWithPage: false } not scroll with page. r=jesup (3f4aa04ba4)
- Bug 1212633 - include mobile and unfiled folders in Sync's concept of 'all IDs'. r=rnewman (908001a794)
- Bug 1217077 - Remove for-each from services/. r=gps (98a7a1d49d)
- Bug 1210573 - Add attribute 'packageIdentifier' to nsIPackagedAppUtils. r=valentin. (0115fa1b85)
- Bug 1178518 - Verify signed packages. r=valentin (5decf51ecb)
- Bug 1178518 - Add an AppTrustedRoot for signed packaged app. r=keeler (15e50605b4)
- Bug 1177013 - test_cpows.xul test for CPOW cancelation (r=dvander) (867c40bec1)
- Bug 1215167 - Forbid unsafe browser CPOWs (disabled by default for now) (r=mrbkap) (cee45a21b1)
- Bug 1174487. Stop using JS_ReportPendingException in ThrowAndReport. Just let the AutoJSAPI do the work for us. r=bholley (877d91b8ab)
- Bug 1213289 part 1. Change dom::Throw to take an XPCOM string, not a raw C string, for the message. r=bkelly (d15fbd30d5)
- Bug 1213289 part 2. Introduce ErrorResult::ClearUnionData and use it in various places where we're trying to do that. r=bkelly (c7e5dac146)
- Bug 1213289 part 3. Add a way to throw a DOMException with a custom message on ErrorResult. r=bkelly (aef71f28a9)
- Bug 1213289 part 4. Convert to using an enum for tracking our union state. r=bkelly (def36e74a1)
- Bug 1174593 - Null check context compartment in GetCurrentJSStack(). r=bholley (a785100a75)
- Bug 1216819 - Allow JSAPI SavedFrame accessors to skip past self-hosted frames. r=bz (e7c40f2c30)
- Bug 1200832 - make Console.trace follow async parents; r=baku,bgrins (9694111f6b)
- Bug 1218496 - Add MOZ_COUNT_CTOR/DTOR to ErrorResult::Message. r=bz (53ad08d1d3)
- Bug 1209107 - Only expose module environment object through testing functions r=shu (5fc969293e)
- Bug 930414 - Update module scope chain handling following addition of global lexical scope r=shu (1fc60942f1)
- fix typo (385064acb8)
- Bug 1215341 - Make assignment to const errors runtime TypeErrors in the frontend and interpreter. (r=jandem) (b1f959ad34)
- Bug 930414 - Implement module namespaces r=shu (8c78ae93f2)
- Bug 930414 - Make |this| undefined in modules r=shu (effe64e5ec)
- uBg 930414 - Replace |thisObject| object op with |thisValue| and use if for modules r=shu r=smaug (4875da587e)
- Bug 1125423 part 1 - Attach WindowProxies to globals instead of using innerObject/outerObject hooks. r=bz,luke (ae07ae6add)
- Bug 1125423 part 2 - Rename stopAtOuter argument to *Unwrap functionsto stopAtWindowProxy. r=bz (87334947c7)
- Bug 1125423 part 3 - Use IsWindow/IsWindowProxy functions instead of checking for Class hooks. r=bz (ec479123de)
- Bug 1219183 - Update comments that reference renamed thisObject hook r=shu (d99fd5f5a4)
- Bug 1125423 part 4 - Make GetThisValue infallible, stop invoking the Class hook. r=shu (7780fae25c)
- Bug 1125423 part 5 - Remove innerObject/outerObject/thisValue Class hooks. r=luke (e6798ba62f)
- Bug 1125423 part 6 - Remove nsGlobalWindow::OuterObject and ObjectToOuterObjectValue. r=bz (9c69c88ffc)
- Bug 1217061 - Report OOMs in IonCache::linkAndAttachStub(). r=djvj (6515dfc38f)
- Bug 1215573 - Remove AutoWritableJitCode from IonCache::updateBaseAddress. r=nbp (3b01574971)
- Bug 1209118 part 1 - Add id operand to MGetPropertyCache. r=efaust (d030b03035)
- Bug 1209118 part 2 - Fix GetPropertyIC stubs. r=efaust (3de861379e)
- Bug 1209118 part 3 - Move arguments element stub. r=efaust (90416752ec)
- Bug 1209118 part 4 - Move dense element stub. r=efaust (1c00927242)
- Bug 1209118 part 5 - Move dense element hole stub. r=efaust (888aeac645)
- Bug 1209118 part 6 - Move typed-or-unboxed element stub. r=efaust (1faf3c96eb)
- Bug 1209118 part 7 - Disable GetPropertyIC when the IC fails to attach stubs. r=efaust (ee29616d9e)
- Bug 1209118 part 8 - Use MGetPropertyCache for GETELEM. r=efaust (9ce7df2660)
- Bug 1209118 part 9 - rm MGetElementCache, GetElementIC. r=efaust (0c1747a8f8)
- Bug 1209118 part 10 - Fix a performance issue when disabling GetPropertyIC. r=efaust (c915688ed4)
- Bug 1209118 part 11 - Fix and simplify condition in GetPropertyIC::maybeDisable. r=efaust (051d4bc465)
- Bug 1214562 part 1 - SetElementCache no longer needs a byteop register on x86. r=bhackett (51353013a1)
- Bug 1214163 - Clean up SetPropertyIC::update. r=efaust (a520d092ac)
- Bug 1214562 part 2 - Refactor SetPropertyCache regalloc. r=bhackett (e7be5c651b)
- Bug 1216151 - Ensure the object has a non-lazy group in SetPropertyIC::tryAttachStub. r=efaust (205f6770cb)
- Bug 1213859 - Focus and blur events should not be cancelable; r=smaug (17e8f894d7)
- Bug 848569 - Replace DownloadsLogger with usage of ConsoleAPI. r=paolo (2ecc8e2c21)
- Bug 974718 - the download indicator stayhighlighted after "clear downloads" selected. r=paolo (4b44e45dd5)
- Bug 1146907 - Dismissing the unblock related dialog window unblocks the download. r=paolo (9fa551f5c2)
- mark done (19f3101048)
- Bug 1196047 - Move system.js to devtools/shared. r=jsantell (4c8ba36843)
- Bug 1197967 - preserve spelling of urls in output-parser.js; r=pbrosset (00395d373c)
- Bug 1146935 - StyleEditor: Respect the transition preference when a linked CSS file has changed on disk. r=bgrins (6b65ff1e0f)
- Bug 1206425 - Reorganize CodeMirror file structure for easier upgrades r=bgrins (95b5e26ce3)
- Bug 1132557 - Part 1: Upgrade to CodeMirror 5.7.0 r=bgrins * * * Bug 1132557 - Part 1: Update CodeMirror License r=bgrins * * * Bug 1132557 - Part 2: Upgrade existing addons to CodeMirror 5.7.0 r=bgrins * * * Bug 1132557 - Part 4: Upgrade existing CodeMirror keymap to 5.7.0 r=bgrins * * * Bug 1132557 - Part 5: Upgrade existing CodeMirror mode to 5.7.0 r=bgrins * * * Bug 1132557 - Part 6: Upgrade to CodeMirror 5.7.0 r=bgrins * * * Bug 1132557 - Part 7: Upgrade existing CodeMirror tests to 5.7.0 r=bgrins * * * Bug 1132557 - Part 13: Update CodeMirror README for version 5.7.0 r=bgrins (3435eae2d9)
- Bug 1132557 - Part 2: Apply fixes for CodeMirror 5.7.0 upgrade r=bgrins * * * Bug 1132557 - Part 3: Apply CodeMirror customization for search.js r=bgrins * * * Bug 1132557 - Part 8: Editor config option should be updated r=bgrins * * * Bug 1132557 - Part 9: Editor should emit a cursorActivity on setCursor r=bgrins * * * Bug 1132557 - Part 10: Make Debugger breadrumbs keyboard access test by refocusing the stack frame r=bgrins * * * Bug 1132557 - Part 11: Scratchpad should use capture on the paste event r=bgrins * * * Bug 1132557 - Part 12: Stylesheet Editor should always batch up updates r=bgrins (d4f8c2e49f)
- Bug 984880 - as-authored styles in the rule view; r=pbrosset,r=bgrins (6290c7c0e8)
- Bug 1170864 - Add xpcshell-tests for DevToolsUtils.fetch. r=past Bug 1196047 - Move indentation.js to devtools/shared. r=bgrins (21599da2d7)
- missing bits 1154809 (9516a51799)
- bit of Bug 1142194 - fix quoteString to correctly quote. r=pbrosset (4fb19f01f9)
- Bug 1195356 - make parseDeclarations handle comments; add rewriteDeclarations; r=pbrosset (5fdb22f57b)
- Bug 1195995 - merge css-tokenizer into css-parsing-utils; r=mratcliffe (8959b204f4)
- missing tests (bccf719441)
- Bug 1201949 - Initial redux-style controllers for front end memory tool heap snapshot. r=jlongster (cf2917e645)
- Bug 1196047 - Move async-storage.js to devtools/shared. r=bgrins (dc246d7891)
- Bug 1196047 - Move worker*.js to devtools/shared. r=jsantell (0d5f4d1aec)
- Bug 1196047 - Move most of shared/performance to client or server. r=jsantell (11cd58015a)
- Bug 1196047 - Move shared/shared perf files to server/performance. r=jsantell (9b4348afd2)
- Bug 1196047 - Move tern to client/sourceeditor. r=bgrins (82b81726d3)
567 lines
19 KiB
JavaScript
567 lines
19 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
"use strict";
|
|
|
|
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
|
const { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
|
|
|
|
const { Task } = require("resource://gre/modules/Task.jsm");
|
|
const { Heritage, ViewHelpers, WidgetMethods } = require("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
|
|
|
|
// Events emitted by various objects in the panel.
|
|
const EVENTS = require("devtools/client/performance/events");
|
|
|
|
loader.lazyRequireGetter(this, "Services");
|
|
loader.lazyRequireGetter(this, "promise");
|
|
loader.lazyRequireGetter(this, "EventEmitter",
|
|
"devtools/shared/event-emitter");
|
|
loader.lazyRequireGetter(this, "DevToolsUtils",
|
|
"devtools/shared/DevToolsUtils");
|
|
loader.lazyRequireGetter(this, "system",
|
|
"devtools/shared/system");
|
|
|
|
// Logic modules
|
|
|
|
loader.lazyRequireGetter(this, "L10N",
|
|
"devtools/client/performance/modules/global", true);
|
|
loader.lazyRequireGetter(this, "PerformanceTelemetry",
|
|
"devtools/client/performance/modules/logic/telemetry", true);
|
|
loader.lazyRequireGetter(this, "TIMELINE_BLUEPRINT",
|
|
"devtools/client/performance/modules/markers", true);
|
|
loader.lazyRequireGetter(this, "RecordingUtils",
|
|
"devtools/shared/performance/recording-utils");
|
|
loader.lazyRequireGetter(this, "GraphsController",
|
|
"devtools/client/performance/modules/widgets/graphs", true);
|
|
loader.lazyRequireGetter(this, "OptimizationsGraph",
|
|
"devtools/client/performance/modules/widgets/graphs", true);
|
|
loader.lazyRequireGetter(this, "WaterfallHeader",
|
|
"devtools/client/performance/modules/widgets/waterfall-ticks", true);
|
|
loader.lazyRequireGetter(this, "MarkerView",
|
|
"devtools/client/performance/modules/widgets/marker-view", true);
|
|
loader.lazyRequireGetter(this, "MarkerDetails",
|
|
"devtools/client/performance/modules/widgets/marker-details", true);
|
|
loader.lazyRequireGetter(this, "MarkerUtils",
|
|
"devtools/client/performance/modules/logic/marker-utils");
|
|
loader.lazyRequireGetter(this, "WaterfallUtils",
|
|
"devtools/client/performance/modules/logic/waterfall-utils");
|
|
loader.lazyRequireGetter(this, "FrameUtils",
|
|
"devtools/client/performance/modules/logic/frame-utils");
|
|
loader.lazyRequireGetter(this, "CallView",
|
|
"devtools/client/performance/modules/widgets/tree-view", true);
|
|
loader.lazyRequireGetter(this, "ThreadNode",
|
|
"devtools/client/performance/modules/logic/tree-model", true);
|
|
loader.lazyRequireGetter(this, "FrameNode",
|
|
"devtools/client/performance/modules/logic/tree-model", true);
|
|
loader.lazyRequireGetter(this, "JITOptimizations",
|
|
"devtools/client/performance/modules/logic/jit", true);
|
|
|
|
// Widgets modules
|
|
|
|
loader.lazyRequireGetter(this, "OptionsView",
|
|
"devtools/client/shared/options-view", true);
|
|
loader.lazyRequireGetter(this, "FlameGraphUtils",
|
|
"devtools/client/shared/widgets/FlameGraph", true);
|
|
loader.lazyRequireGetter(this, "FlameGraph",
|
|
"devtools/client/shared/widgets/FlameGraph", true);
|
|
loader.lazyRequireGetter(this, "TreeWidget",
|
|
"devtools/client/shared/widgets/TreeWidget", true);
|
|
|
|
loader.lazyImporter(this, "SideMenuWidget",
|
|
"resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
|
|
loader.lazyImporter(this, "setNamedTimeout",
|
|
"resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
|
|
loader.lazyImporter(this, "clearNamedTimeout",
|
|
"resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
|
|
loader.lazyImporter(this, "PluralForm",
|
|
"resource://gre/modules/PluralForm.jsm");
|
|
|
|
const BRANCH_NAME = "devtools.performance.ui.";
|
|
|
|
/**
|
|
* The current target, toolbox and PerformanceFront, set by this tool's host.
|
|
*/
|
|
var gToolbox, gTarget, gFront;
|
|
|
|
/**
|
|
* Initializes the profiler controller and views.
|
|
*/
|
|
var startupPerformance = Task.async(function*() {
|
|
yield PerformanceController.initialize();
|
|
yield PerformanceView.initialize();
|
|
});
|
|
|
|
/**
|
|
* Destroys the profiler controller and views.
|
|
*/
|
|
var shutdownPerformance = Task.async(function*() {
|
|
yield PerformanceController.destroy();
|
|
yield PerformanceView.destroy();
|
|
});
|
|
|
|
/**
|
|
* Functions handling target-related lifetime events and
|
|
* UI interaction.
|
|
*/
|
|
var PerformanceController = {
|
|
_recordings: [],
|
|
_currentRecording: null,
|
|
|
|
/**
|
|
* Listen for events emitted by the current tab target and
|
|
* main UI events.
|
|
*/
|
|
initialize: Task.async(function* () {
|
|
this._telemetry = new PerformanceTelemetry(this);
|
|
this.startRecording = this.startRecording.bind(this);
|
|
this.stopRecording = this.stopRecording.bind(this);
|
|
this.importRecording = this.importRecording.bind(this);
|
|
this.exportRecording = this.exportRecording.bind(this);
|
|
this.clearRecordings = this.clearRecordings.bind(this);
|
|
this._onRecordingSelectFromView = this._onRecordingSelectFromView.bind(this);
|
|
this._onPrefChanged = this._onPrefChanged.bind(this);
|
|
this._onThemeChanged = this._onThemeChanged.bind(this);
|
|
this._onFrontEvent = this._onFrontEvent.bind(this);
|
|
this._pipe = this._pipe.bind(this);
|
|
|
|
// Store data regarding if e10s is enabled.
|
|
this._e10s = Services.appinfo.browserTabsRemoteAutostart;
|
|
this._setMultiprocessAttributes();
|
|
|
|
this._prefs = require("devtools/client/performance/modules/global").PREFS;
|
|
this._prefs.on("pref-changed", this._onPrefChanged);
|
|
|
|
gFront.on("*", this._onFrontEvent);
|
|
ToolbarView.on(EVENTS.PREF_CHANGED, this._onPrefChanged);
|
|
PerformanceView.on(EVENTS.UI_START_RECORDING, this.startRecording);
|
|
PerformanceView.on(EVENTS.UI_STOP_RECORDING, this.stopRecording);
|
|
PerformanceView.on(EVENTS.UI_IMPORT_RECORDING, this.importRecording);
|
|
PerformanceView.on(EVENTS.UI_CLEAR_RECORDINGS, this.clearRecordings);
|
|
RecordingsView.on(EVENTS.UI_EXPORT_RECORDING, this.exportRecording);
|
|
RecordingsView.on(EVENTS.RECORDING_SELECTED, this._onRecordingSelectFromView);
|
|
DetailsView.on(EVENTS.DETAILS_VIEW_SELECTED, this._pipe);
|
|
|
|
gDevTools.on("pref-changed", this._onThemeChanged);
|
|
}),
|
|
|
|
/**
|
|
* Remove events handled by the PerformanceController
|
|
*/
|
|
destroy: function() {
|
|
this._telemetry.destroy();
|
|
this._prefs.off("pref-changed", this._onPrefChanged);
|
|
|
|
gFront.off("*", this._onFrontEvent);
|
|
ToolbarView.off(EVENTS.PREF_CHANGED, this._onPrefChanged);
|
|
PerformanceView.off(EVENTS.UI_START_RECORDING, this.startRecording);
|
|
PerformanceView.off(EVENTS.UI_STOP_RECORDING, this.stopRecording);
|
|
PerformanceView.off(EVENTS.UI_IMPORT_RECORDING, this.importRecording);
|
|
PerformanceView.off(EVENTS.UI_CLEAR_RECORDINGS, this.clearRecordings);
|
|
RecordingsView.off(EVENTS.UI_EXPORT_RECORDING, this.exportRecording);
|
|
RecordingsView.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelectFromView);
|
|
DetailsView.off(EVENTS.DETAILS_VIEW_SELECTED, this._pipe);
|
|
|
|
gDevTools.off("pref-changed", this._onThemeChanged);
|
|
},
|
|
|
|
/**
|
|
* Returns the current devtools theme.
|
|
*/
|
|
getTheme: function () {
|
|
return Services.prefs.getCharPref("devtools.theme");
|
|
},
|
|
|
|
/**
|
|
* Get a boolean preference setting from `prefName` via the underlying
|
|
* OptionsView in the ToolbarView. This preference is guaranteed to be
|
|
* displayed in the UI.
|
|
*
|
|
* @param string prefName
|
|
* @return boolean
|
|
*/
|
|
getOption: function (prefName) {
|
|
return ToolbarView.optionsView.getPref(prefName);
|
|
},
|
|
|
|
/**
|
|
* Get a preference setting from `prefName`. This preference can be of
|
|
* any type and might not be displayed in the UI.
|
|
*
|
|
* @param string prefName
|
|
* @return any
|
|
*/
|
|
getPref: function (prefName) {
|
|
return this._prefs[prefName];
|
|
},
|
|
|
|
/**
|
|
* Set a preference setting from `prefName`. This preference can be of
|
|
* any type and might not be displayed in the UI.
|
|
*
|
|
* @param string prefName
|
|
* @param any prefValue
|
|
*/
|
|
setPref: function (prefName, prefValue) {
|
|
this._prefs[prefName] = prefValue;
|
|
},
|
|
|
|
/**
|
|
* Starts recording with the PerformanceFront.
|
|
*/
|
|
startRecording: Task.async(function *() {
|
|
let options = {
|
|
withMarkers: true,
|
|
withMemory: this.getOption("enable-memory"),
|
|
withTicks: this.getOption("enable-framerate"),
|
|
withJITOptimizations: this.getOption("enable-jit-optimizations"),
|
|
withAllocations: this.getOption("enable-allocations"),
|
|
allocationsSampleProbability: this.getPref("memory-sample-probability"),
|
|
allocationsMaxLogLength: this.getPref("memory-max-log-length"),
|
|
bufferSize: this.getPref("profiler-buffer-size"),
|
|
sampleFrequency: this.getPref("profiler-sample-frequency")
|
|
};
|
|
|
|
yield gFront.startRecording(options);
|
|
}),
|
|
|
|
/**
|
|
* Stops recording with the PerformanceFront.
|
|
*/
|
|
stopRecording: Task.async(function *() {
|
|
let recording = this.getLatestManualRecording();
|
|
yield gFront.stopRecording(recording);
|
|
|
|
// Emit another stop event here, as a lot of tests use
|
|
// the RECORDING_STOPPED event, but in the case of a UI click on a button,
|
|
// the RECORDING_STOPPED event happens from the server, where this request may
|
|
// not have yet finished, so listen to this in tests that fail because the `stopRecording`
|
|
// request is not yet completed. Should only be used in that scenario.
|
|
this.emit(EVENTS.CONTROLLER_STOPPED_RECORDING);
|
|
}),
|
|
|
|
/**
|
|
* Saves the given recording to a file. Emits `EVENTS.RECORDING_EXPORTED`
|
|
* when the file was saved.
|
|
*
|
|
* @param PerformanceRecording recording
|
|
* The model that holds the recording data.
|
|
* @param nsILocalFile file
|
|
* The file to stream the data into.
|
|
*/
|
|
exportRecording: Task.async(function*(_, recording, file) {
|
|
yield recording.exportRecording(file);
|
|
this.emit(EVENTS.RECORDING_EXPORTED, recording, file);
|
|
}),
|
|
|
|
/**
|
|
* Clears all recordings from the list as well as the current recording.
|
|
* Emits `EVENTS.RECORDINGS_CLEARED` when complete so other components can clean up.
|
|
*/
|
|
clearRecordings: Task.async(function* () {
|
|
let latest = this.getLatestManualRecording();
|
|
if (latest && latest.isRecording()) {
|
|
yield this.stopRecording();
|
|
}
|
|
// If last recording is not recording, but finalizing itself,
|
|
// wait for that to finish
|
|
if (latest && !latest.isCompleted()) {
|
|
yield this.waitForStateChangeOnRecording(latest, "recording-stopped");
|
|
}
|
|
|
|
this._recordings.length = 0;
|
|
this.setCurrentRecording(null);
|
|
this.emit(EVENTS.RECORDINGS_CLEARED);
|
|
}),
|
|
|
|
/**
|
|
* Loads a recording from a file, adding it to the recordings list. Emits
|
|
* `EVENTS.RECORDING_IMPORTED` when the file was loaded.
|
|
*
|
|
* @param nsILocalFile file
|
|
* The file to import the data from.
|
|
*/
|
|
importRecording: Task.async(function*(_, file) {
|
|
let recording = yield gFront.importRecording(file);
|
|
this._addNewRecording(recording);
|
|
|
|
this.emit(EVENTS.RECORDING_IMPORTED, recording);
|
|
}),
|
|
|
|
/**
|
|
* Sets the currently active PerformanceRecording. Should rarely be called directly,
|
|
* as RecordingsView handles this when manually selected a recording item. Exceptions
|
|
* are when clearing the view.
|
|
* @param PerformanceRecording recording
|
|
*/
|
|
setCurrentRecording: function (recording) {
|
|
if (this._currentRecording !== recording) {
|
|
this._currentRecording = recording;
|
|
this.emit(EVENTS.RECORDING_SELECTED, recording);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Gets the currently active PerformanceRecording.
|
|
* @return PerformanceRecording
|
|
*/
|
|
getCurrentRecording: function () {
|
|
return this._currentRecording;
|
|
},
|
|
|
|
/**
|
|
* Get most recently added recording that was triggered manually (via UI).
|
|
* @return PerformanceRecording
|
|
*/
|
|
getLatestManualRecording: function () {
|
|
for (let i = this._recordings.length - 1; i >= 0; i--) {
|
|
let model = this._recordings[i];
|
|
if (!model.isConsole() && !model.isImported()) {
|
|
return this._recordings[i];
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Fired from RecordingsView, we listen on the PerformanceController so we can
|
|
* set it here and re-emit on the controller, where all views can listen.
|
|
*/
|
|
_onRecordingSelectFromView: function (_, recording) {
|
|
this.setCurrentRecording(recording);
|
|
},
|
|
|
|
/**
|
|
* Fired when the ToolbarView fires a PREF_CHANGED event.
|
|
* with the value.
|
|
*/
|
|
_onPrefChanged: function (_, prefName, prefValue) {
|
|
this.emit(EVENTS.PREF_CHANGED, prefName, prefValue);
|
|
},
|
|
|
|
/*
|
|
* Called when the developer tools theme changes.
|
|
*/
|
|
_onThemeChanged: function (_, data) {
|
|
// Right now, gDevTools only emits `pref-changed` for the theme,
|
|
// but this could change in the future.
|
|
if (data.pref !== "devtools.theme") {
|
|
return;
|
|
}
|
|
|
|
this.emit(EVENTS.THEME_CHANGED, data.newValue);
|
|
},
|
|
|
|
/**
|
|
* Fired from the front on any event. Propagates to other handlers from here.
|
|
*/
|
|
_onFrontEvent: function (eventName, ...data) {
|
|
if (eventName === "profiler-status") {
|
|
this._onProfilerStatusUpdated(...data);
|
|
return;
|
|
}
|
|
|
|
if (["recording-started", "recording-stopped", "recording-stopping"].indexOf(eventName) !== -1) {
|
|
this._onRecordingStateChange(eventName, ...data);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Emitted when the front updates PerformanceRecording's buffer status.
|
|
*/
|
|
_onProfilerStatusUpdated: function (data) {
|
|
this.emit(EVENTS.PROFILER_STATUS_UPDATED, data);
|
|
},
|
|
|
|
/**
|
|
* Stores a recording internally.
|
|
*
|
|
* @param {PerformanceRecordingFront} recording
|
|
*/
|
|
_addNewRecording: function (recording) {
|
|
if (this._recordings.indexOf(recording) === -1) {
|
|
this._recordings.push(recording);
|
|
this.emit(EVENTS.NEW_RECORDING, recording);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Fired when a recording model changes state.
|
|
*
|
|
* @param {string} state
|
|
* Can be "recording-started", "recording-stopped" or "recording-stopping".
|
|
* @param {PerformanceRecording} model
|
|
*/
|
|
_onRecordingStateChange: function (state, model) {
|
|
this._addNewRecording(model);
|
|
|
|
this.emit(EVENTS.RECORDING_STATE_CHANGE, state, model);
|
|
|
|
// Emit the state specific events for tests that I'm too
|
|
// lazy and frusterated to change right now. These events
|
|
// should only be used in tests and specific rare cases (telemetry),
|
|
// as the rest of the UI should react to general RECORDING_STATE_CHANGE
|
|
// events and NEW_RECORDING events to handle lazy recordings.
|
|
switch (state) {
|
|
case "recording-started":
|
|
this.emit(EVENTS.RECORDING_STARTED, model);
|
|
break;
|
|
case "recording-stopping":
|
|
this.emit(EVENTS.RECORDING_WILL_STOP, model);
|
|
break;
|
|
case "recording-stopped":
|
|
this.emit(EVENTS.RECORDING_STOPPED, model);
|
|
break;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Takes a recording and returns a value between 0 and 1 indicating how much
|
|
* of the buffer is used.
|
|
*/
|
|
getBufferUsageForRecording: function (recording) {
|
|
return gFront.getBufferUsageForRecording(recording);
|
|
},
|
|
|
|
/**
|
|
* Returns a boolean indicating if any recordings are currently in progress or not.
|
|
*/
|
|
isRecording: function () {
|
|
return this._recordings.some(r => r.isRecording());
|
|
},
|
|
|
|
/**
|
|
* Returns the internal store of recording models.
|
|
*/
|
|
getRecordings: function () {
|
|
return this._recordings;
|
|
},
|
|
|
|
/**
|
|
* Returns traits from the front.
|
|
*/
|
|
getTraits: function () {
|
|
return gFront.traits;
|
|
},
|
|
|
|
/**
|
|
* Utility method taking a string or an array of strings of feature names (like
|
|
* "withAllocations" or "withMarkers"), and returns whether or not the current
|
|
* recording supports that feature, based off of UI preferences and server support.
|
|
*
|
|
* @option {Array<string>|string} features
|
|
* A string or array of strings indicating what configuration is needed on the recording
|
|
* model, like `withTicks`, or `withMemory`.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
isFeatureSupported: function (features) {
|
|
if (!features) {
|
|
return true;
|
|
}
|
|
|
|
let recording = this.getCurrentRecording();
|
|
if (!recording) {
|
|
return false;
|
|
}
|
|
|
|
let config = recording.getConfiguration();
|
|
return [].concat(features).every(f => config[f]);
|
|
},
|
|
|
|
/**
|
|
* Takes an array of PerformanceRecordingFronts and adds them to the internal
|
|
* store of the UI. Used by the toolbox to lazily seed recordings that
|
|
* were observed before the panel was loaded in the scenario where `console.profile()`
|
|
* is used before the tool is loaded.
|
|
*
|
|
* @param {Array<PerformanceRecordingFront>} recordings
|
|
*/
|
|
populateWithRecordings: function (recordings=[]) {
|
|
for (let recording of recordings) {
|
|
PerformanceController._addNewRecording(recording);
|
|
}
|
|
this.emit(EVENTS.RECORDINGS_SEEDED);
|
|
},
|
|
|
|
/**
|
|
* Returns an object with `supported` and `enabled` properties indicating
|
|
* whether or not the platform is capable of turning on e10s and whether or not
|
|
* it's already enabled, respectively.
|
|
*
|
|
* @return {object}
|
|
*/
|
|
getMultiprocessStatus: function () {
|
|
// If testing, set both supported and enabled to true so we
|
|
// have realtime rendering tests in non-e10s. This function is
|
|
// overridden wholesale in tests when we want to test multiprocess support
|
|
// specifically.
|
|
if (DevToolsUtils.testing) {
|
|
return { supported: true, enabled: true };
|
|
}
|
|
let supported = system.constants.E10S_TESTING_ONLY;
|
|
// This is only checked on tool startup -- requires a restart if
|
|
// e10s subsequently enabled.
|
|
let enabled = this._e10s;
|
|
return { supported, enabled };
|
|
},
|
|
|
|
/**
|
|
* Takes a PerformanceRecording and a state, and waits for
|
|
* the event to be emitted from the front for that recording.
|
|
*
|
|
* @param {PerformanceRecordingFront} recording
|
|
* @param {string} expectedState
|
|
* @return {Promise}
|
|
*/
|
|
waitForStateChangeOnRecording: Task.async(function *(recording, expectedState) {
|
|
let deferred = promise.defer();
|
|
this.on(EVENTS.RECORDING_STATE_CHANGE, function handler (state, model) {
|
|
if (state === expectedState && model === recording) {
|
|
this.off(EVENTS.RECORDING_STATE_CHANGE, handler);
|
|
deferred.resolve();
|
|
}
|
|
});
|
|
yield deferred.promise;
|
|
}),
|
|
|
|
/**
|
|
* Called on init, sets an `e10s` attribute on the main view container with
|
|
* "disabled" if e10s is possible on the platform and just not on, or "unsupported"
|
|
* if e10s is not possible on the platform. If e10s is on, no attribute is set.
|
|
*/
|
|
_setMultiprocessAttributes: function () {
|
|
let { enabled, supported } = this.getMultiprocessStatus();
|
|
if (!enabled && supported) {
|
|
$("#performance-view").setAttribute("e10s", "disabled");
|
|
}
|
|
// Could be a chance where the directive goes away yet e10s is still on
|
|
else if (!enabled && !supported) {
|
|
$("#performance-view").setAttribute("e10s", "unsupported");
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Pipes an event from some source to the PerformanceController.
|
|
*/
|
|
_pipe: function (eventName, ...data) {
|
|
this.emit(eventName, ...data);
|
|
},
|
|
|
|
toString: () => "[object PerformanceController]"
|
|
};
|
|
|
|
/**
|
|
* Convenient way of emitting events from the controller.
|
|
*/
|
|
EventEmitter.decorate(PerformanceController);
|
|
|
|
/**
|
|
* DOM query helpers.
|
|
*/
|
|
function $(selector, target = document) {
|
|
return target.querySelector(selector);
|
|
}
|
|
function $$(selector, target = document) {
|
|
return target.querySelectorAll(selector);
|
|
}
|