зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1482091) for bc failures on browser_domFullscreen_fullscreenMode.js
Backed out changeset bc03f101937e (bug 1482091) Backed out changeset 28a19b7290ab (bug 1482091)
This commit is contained in:
Родитель
b42b0470a1
Коммит
0c81738411
|
@ -64,6 +64,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
SitePermissions: "resource:///modules/SitePermissions.jsm",
|
||||
TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
|
||||
TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
Translation: "resource:///modules/translation/Translation.jsm",
|
||||
UITour: "resource:///modules/UITour.jsm",
|
||||
UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
|
||||
|
|
|
@ -82,6 +82,7 @@ const intermittently_loaded_whitelist = {
|
|||
]),
|
||||
modules: new Set([
|
||||
"resource://gre/modules/sessionstore/Utils.jsm",
|
||||
"resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
]),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
// This test tends to trigger a race in the fullscreen time telemetry,
|
||||
// where the fullscreen enter and fullscreen exit events (which use the
|
||||
// same histogram ID) overlap. That causes TelemetryStopwatch to log an
|
||||
// error.
|
||||
SimpleTest.ignoreAllUncaughtExceptions(true);
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/AppMenuNotifications.jsm");
|
||||
|
||||
function waitForDocshellActivated() {
|
||||
|
|
|
@ -28,6 +28,8 @@ ChromeUtils.defineModuleGetter(this, "ResponsivenessMonitor",
|
|||
"resource://gre/modules/ResponsivenessMonitor.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Sqlite",
|
||||
"resource://gre/modules/Sqlite.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
|
||||
"resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "WindowsRegistry",
|
||||
"resource://gre/modules/WindowsRegistry.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "setTimeout",
|
||||
|
|
|
@ -20,6 +20,8 @@ XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesControll
|
|||
"chrome://browser/content/places/controller.js");
|
||||
/* End Shared Places Import */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
||||
var gHistoryTree;
|
||||
var gSearchBox;
|
||||
var gHistoryGrouping = "";
|
||||
|
|
|
@ -24,6 +24,7 @@ XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesControll
|
|||
/* End Shared Places Import */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "MigrationUtils",
|
||||
"resource:///modules/MigrationUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "BookmarkJSONUtils",
|
||||
|
|
|
@ -10,6 +10,9 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
|||
ChromeUtils.import("resource://gre/modules/Timer.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
|
||||
"resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
||||
function debug(msg) {
|
||||
Services.console.logStringMessage("SessionStoreContent: " + msg);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ var EXPORTED_SYMBOLS = ["SessionSaver"];
|
|||
ChromeUtils.import("resource://gre/modules/Timer.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
|
|
|
@ -156,6 +156,7 @@ const RESTORE_TAB_CONTENT_REASON = {
|
|||
|
||||
ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryTimestamps.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/Timer.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
|
|
|
@ -11,6 +11,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "gTabWarmingEnabled",
|
||||
|
|
|
@ -12,6 +12,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
|
||||
FormHistory: "resource://gre/modules/FormHistory.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
|
||||
});
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
var EXPORTED_SYMBOLS = ["SchedulePressure"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
|
||||
"resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "SCHEDULE_PRESSURE_ENABLED",
|
||||
"browser.schedulePressure.enabled", true);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "TIMEOUT_AMOUNT",
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const TelemetryStopwatch = require("TelemetryStopwatch");
|
||||
const { TelemetryStopwatch } = require("resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
const { getNthPathExcluding } = require("devtools/shared/platform/stack");
|
||||
const { TelemetryEnvironment } = require("resource://gre/modules/TelemetryEnvironment.jsm");
|
||||
const WeakMapMap = require("devtools/client/shared/WeakMapMap");
|
||||
|
|
|
@ -22,7 +22,6 @@ const {
|
|||
console,
|
||||
HeapSnapshot,
|
||||
StructuredCloneHolder,
|
||||
TelemetryStopwatch,
|
||||
} = Cu.getGlobalForObject(jsmScope);
|
||||
|
||||
// Create a single Sandbox to access global properties needed in this module.
|
||||
|
@ -219,7 +218,6 @@ exports.modules = {
|
|||
// pull it is destroyed. See bug 1402779.
|
||||
Promise,
|
||||
Services: Object.create(Services),
|
||||
TelemetryStopwatch,
|
||||
};
|
||||
|
||||
defineLazyGetter(exports.modules, "Debugger", () => {
|
||||
|
|
|
@ -1016,10 +1016,6 @@ DOMInterfaces = {
|
|||
'concrete': False,
|
||||
},
|
||||
|
||||
'TelemetryStopwatch': {
|
||||
'nativeType': 'mozilla::telemetry::Stopwatch',
|
||||
},
|
||||
|
||||
'TestFunctions': {
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
|
|
@ -1,238 +0,0 @@
|
|||
/* 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/.
|
||||
*/
|
||||
|
||||
typedef DOMString HistogramID;
|
||||
typedef DOMString HistogramKey;
|
||||
|
||||
[ChromeOnly, Exposed=Window]
|
||||
namespace TelemetryStopwatch {
|
||||
/**
|
||||
* Starts a timer associated with a telemetry histogram. The timer can be
|
||||
* directly associated with a histogram, or with a pair of a histogram and
|
||||
* an object.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently, as long as they are associated with
|
||||
* different objects.
|
||||
* @param [options.inSeconds=false] - record elapsed time for this
|
||||
* histogram in seconds instead of milliseconds. Defaults to
|
||||
* false.
|
||||
*
|
||||
* @returns True if the timer was successfully started, false
|
||||
* otherwise. If a timer already exists, it can't be
|
||||
* started again, and the existing one will be cleared in
|
||||
* order to avoid measurements errors.
|
||||
*/
|
||||
boolean start(HistogramID histogram, optional object? obj = null,
|
||||
optional TelemetryStopwatchOptions options);
|
||||
|
||||
/**
|
||||
* Returns whether a timer associated with a telemetry histogram is currently
|
||||
* running. The timer can be directly associated with a histogram, or with a
|
||||
* pair of a histogram and an object.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently, as long as they are associated with
|
||||
* different objects.
|
||||
*
|
||||
* @returns True if the timer exists and is currently running.
|
||||
*/
|
||||
boolean running(HistogramID histogram, optional object? obj = null);
|
||||
|
||||
/**
|
||||
* Deletes the timer associated with a telemetry histogram. The timer can be
|
||||
* directly associated with a histogram, or with a pair of a histogram and
|
||||
* an object. Important: Only use this method when a legitimate cancellation
|
||||
* should be done.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers or a same histogram may be run concurrently,
|
||||
* as long as they are associated with different
|
||||
* objects.
|
||||
*
|
||||
* @returns True if the timer exist and it was cleared, False
|
||||
* otherwise.
|
||||
*/
|
||||
boolean cancel(HistogramID histogram, optional object? obj = null);
|
||||
|
||||
/**
|
||||
* Returns the elapsed time for a particular stopwatch. Primarily for
|
||||
* debugging purposes. Must be called prior to finish.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
* if an invalid name is given, the function will
|
||||
* throw.
|
||||
*
|
||||
* @param obj - Optional parameter which associates the histogram
|
||||
* timer with the given object.
|
||||
*
|
||||
* @param canceledOkay - Optional parameter which will suppress any
|
||||
* warnings that normally fire when a stopwatch
|
||||
* is finished after being cancelled. Defaults
|
||||
* to false.
|
||||
*
|
||||
* @returns Time in milliseconds or -1 if the stopwatch was not
|
||||
* found.
|
||||
*/
|
||||
long timeElapsed(HistogramID histogram,
|
||||
optional object? obj = null,
|
||||
optional boolean canceledOkay = false);
|
||||
|
||||
/**
|
||||
* Stops the timer associated with the given histogram (and object),
|
||||
* calculates the time delta between start and finish, and adds the value
|
||||
* to the histogram.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param obj - Optional parameter which associates the histogram
|
||||
* timer with the given object.
|
||||
*
|
||||
* @param canceledOkay - Optional parameter which will suppress any
|
||||
* warnings that normally fire when a stopwatch
|
||||
* is finished after being cancelled. Defaults
|
||||
* to false.
|
||||
*
|
||||
* @returns True if the timer was succesfully stopped and the data
|
||||
* was added to the histogram, false otherwise.
|
||||
*/
|
||||
boolean finish(HistogramID histogram,
|
||||
optional object? obj = null,
|
||||
optional boolean canceledOkay = false);
|
||||
|
||||
/**
|
||||
* Starts a timer associated with a keyed telemetry histogram. The timer can
|
||||
* be directly associated with a histogram and its key. Similarly to
|
||||
* @see{TelemetryStopwatch.start} the histogram and its key can be associated
|
||||
* with an object. Each key may have multiple associated objects and each
|
||||
* object can be associated with multiple keys.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param key - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently,as long as they are associated with
|
||||
* different objects.
|
||||
* @param [options.inSeconds=false] - record elapsed time for this
|
||||
* histogram in seconds instead of milliseconds. Defaults to
|
||||
* false.
|
||||
*
|
||||
* @returns True if the timer was successfully started, false
|
||||
* otherwise. If a timer already exists, it can't be
|
||||
* started again, and the existing one will be cleared in
|
||||
* order to avoid measurements errors.
|
||||
*/
|
||||
boolean startKeyed(HistogramID histogram, HistogramKey key,
|
||||
optional object? obj = null,
|
||||
optional TelemetryStopwatchOptions options);
|
||||
|
||||
/**
|
||||
* Returns whether a timer associated with a telemetry histogram is currently
|
||||
* running. Similarly to @see{TelemetryStopwatch.running} the timer and its
|
||||
* key can be associated with an object. Each key may have multiple associated
|
||||
* objects and each object can be associated with multiple keys.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param key - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently, as long as they are associated with
|
||||
* different objects.
|
||||
*
|
||||
* @returns True if the timer exists and is currently running.
|
||||
*/
|
||||
boolean runningKeyed(HistogramID histogram, HistogramKey key,
|
||||
optional object? obj = null);
|
||||
|
||||
/**
|
||||
* Deletes the timer associated with a keyed histogram. Important: Only use
|
||||
* this method when a legitimate cancellation should be done.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param key - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer
|
||||
* associated with this object is deleted.
|
||||
*
|
||||
* @returns True if the timer exist and it was cleared, False
|
||||
* otherwise.
|
||||
*/
|
||||
boolean cancelKeyed(HistogramID histogram, HistogramKey key,
|
||||
optional object? obj = null);
|
||||
|
||||
/**
|
||||
* Returns the elapsed time for a particular stopwatch. Primarily for
|
||||
* debugging purposes. Cannot be called after finish().
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param key - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param obj - Optional parameter. If specified, the timer
|
||||
* associated with this object is used to calculate
|
||||
* the elapsed time.
|
||||
*
|
||||
* @returns Time in milliseconds or -1 if the stopwatch was not
|
||||
* found.
|
||||
*/
|
||||
long timeElapsedKeyed(HistogramID histogram, HistogramKey key,
|
||||
optional object? obj = null,
|
||||
optional boolean canceledOkay = false);
|
||||
|
||||
/**
|
||||
* Stops the timer associated with the given keyed histogram (and object),
|
||||
* calculates the time delta between start and finish, and adds the value
|
||||
* to the keyed histogram.
|
||||
*
|
||||
* @param histogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param key - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param obj - optional parameter which associates the histogram
|
||||
* timer with the given object.
|
||||
*
|
||||
* @param canceledOkay - Optional parameter which will suppress any
|
||||
* warnings that normally fire when a stopwatch
|
||||
* is finished after being cancelled. Defaults
|
||||
* to false.
|
||||
*
|
||||
* @returns True if the timer was succesfully stopped and the data
|
||||
* was added to the histogram, false otherwise.
|
||||
*/
|
||||
boolean finishKeyed(HistogramID histogram, HistogramKey key,
|
||||
optional object? obj = null,
|
||||
optional boolean canceledOkay = false);
|
||||
|
||||
/**
|
||||
* Set the testing mode. Used by tests.
|
||||
*/
|
||||
void setTestModeEnabled(optional boolean testing = true);
|
||||
};
|
||||
|
||||
dictionary TelemetryStopwatchOptions {
|
||||
/**
|
||||
* If true, record elapsed time for this histogram in seconds instead of
|
||||
* milliseconds.
|
||||
*/
|
||||
boolean inSeconds = false;
|
||||
};
|
|
@ -51,7 +51,6 @@ WEBIDL_FILES = [
|
|||
'PrecompiledScript.webidl',
|
||||
'PromiseDebugging.webidl',
|
||||
'StructuredCloneHolder.webidl',
|
||||
'TelemetryStopwatch.webidl',
|
||||
'WebExtensionContentScript.webidl',
|
||||
'WebExtensionPolicy.webidl',
|
||||
'XULFrameElement.webidl',
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
// This test tends to trigger a race in the fullscreen time telemetry,
|
||||
// where the fullscreen enter and fullscreen exit events (which use the
|
||||
// same histogram ID) overlap. That causes TelemetryStopwatch to log an
|
||||
// error.
|
||||
SimpleTest.ignoreAllUncaughtExceptions(true);
|
||||
|
||||
const kPage = "http://example.org/browser/" +
|
||||
"dom/html/test/file_fullscreen-newtab.html";
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
ChromeUtils.import("resource://services-common/utils.js"); /* global: CommonUtils */
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(window, "gChromeWin", () =>
|
||||
window.docShell.rootTreeItem.domWindow
|
||||
|
|
|
@ -105,6 +105,8 @@ ChromeUtils.defineModuleGetter(this, "RuntimePermissions", "resource://gre/modul
|
|||
|
||||
ChromeUtils.defineModuleGetter(this, "WebsiteMetadata", "resource://gre/modules/WebsiteMetadata.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "FontEnumerator",
|
||||
"@mozilla.org/gfx/fontenumerator;1",
|
||||
"nsIFontEnumerator");
|
||||
|
|
|
@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.jsm",
|
||||
SharedPreferences: "resource://gre/modules/SharedPreferences.jsm",
|
||||
Task: "resource://gre/modules/Task.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
Utils: "resource://gre/modules/sessionstore/Utils.jsm",
|
||||
});
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
OS: "resource://gre/modules/osfile.jsm",
|
||||
ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
|
||||
Task: "resource://gre/modules/Task.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetters(this, {
|
||||
|
|
|
@ -9,6 +9,8 @@ var EXPORTED_SYMBOLS = ["ExtensionTelemetry", "getTrimmedString"];
|
|||
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
|
||||
"resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
||||
// Map of the base histogram ids for the metrics recorded for the extensions.
|
||||
const histograms = {
|
||||
|
|
|
@ -8,6 +8,7 @@ ChromeUtils.import("resource://gre/modules/narrate/VoiceSelect.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/narrate/Narrator.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/AsyncPrefs.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["NarrateControls"];
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ ChromeUtils.defineModuleGetter(this, "Task",
|
|||
// The implementation of communications
|
||||
ChromeUtils.import("resource://gre/modules/PromiseWorker.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/AsyncShutdown.jsm", this);
|
||||
var Native = ChromeUtils.import("resource://gre/modules/osfile/osfile_native.jsm", {});
|
||||
|
||||
|
|
|
@ -327,6 +327,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
|
||||
ProfileAge: "resource://gre/modules/ProfileAge.jsm",
|
||||
Sqlite: "resource://gre/modules/Sqlite.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
|
||||
UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.jsm",
|
||||
UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
|
||||
|
|
|
@ -11,6 +11,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
|
||||
DeferredTask: "resource://gre/modules/DeferredTask.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
Deprecated: "resource://gre/modules/Deprecated.jsm",
|
||||
SearchStaticData: "resource://gre/modules/SearchStaticData.jsm",
|
||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
|
|
|
@ -0,0 +1,434 @@
|
|||
/* 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";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["TelemetryStopwatch"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Log",
|
||||
"resource://gre/modules/Log.jsm");
|
||||
|
||||
// Weak map does not allow using null objects as keys. These objects are used
|
||||
// as 'null' placeholders.
|
||||
const NULL_OBJECT = {};
|
||||
const NULL_KEY = {};
|
||||
|
||||
/**
|
||||
* Timers is a variation of a Map used for storing information about running
|
||||
* Stopwatches. Timers has the following data structure:
|
||||
*
|
||||
* {
|
||||
* "HISTOGRAM_NAME": WeakMap {
|
||||
* Object || NULL_OBJECT: Map {
|
||||
* "KEY" || NULL_KEY: startTime
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* // Stores current time for a keyed histogram "PLAYING_WITH_CUTE_ANIMALS".
|
||||
* Timers.put("PLAYING_WITH_CUTE_ANIMALS", null, "CATS", Date.now());
|
||||
*
|
||||
* @example
|
||||
* // Returns information about a simple Stopwatch.
|
||||
* let startTime = Timers.get("PLAYING_WITH_CUTE_ANIMALS", null, "CATS");
|
||||
*/
|
||||
const Timers = {
|
||||
_timers: new Map(),
|
||||
|
||||
_inSeconds: new Set(),
|
||||
|
||||
_validTypes(histogram, obj, key) {
|
||||
const nonEmptyString = value => {
|
||||
return typeof value === "string" && value !== "" && value.length > 0;
|
||||
};
|
||||
return nonEmptyString(histogram) &&
|
||||
typeof obj == "object" &&
|
||||
(key === NULL_KEY || nonEmptyString(key));
|
||||
},
|
||||
|
||||
get(histogram, obj, key) {
|
||||
key = key === null ? NULL_KEY : key;
|
||||
obj = obj || NULL_OBJECT;
|
||||
|
||||
if (!this.has(histogram, obj, key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._timers.get(histogram).get(obj).get(key);
|
||||
},
|
||||
|
||||
put(histogram, obj, key, startTime, {inSeconds} = {}) {
|
||||
key = key === null ? NULL_KEY : key;
|
||||
obj = obj || NULL_OBJECT;
|
||||
|
||||
if (!this._validTypes(histogram, obj, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inSeconds) {
|
||||
this._inSeconds.add(histogram);
|
||||
}
|
||||
|
||||
const objectMap = this._timers.get(histogram) || new WeakMap();
|
||||
const keyedInfo = objectMap.get(obj) || new Map();
|
||||
keyedInfo.set(key, startTime);
|
||||
objectMap.set(obj, keyedInfo);
|
||||
this._timers.set(histogram, objectMap);
|
||||
return true;
|
||||
},
|
||||
|
||||
has(histogram, obj, key) {
|
||||
key = key === null ? NULL_KEY : key;
|
||||
obj = obj || NULL_OBJECT;
|
||||
|
||||
return this._timers.has(histogram) &&
|
||||
this._timers.get(histogram).has(obj) &&
|
||||
this._timers.get(histogram).get(obj).has(key);
|
||||
},
|
||||
|
||||
delete(histogram, obj, key) {
|
||||
key = key === null ? NULL_KEY : key;
|
||||
obj = obj || NULL_OBJECT;
|
||||
|
||||
if (!this.has(histogram, obj, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._inSeconds.delete(histogram);
|
||||
|
||||
const objectMap = this._timers.get(histogram);
|
||||
const keyedInfo = objectMap.get(obj);
|
||||
if (keyedInfo.size > 1) {
|
||||
keyedInfo.delete(key);
|
||||
return true;
|
||||
}
|
||||
objectMap.delete(obj);
|
||||
// NOTE:
|
||||
// We never delete empty objecMaps from this._timers because there is no
|
||||
// nice solution for tracking the number of objects in a WeakMap.
|
||||
// WeakMap is not enumerable, so we can't deterministically say when it's
|
||||
// empty. We accept that trade-off here, given that entries for short-lived
|
||||
// objects will go away when they are no longer referenced
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
var TelemetryStopwatch = {
|
||||
/**
|
||||
* Starts a timer associated with a telemetry histogram. The timer can be
|
||||
* directly associated with a histogram, or with a pair of a histogram and
|
||||
* an object.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently, as long as they are associated with
|
||||
* different objects.
|
||||
* @param {Object} [options.inSeconds=false] - Record elapsed time for this
|
||||
* histogram in seconds instead of milliseconds. Defaults to
|
||||
* false.
|
||||
*
|
||||
* @returns {Boolean} True if the timer was successfully started, false
|
||||
* otherwise. If a timer already exists, it can't be
|
||||
* started again, and the existing one will be cleared in
|
||||
* order to avoid measurements errors.
|
||||
*/
|
||||
start(aHistogram, aObj, {inSeconds} = {}) {
|
||||
return TelemetryStopwatchImpl.start(aHistogram, aObj, null, {inSeconds});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether a timer associated with a telemetry histogram is currently
|
||||
* running. The timer can be directly associated with a histogram, or with a
|
||||
* pair of a histogram and an object.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently, as long as they are associated with
|
||||
* different objects.
|
||||
*
|
||||
* @returns {Boolean} True if the timer exists and is currently running.
|
||||
*/
|
||||
running(aHistogram, aObj) {
|
||||
return TelemetryStopwatchImpl.running(aHistogram, aObj, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the timer associated with a telemetry histogram. The timer can be
|
||||
* directly associated with a histogram, or with a pair of a histogram and
|
||||
* an object. Important: Only use this method when a legitimate cancellation
|
||||
* should be done.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers or a same histogram may be run concurrently,
|
||||
* as long as they are associated with different
|
||||
* objects.
|
||||
*
|
||||
* @returns {Boolean} True if the timer exist and it was cleared, False
|
||||
* otherwise.
|
||||
*/
|
||||
cancel(aHistogram, aObj) {
|
||||
return TelemetryStopwatchImpl.cancel(aHistogram, aObj, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the elapsed time for a particular stopwatch. Primarily for
|
||||
* debugging purposes. Must be called prior to finish.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
* If an invalid name is given, the function will
|
||||
* throw.
|
||||
*
|
||||
* @param (Object) aObj - Optional parameter which associates the histogram
|
||||
* timer with the given object.
|
||||
*
|
||||
* @param {Boolean} aCanceledOkay - Optional parameter which will suppress any
|
||||
* warnings that normally fire when a stopwatch
|
||||
* is finished after being cancelled. Defaults
|
||||
* to false.
|
||||
*
|
||||
* @returns {Integer} time in milliseconds or -1 if the stopwatch was not
|
||||
* found.
|
||||
*/
|
||||
timeElapsed(aHistogram, aObj, aCanceledOkay) {
|
||||
return TelemetryStopwatchImpl.timeElapsed(aHistogram, aObj, null,
|
||||
aCanceledOkay);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the timer associated with the given histogram (and object),
|
||||
* calculates the time delta between start and finish, and adds the value
|
||||
* to the histogram.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter which associates the histogram
|
||||
* timer with the given object.
|
||||
*
|
||||
* @param {Boolean} aCanceledOkay - Optional parameter which will suppress any
|
||||
* warnings that normally fire when a stopwatch
|
||||
* is finished after being cancelled. Defaults
|
||||
* to false.
|
||||
*
|
||||
* @returns {Boolean} True if the timer was succesfully stopped and the data
|
||||
* was added to the histogram, False otherwise.
|
||||
*/
|
||||
finish(aHistogram, aObj, aCanceledOkay) {
|
||||
return TelemetryStopwatchImpl.finish(aHistogram, aObj, null, aCanceledOkay);
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts a timer associated with a keyed telemetry histogram. The timer can
|
||||
* be directly associated with a histogram and its key. Similarly to
|
||||
* @see{TelemetryStopwatch.stat} the histogram and its key can be associated
|
||||
* with an object. Each key may have multiple associated objects and each
|
||||
* object can be associated with multiple keys.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {String} aKey - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently,as long as they are associated with
|
||||
* different objects.
|
||||
* @param {Object} [options.inSeconds=false] - Record elapsed time for this
|
||||
* histogram in seconds instead of milliseconds. Defaults to
|
||||
* false.
|
||||
*
|
||||
* @returns {Boolean} True if the timer was successfully started, false
|
||||
* otherwise. If a timer already exists, it can't be
|
||||
* started again, and the existing one will be cleared in
|
||||
* order to avoid measurements errors.
|
||||
*/
|
||||
startKeyed(aHistogram, aKey, aObj, {inSeconds} = {}) {
|
||||
return TelemetryStopwatchImpl.start(aHistogram, aObj, aKey, {inSeconds});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether a timer associated with a telemetry histogram is currently
|
||||
* running. Similarly to @see{TelemetryStopwatch.running} the timer and its
|
||||
* key can be associated with an object. Each key may have multiple associated
|
||||
* objects and each object can be associated with multiple keys.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {String} aKey - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer is
|
||||
* associated with this object, meaning that multiple
|
||||
* timers for the same histogram may be run
|
||||
* concurrently, as long as they are associated with
|
||||
* different objects.
|
||||
*
|
||||
* @returns {Boolean} True if the timer exists and is currently running.
|
||||
*/
|
||||
runningKeyed(aHistogram, aKey, aObj) {
|
||||
return TelemetryStopwatchImpl.running(aHistogram, aObj, aKey);
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the timer associated with a keyed histogram. Important: Only use
|
||||
* this method when a legitimate cancellation should be done.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {String} aKey - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer
|
||||
* associated with this object is deleted.
|
||||
*
|
||||
* @return {Boolean} True if the timer exist and it was cleared, False
|
||||
* otherwise.
|
||||
*/
|
||||
cancelKeyed(aHistogram, aKey, aObj) {
|
||||
return TelemetryStopwatchImpl.cancel(aHistogram, aObj, aKey);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the elapsed time for a particular stopwatch. Primarily for
|
||||
* debugging purposes. Must be called prior to finish.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {String} aKey - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param {Object} aObj - Optional parameter. If specified, the timer
|
||||
* associated with this object is used to calculate
|
||||
* the elapsed time.
|
||||
*
|
||||
* @return {Integer} time in milliseconds or -1 if the stopwatch was not
|
||||
* found.
|
||||
*/
|
||||
timeElapsedKeyed(aHistogram, aKey, aObj, aCanceledOkay) {
|
||||
return TelemetryStopwatchImpl.timeElapsed(aHistogram, aObj, aKey,
|
||||
aCanceledOkay);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the timer associated with the given keyed histogram (and object),
|
||||
* calculates the time delta between start and finish, and adds the value
|
||||
* to the keyed histogram.
|
||||
*
|
||||
* @param {String} aHistogram - a string which must be a valid histogram name.
|
||||
*
|
||||
* @param {String} aKey - a string which must be a valid histgram key.
|
||||
*
|
||||
* @param {Object} aObj - optional parameter which associates the histogram
|
||||
* timer with the given object.
|
||||
*
|
||||
* @param {Boolean} aCanceledOkay - Optional parameter which will suppress any
|
||||
* warnings that normally fire when a stopwatch
|
||||
* is finished after being cancelled. Defaults
|
||||
* to false.
|
||||
*
|
||||
* @returns {Boolean} True if the timer was succesfully stopped and the data
|
||||
* was added to the histogram, False otherwise.
|
||||
*/
|
||||
finishKeyed(aHistogram, aKey, aObj, aCanceledOkay) {
|
||||
return TelemetryStopwatchImpl.finish(aHistogram, aObj, aKey, aCanceledOkay);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the testing mode. Used by tests.
|
||||
*/
|
||||
setTestModeEnabled(testing = true) {
|
||||
TelemetryStopwatchImpl.suppressErrors(testing);
|
||||
},
|
||||
};
|
||||
|
||||
var TelemetryStopwatchImpl = {
|
||||
// Suppress errors. Used when testing.
|
||||
_suppressErrors: false,
|
||||
|
||||
suppressErrors(suppress) {
|
||||
this._suppressErrors = suppress;
|
||||
},
|
||||
|
||||
start(histogram, object, key, {inSeconds} = {}) {
|
||||
if (Timers.has(histogram, object, key)) {
|
||||
Timers.delete(histogram, object, key);
|
||||
if (!this._suppressErrors) {
|
||||
Cu.reportError(`TelemetryStopwatch: key "${histogram}" was already ` +
|
||||
"initialized");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return Timers.put(histogram, object, key, Cu.now(), {inSeconds});
|
||||
},
|
||||
|
||||
running(histogram, object, key) {
|
||||
return Timers.has(histogram, object, key);
|
||||
},
|
||||
|
||||
cancel(histogram, object, key) {
|
||||
return Timers.delete(histogram, object, key);
|
||||
},
|
||||
|
||||
timeElapsed(histogram, object, key, aCanceledOkay) {
|
||||
const startTime = Timers.get(histogram, object, key);
|
||||
if (startTime === null) {
|
||||
if (!aCanceledOkay && !this._suppressErrors) {
|
||||
Cu.reportError("TelemetryStopwatch: requesting elapsed time for " +
|
||||
`nonexisting stopwatch. Histogram: "${histogram}", ` +
|
||||
`key: "${key}"`);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
try {
|
||||
const delta = Cu.now() - startTime;
|
||||
if (Timers._inSeconds.has(histogram)) {
|
||||
return Math.round(delta / 1000);
|
||||
}
|
||||
return Math.round(delta);
|
||||
} catch (e) {
|
||||
if (!this._suppressErrors) {
|
||||
Cu.reportError("TelemetryStopwatch: failed to calculate elapsed time " +
|
||||
`for Histogram: "${histogram}", key: "${key}", ` +
|
||||
`exception: ${Log.exceptionStr(e)}`);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
|
||||
finish(histogram, object, key, aCanceledOkay) {
|
||||
const delta = this.timeElapsed(histogram, object, key, aCanceledOkay);
|
||||
if (delta == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (key) {
|
||||
Services.telemetry.getKeyedHistogramById(histogram).add(key, delta);
|
||||
} else {
|
||||
Services.telemetry.getHistogramById(histogram).add(delta);
|
||||
}
|
||||
} catch (e) {
|
||||
if (!this._suppressErrors) {
|
||||
Cu.reportError("TelemetryStopwatch: failed to update the Histogram " +
|
||||
`"${histogram}", using key: "${key}", ` +
|
||||
`exception: ${Log.exceptionStr(e)}`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return Timers.delete(histogram, object, key);
|
||||
},
|
||||
};
|
|
@ -1,535 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/telemetry/Stopwatch.h"
|
||||
|
||||
#include "TelemetryHistogram.h"
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
using mozilla::dom::AutoJSAPI;
|
||||
|
||||
static inline nsQueryObject<nsISupports>
|
||||
do_QueryReflector(JSObject* aReflector)
|
||||
{
|
||||
nsCOMPtr<nsISupports> reflector = xpc::UnwrapReflectorToISupports(aReflector);
|
||||
return do_QueryObject(reflector);
|
||||
}
|
||||
|
||||
static inline nsQueryObject<nsISupports>
|
||||
do_QueryReflector(const JS::Value& aReflector)
|
||||
{
|
||||
return do_QueryReflector(&aReflector.toObject());
|
||||
}
|
||||
|
||||
static void
|
||||
LogError(JSContext* aCx, const nsCString& aMessage)
|
||||
{
|
||||
// This is a bit of a hack to report an error with the current JS caller's
|
||||
// location. We create an AutoJSAPI object bound to the current caller
|
||||
// global, report a JS error, and then let AutoJSAPI's destructor report the
|
||||
// error.
|
||||
//
|
||||
// Unfortunately, there isn't currently a more straightforward way to do
|
||||
// this from C++.
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (jsapi.Init(global)) {
|
||||
JS_ReportErrorUTF8(jsapi.cx(), "%s", aMessage.get());
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace telemetry {
|
||||
|
||||
class Timer final
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(Timer)
|
||||
|
||||
Timer() = default;
|
||||
|
||||
void Start(bool aInSeconds)
|
||||
{
|
||||
mStartTime = TimeStamp::Now();
|
||||
mInSeconds = aInSeconds;
|
||||
}
|
||||
|
||||
bool Started()
|
||||
{
|
||||
return !mStartTime.IsNull();
|
||||
}
|
||||
|
||||
uint32_t Elapsed()
|
||||
{
|
||||
auto delta = TimeStamp::Now() - mStartTime;
|
||||
return mInSeconds ? delta.ToSeconds() : delta.ToMilliseconds();
|
||||
}
|
||||
|
||||
bool& InSeconds()
|
||||
{
|
||||
return mInSeconds;
|
||||
}
|
||||
|
||||
private:
|
||||
~Timer() = default;
|
||||
|
||||
TimeStamp mStartTime {};
|
||||
bool mInSeconds;
|
||||
};
|
||||
|
||||
|
||||
#define TIMER_KEYS_IID \
|
||||
{ 0xef707178, 0x1544, 0x46e2, \
|
||||
{ 0xa3, 0xf5, 0x98, 0x38, 0xba, 0x60, 0xfd, 0x8f } }
|
||||
|
||||
class TimerKeys final : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(TIMER_KEYS_IID)
|
||||
|
||||
Timer* Get(const nsAString& aKey, bool aCreate = true);
|
||||
|
||||
already_AddRefed<Timer> GetAndDelete(const nsAString& aKey)
|
||||
{
|
||||
RefPtr<Timer> timer;
|
||||
mTimers.Remove(aKey, getter_AddRefs(timer));
|
||||
return timer.forget();
|
||||
}
|
||||
|
||||
bool Delete(const nsAString& aKey)
|
||||
{
|
||||
return mTimers.Remove(aKey);
|
||||
}
|
||||
|
||||
private:
|
||||
~TimerKeys() = default;
|
||||
|
||||
nsRefPtrHashtable<nsStringHashKey, Timer> mTimers;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(TimerKeys, TIMER_KEYS_IID)
|
||||
|
||||
NS_IMPL_ISUPPORTS(TimerKeys, TimerKeys)
|
||||
|
||||
Timer*
|
||||
TimerKeys::Get(const nsAString& aKey, bool aCreate)
|
||||
{
|
||||
if (aCreate) {
|
||||
RefPtr<Timer>& timer = mTimers.GetOrInsert(aKey);
|
||||
if (!timer) {
|
||||
timer = new Timer();
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
return mTimers.GetWeak(aKey);
|
||||
}
|
||||
|
||||
|
||||
class Timers final
|
||||
{
|
||||
public:
|
||||
Timers();
|
||||
|
||||
static Timers& Singleton();
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(Timers)
|
||||
|
||||
JSObject* Get(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
bool aCreate = true);
|
||||
|
||||
TimerKeys* Get(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
bool aCreate = true);
|
||||
|
||||
Timer* Get(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aCreate = true);
|
||||
|
||||
already_AddRefed<Timer>
|
||||
GetAndDelete(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey);
|
||||
|
||||
bool Delete(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey);
|
||||
|
||||
int32_t TimeElapsed(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aCanceledOkay = false,
|
||||
bool aDelete = false);
|
||||
|
||||
bool Start(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aInSeconds = false);
|
||||
|
||||
int32_t Finish(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aCanceledOkay = false);
|
||||
|
||||
bool& SuppressErrors()
|
||||
{
|
||||
return mSuppressErrors;
|
||||
}
|
||||
|
||||
private:
|
||||
~Timers() = default;
|
||||
|
||||
JS::PersistentRooted<JSObject*> mTimers;
|
||||
bool mSuppressErrors = false;
|
||||
|
||||
static StaticRefPtr<Timers> sSingleton;
|
||||
};
|
||||
|
||||
StaticRefPtr<Timers> Timers::sSingleton;
|
||||
|
||||
/* static */ Timers&
|
||||
Timers::Singleton()
|
||||
{
|
||||
if (!sSingleton) {
|
||||
sSingleton = new Timers();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
return *sSingleton;
|
||||
}
|
||||
|
||||
Timers::Timers()
|
||||
: mTimers(dom::RootingCx())
|
||||
{
|
||||
AutoJSAPI jsapi;
|
||||
MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
|
||||
|
||||
mTimers = JS::NewMapObject(jsapi.cx());
|
||||
MOZ_RELEASE_ASSERT(mTimers);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Timers::Get(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
bool aCreate)
|
||||
{
|
||||
JSAutoRealm ar(aCx, mTimers);
|
||||
|
||||
JS::RootedValue histogram(aCx);
|
||||
JS::RootedValue objs(aCx);
|
||||
|
||||
if (!xpc::NonVoidStringToJsval(aCx, aHistogram, &histogram) ||
|
||||
!JS::MapGet(aCx, mTimers, histogram, &objs)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!objs.isObject()) {
|
||||
if (aCreate) {
|
||||
objs = JS::ObjectOrNullValue(JS::NewWeakMapObject(aCx));
|
||||
}
|
||||
if (!objs.isObject() ||
|
||||
!JS::MapSet(aCx, mTimers, histogram, objs)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &objs.toObject();
|
||||
}
|
||||
|
||||
TimerKeys*
|
||||
Timers::Get(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
bool aCreate)
|
||||
{
|
||||
JSAutoRealm ar(aCx, mTimers);
|
||||
|
||||
JS::RootedObject objs(aCx, Get(aCx, aHistogram, aCreate));
|
||||
if (!objs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If no object is passed, use mTimers as a stand-in for a null object
|
||||
// (which cannot be used as a weak map key).
|
||||
JS::RootedObject obj(aCx, aObj ? aObj : mTimers);
|
||||
if (!JS_WrapObject(aCx, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<TimerKeys> keys;
|
||||
JS::RootedValue keysObj(aCx);
|
||||
if (!JS::GetWeakMapEntry(aCx, objs, obj, &keysObj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!keysObj.isObject()) {
|
||||
if (aCreate) {
|
||||
keys = new TimerKeys();
|
||||
Unused << nsContentUtils::WrapNative(aCx, keys, &keysObj);
|
||||
}
|
||||
if (!keysObj.isObject() ||
|
||||
!JS::SetWeakMapEntry(aCx, objs, obj, keysObj)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
keys = do_QueryReflector(keysObj);
|
||||
return keys;
|
||||
}
|
||||
|
||||
Timer*
|
||||
Timers::Get(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aCreate)
|
||||
{
|
||||
if (RefPtr<TimerKeys> keys = Get(aCx, aHistogram, aObj, aCreate)) {
|
||||
return keys->Get(aKey, aCreate);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<Timer>
|
||||
Timers::GetAndDelete(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey)
|
||||
{
|
||||
if (RefPtr<TimerKeys> keys = Get(aCx, aHistogram, aObj, false)) {
|
||||
return keys->GetAndDelete(aKey);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
Timers::Delete(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey)
|
||||
{
|
||||
if (RefPtr<TimerKeys> keys = Get(aCx, aHistogram, aObj, false)) {
|
||||
return keys->Delete(aKey);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t
|
||||
Timers::TimeElapsed(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aCanceledOkay,
|
||||
bool aDelete)
|
||||
{
|
||||
RefPtr<Timer> timer;
|
||||
if (aDelete) {
|
||||
timer = GetAndDelete(aCx, aHistogram, aObj, aKey);
|
||||
} else {
|
||||
timer = Get(aCx, aHistogram, aObj, aKey, false);
|
||||
}
|
||||
if (!timer) {
|
||||
if (!aCanceledOkay && !mSuppressErrors) {
|
||||
LogError(aCx, nsPrintfCString(
|
||||
"TelemetryStopwatch: requesting elapsed time for "
|
||||
"nonexisting stopwatch. Histogram: \"%s\", key: \"%s\"",
|
||||
NS_ConvertUTF16toUTF8(aHistogram).get(),
|
||||
NS_ConvertUTF16toUTF8(aKey).get()));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return timer->Elapsed();
|
||||
}
|
||||
|
||||
bool
|
||||
Timers::Start(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aInSeconds)
|
||||
{
|
||||
if (RefPtr<Timer> timer = Get(aCx, aHistogram, aObj, aKey)) {
|
||||
if (timer->Started()) {
|
||||
if (!mSuppressErrors) {
|
||||
LogError(aCx, nsPrintfCString(
|
||||
"TelemetryStopwatch: key \"%s\" was already initialized",
|
||||
NS_ConvertUTF16toUTF8(aHistogram).get()));
|
||||
}
|
||||
Delete(aCx, aHistogram, aObj, aKey);
|
||||
} else {
|
||||
timer->Start(aInSeconds);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t
|
||||
Timers::Finish(JSContext* aCx,
|
||||
const nsAString& aHistogram,
|
||||
JS::HandleObject aObj,
|
||||
const nsAString& aKey,
|
||||
bool aCanceledOkay)
|
||||
{
|
||||
int32_t delta = TimeElapsed(aCx, aHistogram, aObj, aKey, aCanceledOkay, true);
|
||||
if (delta == -1) {
|
||||
return delta;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 histogram(aHistogram);
|
||||
bool ok;
|
||||
if (!aKey.IsVoid()) {
|
||||
NS_ConvertUTF16toUTF8 key(aKey);
|
||||
ok = TelemetryHistogram::Accumulate(histogram.get(), key, delta);
|
||||
} else {
|
||||
ok = TelemetryHistogram::Accumulate(histogram.get(), delta);
|
||||
}
|
||||
if (!ok && !mSuppressErrors) {
|
||||
LogError(aCx, nsPrintfCString(
|
||||
"TelemetryStopwatch: failed to update the Histogram "
|
||||
"\"%s\", using key: \"%s\"",
|
||||
NS_ConvertUTF16toUTF8(aHistogram).get(),
|
||||
NS_ConvertUTF16toUTF8(aKey).get()));
|
||||
}
|
||||
return ok ? delta : -1;
|
||||
}
|
||||
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::Start(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
const dom::TelemetryStopwatchOptions& aOptions)
|
||||
{
|
||||
return StartKeyed(aGlobal, aHistogram, VoidString(), aObj,
|
||||
aOptions);
|
||||
}
|
||||
/* static */ bool
|
||||
Stopwatch::StartKeyed(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
const nsAString& aKey,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
const dom::TelemetryStopwatchOptions& aOptions)
|
||||
{
|
||||
return Timers::Singleton().Start(aGlobal.Context(),
|
||||
aHistogram, aObj, aKey,
|
||||
aOptions.mInSeconds);
|
||||
}
|
||||
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::Running(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
return RunningKeyed(aGlobal, aHistogram, VoidString(), aObj);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::RunningKeyed(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
const nsAString& aKey,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
return TimeElapsedKeyed(aGlobal, aHistogram, aKey, aObj, true) != -1;
|
||||
}
|
||||
|
||||
|
||||
/* static */ int32_t
|
||||
Stopwatch::TimeElapsed(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
bool aCanceledOkay)
|
||||
{
|
||||
return TimeElapsedKeyed(aGlobal, aHistogram, VoidString(), aObj,
|
||||
aCanceledOkay);
|
||||
}
|
||||
|
||||
/* static */ int32_t
|
||||
Stopwatch::TimeElapsedKeyed(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
const nsAString& aKey,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
bool aCanceledOkay)
|
||||
{
|
||||
return Timers::Singleton().TimeElapsed(
|
||||
aGlobal.Context(),
|
||||
aHistogram, aObj, aKey,
|
||||
aCanceledOkay);
|
||||
}
|
||||
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::Finish(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
bool aCanceledOkay)
|
||||
{
|
||||
return FinishKeyed(aGlobal, aHistogram, VoidString(), aObj,
|
||||
aCanceledOkay);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::FinishKeyed(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
const nsAString& aKey,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
bool aCanceledOkay)
|
||||
{
|
||||
return Timers::Singleton().Finish(
|
||||
aGlobal.Context(),
|
||||
aHistogram, aObj, aKey,
|
||||
aCanceledOkay) != -1;
|
||||
}
|
||||
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::Cancel(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
return CancelKeyed(aGlobal, aHistogram, VoidString(), aObj);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Stopwatch::CancelKeyed(const dom::GlobalObject& aGlobal,
|
||||
const nsAString& aHistogram,
|
||||
const nsAString& aKey,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
return Timers::Singleton().Delete(aGlobal.Context(),
|
||||
aHistogram, aObj, aKey);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Stopwatch::SetTestModeEnabled(const dom::GlobalObject& aGlobal,
|
||||
bool aTesting)
|
||||
{
|
||||
Timers::Singleton().SuppressErrors() = aTesting;
|
||||
}
|
||||
|
||||
} // namespace telemetry
|
||||
} // namespace mozilla
|
|
@ -1,77 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef Stopwatch_h__
|
||||
#define Stopwatch_h__
|
||||
|
||||
#include "mozilla/dom/TelemetryStopwatchBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace telemetry {
|
||||
|
||||
class Stopwatch
|
||||
{
|
||||
using GlobalObject = mozilla::dom::GlobalObject;
|
||||
|
||||
public:
|
||||
static bool Start(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
JS::Handle<JSObject*> obj,
|
||||
const dom::TelemetryStopwatchOptions& options);
|
||||
|
||||
static bool Running(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
JS::Handle<JSObject*> obj);
|
||||
|
||||
static bool Cancel(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
JS::Handle<JSObject*> obj);
|
||||
|
||||
static int32_t TimeElapsed(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
JS::Handle<JSObject*> obj,
|
||||
bool canceledOkay);
|
||||
|
||||
static bool Finish(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
JS::Handle<JSObject*> obj,
|
||||
bool canceledOkay);
|
||||
|
||||
static bool StartKeyed(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
const nsAString& key,
|
||||
JS::Handle<JSObject*> obj,
|
||||
const dom::TelemetryStopwatchOptions& options);
|
||||
|
||||
static bool RunningKeyed(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
const nsAString& key,
|
||||
JS::Handle<JSObject*> obj);
|
||||
|
||||
static bool CancelKeyed(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
const nsAString& key,
|
||||
JS::Handle<JSObject*> obj);
|
||||
|
||||
static int32_t TimeElapsedKeyed(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
const nsAString& key,
|
||||
JS::Handle<JSObject*> obj,
|
||||
bool canceledOkay);
|
||||
|
||||
static bool FinishKeyed(const GlobalObject& global,
|
||||
const nsAString& histogram,
|
||||
const nsAString& key,
|
||||
JS::Handle<JSObject*> obj,
|
||||
bool canceledOkay);
|
||||
|
||||
static void SetTestModeEnabled(const GlobalObject& global,
|
||||
bool testing);
|
||||
};
|
||||
|
||||
} // namespace telemetry
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // Stopwatch_h__
|
|
@ -2264,23 +2264,22 @@ TelemetryHistogram::Accumulate(HistogramID aID, const nsCString& aKey,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
TelemetryHistogram::Accumulate(const char* name, uint32_t sample)
|
||||
{
|
||||
StaticMutexAutoLock locker(gTelemetryHistogramMutex);
|
||||
if (!internal_CanRecordBase()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
HistogramID id;
|
||||
nsresult rv = internal_GetHistogramIdByName(locker, nsDependentCString(name), &id);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
internal_Accumulate(locker, id, sample);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
TelemetryHistogram::Accumulate(const char* name,
|
||||
const nsCString& key, uint32_t sample)
|
||||
{
|
||||
|
@ -2289,7 +2288,7 @@ TelemetryHistogram::Accumulate(const char* name,
|
|||
{
|
||||
StaticMutexAutoLock locker(gTelemetryHistogramMutex);
|
||||
if (!internal_CanRecordBase()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
HistogramID id;
|
||||
nsresult rv = internal_GetHistogramIdByName(locker, nsDependentCString(name), &id);
|
||||
|
@ -2297,7 +2296,7 @@ TelemetryHistogram::Accumulate(const char* name,
|
|||
// Check if we're allowed to record in the provided key, for this histogram.
|
||||
if (gHistogramInfos[id].allows_key(key)) {
|
||||
internal_Accumulate(locker, id, key, sample);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
// We're holding |gTelemetryHistogramMutex|, so we can't print a message
|
||||
// here.
|
||||
|
@ -2312,7 +2311,6 @@ TelemetryHistogram::Accumulate(const char* name,
|
|||
mozilla::Telemetry::ScalarID::TELEMETRY_ACCUMULATE_UNKNOWN_HISTOGRAM_KEYS,
|
||||
NS_ConvertASCIItoUTF16(name), 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -45,8 +45,8 @@ void Accumulate(mozilla::Telemetry::HistogramID aID, const nsCString& aKey,
|
|||
uint32_t aSample);
|
||||
void Accumulate(mozilla::Telemetry::HistogramID aID, const nsCString& aKey,
|
||||
const nsTArray<uint32_t>& aSamples);
|
||||
bool Accumulate(const char* name, uint32_t sample);
|
||||
bool Accumulate(const char* name, const nsCString& key, uint32_t sample);
|
||||
void Accumulate(const char* name, uint32_t sample);
|
||||
void Accumulate(const char* name, const nsCString& key, uint32_t sample);
|
||||
|
||||
void AccumulateCategorical(mozilla::Telemetry::HistogramID aId, const nsCString& aLabel);
|
||||
void AccumulateCategorical(mozilla::Telemetry::HistogramID aId, const nsTArray<nsCString>& aLabels);
|
||||
|
|
|
@ -272,7 +272,7 @@ Note that ``nsITelemetry.getHistogramById()`` will throw an ``NS_ERROR_FAILURE``
|
|||
|
||||
Adding a new Telemetry probe is not possible with Artifact builds. A full build is needed.
|
||||
|
||||
For histograms measuring time, TelemetryStopwatch can be used to avoid working with Dates manually:
|
||||
For histograms measuring time, `TelemetryStopwatch <https://dxr.mozilla.org/mozilla-central/source/toolkit/components/telemetry/TelemetryStopwatch.jsm>`_ can be used to avoid working with Dates manually:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ These helpers record the elapsed time into histograms, so you have to create sui
|
|||
|
||||
From JavaScript
|
||||
===============
|
||||
JavaScript can measure elapsed time using TelemetryStopwatch.
|
||||
JavaScript can measure elapsed time using `TelemetryStopwatch.jsm <https://dxr.mozilla.org/mozilla-central/source/toolkit/components/telemetry/TelemetryStopwatch.jsm>`_.
|
||||
|
||||
``TelemetryStopwatch`` is a helper that simplifies recording elapsed time (in milliseconds) into histograms (plain or keyed).
|
||||
|
||||
|
|
|
@ -61,14 +61,9 @@ EXPORTS.mozilla += [
|
|||
'other/ProcessedStack.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.telemetry += [
|
||||
'core/Stopwatch.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'core/ipc/TelemetryIPC.cpp',
|
||||
'core/ipc/TelemetryIPCAccumulator.cpp',
|
||||
'core/Stopwatch.cpp',
|
||||
'core/Telemetry.cpp',
|
||||
'core/TelemetryCommon.cpp',
|
||||
'core/TelemetryEvent.cpp',
|
||||
|
@ -103,6 +98,7 @@ EXTRA_JS_MODULES += [
|
|||
'app/TelemetryEnvironment.jsm',
|
||||
'app/TelemetryReportingPolicy.jsm',
|
||||
'app/TelemetrySend.jsm',
|
||||
'app/TelemetryStopwatch.jsm',
|
||||
'app/TelemetryStorage.jsm',
|
||||
'app/TelemetryTimestamps.jsm',
|
||||
'app/TelemetryUtils.jsm',
|
||||
|
|
|
@ -17,6 +17,8 @@ ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
|||
ChromeUtils.import("resource://gre/modules/osfile.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing",
|
||||
"resource://gre/modules/HealthPing.jsm");
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var tmpScope = {};
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", tmpScope);
|
||||
var TelemetryStopwatch = tmpScope.TelemetryStopwatch;
|
||||
|
||||
const HIST_NAME = "TELEMETRY_SEND_SUCCESS";
|
||||
const HIST_NAME2 = "RANGE_CHECKSUM_ERRORS";
|
||||
const KEYED_HIST = { id: "TELEMETRY_INVALID_PING_TYPE_SUBMITTED", key: "TEST" };
|
||||
|
@ -22,6 +26,12 @@ function run_test() {
|
|||
snapshot = histogram.snapshot(KEYED_HIST.key);
|
||||
originalCount3 = Object.values(snapshot.values).reduce((a, b) => a += b, 0);
|
||||
|
||||
Assert.ok(!TelemetryStopwatch.start(3));
|
||||
Assert.ok(!TelemetryStopwatch.start({}));
|
||||
Assert.ok(!TelemetryStopwatch.start("", 3));
|
||||
Assert.ok(!TelemetryStopwatch.start("", ""));
|
||||
Assert.ok(!TelemetryStopwatch.start({}, {}));
|
||||
|
||||
Assert.ok(TelemetryStopwatch.start("mark1"));
|
||||
Assert.ok(TelemetryStopwatch.start("mark2"));
|
||||
|
||||
|
@ -113,6 +123,11 @@ function run_test() {
|
|||
Assert.ok(!TelemetryStopwatch.finish(HIST_NAME));
|
||||
Assert.ok(!TelemetryStopwatch.finish(HIST_NAME, refObj));
|
||||
|
||||
// Verify that keyed stopwatch reject invalid keys.
|
||||
for (let key of [3, {}, ""]) {
|
||||
Assert.ok(!TelemetryStopwatch.startKeyed(KEYED_HIST.id, key));
|
||||
}
|
||||
|
||||
// Verify that keyed histograms can be started.
|
||||
Assert.ok(!TelemetryStopwatch.runningKeyed("HISTOGRAM", "KEY1"));
|
||||
Assert.ok(!TelemetryStopwatch.runningKeyed("HISTOGRAM", "KEY2"));
|
||||
|
@ -152,8 +167,7 @@ function run_test() {
|
|||
|
||||
// Verify that keyed histograms can only be canceled through "keyed" API.
|
||||
Assert.ok(TelemetryStopwatch.startKeyed(KEYED_HIST.id, KEYED_HIST.key));
|
||||
Assert.throws(() => TelemetryStopwatch.cancel(KEYED_HIST.id, KEYED_HIST.key),
|
||||
/is not an object/);
|
||||
Assert.ok(!TelemetryStopwatch.cancel(KEYED_HIST.id, KEYED_HIST.key));
|
||||
Assert.ok(TelemetryStopwatch.cancelKeyed(KEYED_HIST.id, KEYED_HIST.key));
|
||||
Assert.ok(!TelemetryStopwatch.cancelKeyed(KEYED_HIST.id, KEYED_HIST.key));
|
||||
|
||||
|
|
|
@ -421,6 +421,19 @@
|
|||
<field name="arrowKeysShouldWrap" readonly="true">
|
||||
/Mac/.test(navigator.platform)
|
||||
</field>
|
||||
<property name="TelemetryStopwatch" readonly="true">
|
||||
<getter><![CDATA[
|
||||
let module = {};
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", module);
|
||||
Object.defineProperty(this, "TelemetryStopwatch", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: module.TelemetryStopwatch,
|
||||
});
|
||||
return module.TelemetryStopwatch;
|
||||
]]></getter>
|
||||
</property>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
@ -434,7 +447,7 @@
|
|||
if (this != this.parentNode.selectedItem) { // Not selected yet
|
||||
let stopwatchid = this.parentNode.getAttribute("stopwatchid");
|
||||
if (stopwatchid) {
|
||||
TelemetryStopwatch.start(stopwatchid);
|
||||
this.TelemetryStopwatch.start(stopwatchid);
|
||||
}
|
||||
|
||||
// Call this before setting the 'ignorefocus' attribute because this
|
||||
|
@ -456,7 +469,7 @@
|
|||
}
|
||||
|
||||
if (stopwatchid) {
|
||||
TelemetryStopwatch.finish(stopwatchid);
|
||||
this.TelemetryStopwatch.finish(stopwatchid);
|
||||
}
|
||||
}
|
||||
// Otherwise this tab is already selected and we will fall
|
||||
|
|
|
@ -64,7 +64,6 @@ module.exports = {
|
|||
// generators, see bug 968038.
|
||||
"StopIteration": false,
|
||||
"StructuredCloneHolder": false,
|
||||
"TelemetryStopwatch": false,
|
||||
"WebAssembly": false,
|
||||
"WebExtensionContentScript": false,
|
||||
"WebExtensionPolicy": false,
|
||||
|
|
|
@ -68,7 +68,6 @@ module.exports = {
|
|||
"StreamFilter": false,
|
||||
"StreamFilterDataEvent": false,
|
||||
"StructuredCloneHolder": false,
|
||||
"TelemetryStopwatch": false,
|
||||
"TCPServerSocket": false,
|
||||
"TCPServerSocketEvent": false,
|
||||
"TCPSocket": false,
|
||||
|
|
Загрузка…
Ссылка в новой задаче