summaryrefslogtreecommitdiff
path: root/toolkit
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2021-10-29 19:53:54 +0000
committerMoonchild <moonchild@palemoon.org>2022-04-02 14:42:57 +0200
commitd60103257eb83db103f9acab54b1755486b7e9c1 (patch)
treefdfdc5a4c70204d0539461c88597fe4a54c2dce2 /toolkit
parentee86d3eb9c468edbb81550d27114ed66b3d71ee5 (diff)
downloaduxp-d60103257eb83db103f9acab54b1755486b7e9c1.tar.gz
Issue #21 - Remove Telemetry accumulation/structures from toolkit js.
This fixes toolkit modules and prevents toolkit component breakage. Also removes about:telemetry
Diffstat (limited to 'toolkit')
-rw-r--r--toolkit/components/addoncompat/CompatWarning.jsm5
-rw-r--r--toolkit/components/alerts/resources/content/alert.js2
-rw-r--r--toolkit/components/asyncshutdown/AsyncShutdown.jsm12
-rw-r--r--toolkit/components/asyncshutdown/nsAsyncShutdown.js1
-rw-r--r--toolkit/components/asyncshutdown/nsIAsyncShutdown.idl5
-rw-r--r--toolkit/components/blocklist/nsBlocklistService.js5
-rw-r--r--toolkit/components/crashes/CrashManager.jsm67
-rw-r--r--toolkit/components/gfx/SanityTest.js41
-rw-r--r--toolkit/components/osfile/NativeOSFileInternals.cpp4
-rw-r--r--toolkit/components/osfile/modules/osfile_async_front.jsm25
-rw-r--r--toolkit/components/osfile/modules/osfile_async_worker.js1
-rw-r--r--toolkit/components/parentalcontrols/nsIParentalControlsService.idl3
-rw-r--r--toolkit/components/passwordmgr/InsecurePasswordUtils.jsm1
-rw-r--r--toolkit/components/passwordmgr/LoginManagerContent.jsm5
-rw-r--r--toolkit/components/passwordmgr/content/passwordManager.js11
-rw-r--r--toolkit/components/passwordmgr/nsLoginManager.js75
-rw-r--r--toolkit/components/passwordmgr/nsLoginManagerPrompter.js20
-rw-r--r--toolkit/components/perfmonitoring/AddonWatcher.jsm12
-rw-r--r--toolkit/components/places/BookmarkHTMLUtils.jsm8
-rw-r--r--toolkit/components/places/BookmarkJSONUtils.jsm8
-rw-r--r--toolkit/components/places/PlacesBackups.jsm8
-rw-r--r--toolkit/components/places/PlacesCategoriesStarter.js9
-rw-r--r--toolkit/components/places/PlacesDBUtils.jsm186
-rw-r--r--toolkit/components/places/UnifiedComplete.js4
-rw-r--r--toolkit/components/places/nsPlacesAutoComplete.js17
-rw-r--r--toolkit/components/places/nsPlacesExpiration.js32
-rw-r--r--toolkit/components/printing/content/printUtils.js13
-rw-r--r--toolkit/components/terminator/terminator.manifest4
-rw-r--r--toolkit/components/thumbnails/BackgroundPageThumbs.jsm59
-rw-r--r--toolkit/components/thumbnails/PageThumbs.jsm7
-rw-r--r--toolkit/components/thumbnails/content/backgroundPageThumbsContent.js4
-rw-r--r--toolkit/components/viewsource/content/viewSourceUtils.js9
-rw-r--r--toolkit/content/aboutTelemetry.css271
-rw-r--r--toolkit/content/aboutTelemetry.js2168
-rw-r--r--toolkit/content/aboutTelemetry.xhtml290
-rw-r--r--toolkit/content/jar.mn3
-rw-r--r--toolkit/mozapps/extensions/AddonManager.jsm73
-rw-r--r--toolkit/mozapps/extensions/content/update.js17
-rw-r--r--toolkit/mozapps/extensions/internal/GMPProvider.jsm11
-rw-r--r--toolkit/mozapps/extensions/internal/XPIProvider.jsm54
-rw-r--r--toolkit/mozapps/extensions/internal/XPIProviderUtils.js49
41 files changed, 22 insertions, 3577 deletions
diff --git a/toolkit/components/addoncompat/CompatWarning.jsm b/toolkit/components/addoncompat/CompatWarning.jsm
index b32409a46b..c4d45adeee 100644
--- a/toolkit/components/addoncompat/CompatWarning.jsm
+++ b/toolkit/components/addoncompat/CompatWarning.jsm
@@ -47,11 +47,6 @@ var CompatWarning = {
}
alreadyWarned = true;
- if (addon) {
- let histogram = Services.telemetry.getKeyedHistogramById("ADDON_SHIM_USAGE");
- histogram.add(addon, warning ? warning.number : 0);
- }
-
if (!Preferences.get("dom.ipc.shims.enabledWarnings", false))
return;
diff --git a/toolkit/components/alerts/resources/content/alert.js b/toolkit/components/alerts/resources/content/alert.js
index e9725bedb0..b2ebedbc0e 100644
--- a/toolkit/components/alerts/resources/content/alert.js
+++ b/toolkit/components/alerts/resources/content/alert.js
@@ -329,8 +329,6 @@ function doNotDisturb() {
.getService(Ci.nsIAlertsService)
.QueryInterface(Ci.nsIAlertsDoNotDisturb);
alertService.manualDoNotDisturb = true;
- Services.telemetry.getHistogramById("WEB_NOTIFICATION_MENU")
- .add(0);
onAlertClose();
}
diff --git a/toolkit/components/asyncshutdown/AsyncShutdown.jsm b/toolkit/components/asyncshutdown/AsyncShutdown.jsm
index 9cdf9e126d..43fdc6bf1e 100644
--- a/toolkit/components/asyncshutdown/AsyncShutdown.jsm
+++ b/toolkit/components/asyncshutdown/AsyncShutdown.jsm
@@ -9,12 +9,11 @@
* sequentially. Typically, each shutdown phase removes some
* capabilities from the application. For instance, at the end of
* phase profileBeforeChange, no service is permitted to write to the
- * profile directory (with the exception of Telemetry). Consequently,
- * if any service has requested I/O to the profile directory before or
- * during phase profileBeforeChange, the system must be informed that
- * these requests need to be completed before the end of phase
- * profileBeforeChange. Failing to inform the system of this
- * requirement can (and has been known to) cause data loss.
+ * profile directory. Consequently, if any service has requested I/O
+ * to the profile directory before or during phase profileBeforeChange,
+ * the system must be informed that these requests need to be completed
+ * before the end of phase profileBeforeChange. Failing to inform the
+ * system of this requirement can (and has been known to) cause data loss.
*
* Example: At some point during shutdown, the Add-On Manager needs to
* ensure that all add-ons have safely written their data to disk,
@@ -1001,7 +1000,6 @@ if (!isContent) {
this.AsyncShutdown.profileChangeTeardown = getPhase("profile-change-teardown");
this.AsyncShutdown.profileBeforeChange = getPhase("profile-before-change");
this.AsyncShutdown.placesClosingInternalConnection = getPhase("places-will-close-connection");
- this.AsyncShutdown.sendTelemetry = getPhase("profile-before-change-telemetry");
}
// Notifications that fire in the parent and content process, but should
diff --git a/toolkit/components/asyncshutdown/nsAsyncShutdown.js b/toolkit/components/asyncshutdown/nsAsyncShutdown.js
index bd2c9a2fdf..70fea9076b 100644
--- a/toolkit/components/asyncshutdown/nsAsyncShutdown.js
+++ b/toolkit/components/asyncshutdown/nsAsyncShutdown.js
@@ -230,7 +230,6 @@ function nsAsyncShutdownService() {
"profileBeforeChange",
"profileChangeTeardown",
"quitApplicationGranted",
- "sendTelemetry",
// Child processes
"contentChildShutdown",
diff --git a/toolkit/components/asyncshutdown/nsIAsyncShutdown.idl b/toolkit/components/asyncshutdown/nsIAsyncShutdown.idl
index 216c8047e0..2f8ca50463 100644
--- a/toolkit/components/asyncshutdown/nsIAsyncShutdown.idl
+++ b/toolkit/components/asyncshutdown/nsIAsyncShutdown.idl
@@ -192,11 +192,6 @@ interface nsIAsyncShutdownService: nsISupports {
*/
readonly attribute nsIAsyncShutdownClient quitApplicationGranted;
- /**
- * Barrier for notification profile-before-change-telemetry.
- */
- readonly attribute nsIAsyncShutdownClient sendTelemetry;
-
// Barriers for global shutdown stages in all processes.
diff --git a/toolkit/components/blocklist/nsBlocklistService.js b/toolkit/components/blocklist/nsBlocklistService.js
index fd4e9fee07..188fdfb387 100644
--- a/toolkit/components/blocklist/nsBlocklistService.js
+++ b/toolkit/components/blocklist/nsBlocklistService.js
@@ -740,10 +740,7 @@ Blocklist.prototype = {
return;
}
- let telemetry = Services.telemetry;
-
if (this._isBlocklistPreloaded()) {
- telemetry.getHistogramById("BLOCKLIST_SYNC_FILE_LOAD").add(false);
this._loadBlocklistFromString(this._preloadedBlocklistContent);
delete this._preloadedBlocklistContent;
return;
@@ -754,8 +751,6 @@ Blocklist.prototype = {
return;
}
- telemetry.getHistogramById("BLOCKLIST_SYNC_FILE_LOAD").add(true);
-
let text = "";
let fstream = null;
let cstream = null;
diff --git a/toolkit/components/crashes/CrashManager.jsm b/toolkit/components/crashes/CrashManager.jsm
index 3aac33254a..537ab328d9 100644
--- a/toolkit/components/crashes/CrashManager.jsm
+++ b/toolkit/components/crashes/CrashManager.jsm
@@ -14,7 +14,6 @@ Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
Cu.import("resource://gre/modules/Timer.jsm", this);
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
-Cu.import("resource://gre/modules/TelemetryController.jsm");
Cu.import("resource://gre/modules/KeyValueParser.jsm");
this.EXPORTED_SYMBOLS = [
@@ -64,9 +63,6 @@ function dateToDays(date) {
* storeDir (string)
* Directory we will use for our data store. This instance will write
* data files into the directory specified.
- *
- * telemetryStoreSizeKey (string)
- * Telemetry histogram to report store size under.
*/
this.CrashManager = function (options) {
for (let k of ["pendingDumpsDir", "submittedDumpsDir", "eventsDirs",
@@ -98,10 +94,6 @@ this.CrashManager = function (options) {
this._storeDir = v;
break;
- case "telemetryStoreSizeKey":
- this._telemetryStoreSizeKey = v;
- break;
-
default:
throw new Error("Unknown property in options: " + k);
}
@@ -531,48 +523,6 @@ this.CrashManager.prototype = Object.freeze({
store.addCrash(this.PROCESS_TYPE_MAIN, this.CRASH_TYPE_CRASH,
crashID, date, metadata);
- // If we have a saved environment, use it. Otherwise report
- // the current environment.
- let crashEnvironment = null;
- let sessionId = null;
- let stackTraces = null;
- let reportMeta = Cu.cloneInto(metadata, myScope);
- if ('TelemetryEnvironment' in reportMeta) {
- try {
- crashEnvironment = JSON.parse(reportMeta.TelemetryEnvironment);
- } catch (e) {
- Cu.reportError(e);
- }
- delete reportMeta.TelemetryEnvironment;
- }
- if ('TelemetrySessionId' in reportMeta) {
- sessionId = reportMeta.TelemetrySessionId;
- delete reportMeta.TelemetrySessionId;
- }
- if ('StackTraces' in reportMeta) {
- try {
- stackTraces = JSON.parse(reportMeta.StackTraces);
- } catch (e) {
- Cu.reportError(e);
- }
- delete reportMeta.StackTraces;
- }
- TelemetryController.submitExternalPing("crash",
- {
- version: 1,
- crashDate: date.toISOString().slice(0, 10), // YYYY-MM-DD
- sessionId: sessionId,
- crashId: entry.id,
- stackTraces: stackTraces,
- metadata: reportMeta,
- hasCrashEnvironment: (crashEnvironment !== null),
- },
- {
- retentionDays: 180,
- addClientId: true,
- addEnvironment: true,
- overrideEnvironment: crashEnvironment,
- });
break;
case "crash.submission.1":
@@ -665,8 +615,7 @@ this.CrashManager.prototype = Object.freeze({
unixMode: OS.Constants.libc.S_IRWXU,
});
- let store = new CrashStore(this._storeDir,
- this._telemetryStoreSizeKey);
+ let store = new CrashStore(this._storeDir);
yield store.load();
this._store = store;
@@ -756,13 +705,9 @@ var gCrashManager;
*
* @param storeDir (string)
* Directory the store should be located in.
- * @param telemetrySizeKey (string)
- * The telemetry histogram that should be used to store the size
- * of the data file.
*/
-function CrashStore(storeDir, telemetrySizeKey) {
+function CrashStore(storeDir) {
this._storeDir = storeDir;
- this._telemetrySizeKey = telemetrySizeKey;
this._storePath = OS.Path.join(storeDir, "store.json.mozlz4");
@@ -950,9 +895,6 @@ CrashStore.prototype = Object.freeze({
let size = yield OS.File.writeAtomic(this._storePath, data, {
tmpPath: this._storePath + ".tmp",
compression: "lz4"});
- if (this._telemetrySizeKey) {
- Services.telemetry.getHistogramById(this._telemetrySizeKey).add(size);
- }
}.bind(this));
},
@@ -1209,8 +1151,6 @@ CrashStore.prototype = Object.freeze({
}
submission.requestDate = date;
- Services.telemetry.getKeyedHistogramById("PROCESS_CRASH_SUBMIT_ATTEMPT")
- .add(crash.type, 1);
return true;
},
@@ -1229,8 +1169,6 @@ CrashStore.prototype = Object.freeze({
submission.responseDate = date;
submission.result = result;
- Services.telemetry.getKeyedHistogramById("PROCESS_CRASH_SUBMIT_SUCCESS")
- .add(crash.type, result == "ok");
return true;
},
@@ -1333,7 +1271,6 @@ XPCOMUtils.defineLazyGetter(this.CrashManager, "Singleton", function () {
submittedDumpsDir: OS.Path.join(crPath, "submitted"),
eventsDirs: [OS.Path.join(crPath, "events"), OS.Path.join(storePath, "events")],
storeDir: storePath,
- telemetryStoreSizeKey: "CRASH_STORE_COMPRESSED_BYTES",
});
// Automatically aggregate event files shortly after startup. This
diff --git a/toolkit/components/gfx/SanityTest.js b/toolkit/components/gfx/SanityTest.js
index a563ec3619..03b9067ef5 100644
--- a/toolkit/components/gfx/SanityTest.js
+++ b/toolkit/components/gfx/SanityTest.js
@@ -55,31 +55,6 @@ function testPixel(ctx, x, y, r, g, b, a, fuzz) {
return false;
}
-function reportResult(val) {
- try {
- let histogram = Services.telemetry.getHistogramById("GRAPHICS_SANITY_TEST");
- histogram.add(val);
- } catch (e) {}
-
- Preferences.set(RUNNING_PREF, false);
- Services.prefs.savePrefFile(null);
-}
-
-function reportTestReason(val) {
- let histogram = Services.telemetry.getHistogramById("GRAPHICS_SANITY_TEST_REASON");
- histogram.add(val);
-}
-
-function annotateCrashReport(value) {
- try {
- // "1" if we're annotating the crash report, "" to remove the annotation.
- var crashReporter = Cc['@mozilla.org/toolkit/crash-reporter;1'].
- getService(Ci.nsICrashReporter);
- crashReporter.annotateCrashReport("GraphicsSanityTest", value ? "1" : "");
- } catch (e) {
- }
-}
-
function setTimeout(aMs, aCallback) {
var timer = Cc['@mozilla.org/timer;1'].
createInstance(Ci.nsITimer);
@@ -125,18 +100,15 @@ function testCompositor(win, ctx) {
var testPassed = true;
if (!verifyVideoRendering(ctx)) {
- reportResult(TEST_FAILED_VIDEO);
Preferences.set(DISABLE_VIDEO_PREF, true);
testPassed = false;
}
if (!verifyLayersRendering(ctx)) {
- reportResult(TEST_FAILED_RENDER);
testPassed = false;
}
if (testPassed) {
- reportResult(TEST_PASSED);
}
return testPassed;
@@ -160,7 +132,6 @@ var listener = {
.getInterface(Ci.nsIDOMWindowUtils);
setTimeout(TIMEOUT_SEC * 1000, () => {
if (this.win) {
- reportResult(TEST_TIMEOUT);
this.endTest();
}
});
@@ -227,10 +198,6 @@ var listener = {
this.mm = null;
}
-
- // Remove the annotation after we've cleaned everything up, to catch any
- // incidental crashes from having performed the sanity test.
- annotateCrashReport(false);
}
};
@@ -248,7 +215,6 @@ SanityTest.prototype = {
if (Preferences.get(RUNNING_PREF, false)) {
Preferences.set(DISABLE_VIDEO_PREF, true);
- reportResult(TEST_CRASHED);
return false;
}
@@ -257,11 +223,6 @@ SanityTest.prototype = {
if (prefValue == value) {
return true;
}
- if (prefValue === undefined) {
- reportTestReason(REASON_FIRST_RUN);
- } else {
- reportTestReason(reason);
- }
return false;
}
@@ -296,8 +257,6 @@ SanityTest.prototype = {
if (!this.shouldRunTest()) return;
- annotateCrashReport(true);
-
// Open a tiny window to render our test page, and notify us when it's loaded
var sanityTest = Services.ww.openWindow(null,
"chrome://gfxsanity/content/sanityparent.html",
diff --git a/toolkit/components/osfile/NativeOSFileInternals.cpp b/toolkit/components/osfile/NativeOSFileInternals.cpp
index 36517d9ec7..801c8c37d5 100644
--- a/toolkit/components/osfile/NativeOSFileInternals.cpp
+++ b/toolkit/components/osfile/NativeOSFileInternals.cpp
@@ -169,7 +169,7 @@ public:
* as the AbstractResult is cycle-collected.
*
* @param aStartDate The instant at which the operation was
- * requested. Used to collect Telemetry statistics.
+ * requested.
*/
explicit AbstractResult(TimeStamp aStartDate)
: mStartDate(aStartDate)
@@ -182,7 +182,7 @@ public:
* Setup the AbstractResult once data is available.
*
* @param aDispatchDate The instant at which the IO thread received
- * the operation request. Used to collect Telemetry statistics.
+ * the operation request.
* @param aExecutionDuration The duration of the operation on the
* IO thread.
*/
diff --git a/toolkit/components/osfile/modules/osfile_async_front.jsm b/toolkit/components/osfile/modules/osfile_async_front.jsm
index 698ac87323..826266ce5f 100644
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_async_front.jsm
@@ -434,34 +434,11 @@ var Scheduler = this.Scheduler = {
Scheduler.Debugging.latestReceived = [Date.now(), error.message, error.fileName, error.lineNumber];
throw error;
} finally {
- if (firstLaunch) {
- Scheduler._updateTelemetry();
- }
Scheduler.restartTimer();
}
}.bind(this)));
- },
-
- /**
- * Post Telemetry statistics.
- *
- * This is only useful on first launch.
- */
- _updateTelemetry: function() {
- let worker = this.worker;
- let workerTimeStamps = worker.workerTimeStamps;
- if (!workerTimeStamps) {
- // If the first call to OS.File results in an uncaught errors,
- // the timestamps are absent. As this case is a developer error,
- // let's not waste time attempting to extract telemetry from it.
- return;
- }
- let HISTOGRAM_LAUNCH = Services.telemetry.getHistogramById("OSFILE_WORKER_LAUNCH_MS");
- HISTOGRAM_LAUNCH.add(worker.workerTimeStamps.entered - worker.launchTimeStamp);
-
- let HISTOGRAM_READY = Services.telemetry.getHistogramById("OSFILE_WORKER_READY_MS");
- HISTOGRAM_READY.add(worker.workerTimeStamps.loaded - worker.launchTimeStamp);
}
+
};
const PREF_OSFILE_LOG = "toolkit.osfile.log";
diff --git a/toolkit/components/osfile/modules/osfile_async_worker.js b/toolkit/components/osfile/modules/osfile_async_worker.js
index 84287c75e7..3ae99e7054 100644
--- a/toolkit/components/osfile/modules/osfile_async_worker.js
+++ b/toolkit/components/osfile/modules/osfile_async_worker.js
@@ -12,7 +12,6 @@ if (this.Components) {
(function(exports) {
"use strict";
- // Timestamps, for use in Telemetry.
// The object is set to |null| once it has been sent
// to the main thread.
let timeStamps = {
diff --git a/toolkit/components/parentalcontrols/nsIParentalControlsService.idl b/toolkit/components/parentalcontrols/nsIParentalControlsService.idl
index 45d349addc..b9d49131f5 100644
--- a/toolkit/components/parentalcontrols/nsIParentalControlsService.idl
+++ b/toolkit/components/parentalcontrols/nsIParentalControlsService.idl
@@ -36,8 +36,7 @@ interface nsIParentalControlsService : nsISupports
const short ADVANCED_SETTINGS = 17; // Advanced settings
const short CAMERA_MICROPHONE = 18; // Camera and microphone (WebRTC)
const short BLOCK_LIST = 19; // Block websites that include sensitive content
- const short TELEMETRY = 20; // Submit telemetry data
- const short HEALTH_REPORT = 21; // Submit FHR data
+ // 20 and 21 are unused. Was: Telemetry, FHR
const short DEFAULT_THEME = 22; // Use default theme or a special parental controls theme
/**
diff --git a/toolkit/components/passwordmgr/InsecurePasswordUtils.jsm b/toolkit/components/passwordmgr/InsecurePasswordUtils.jsm
index 5351e45b23..abd7c7fb4c 100644
--- a/toolkit/components/passwordmgr/InsecurePasswordUtils.jsm
+++ b/toolkit/components/passwordmgr/InsecurePasswordUtils.jsm
@@ -145,6 +145,5 @@ this.InsecurePasswordUtils = {
passwordSafety = 5;
}
- Services.telemetry.getHistogramById("PWMGR_LOGIN_PAGE_SAFETY").add(passwordSafety);
},
};
diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm
index 60805530d3..e8dcf8ad38 100644
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1068,8 +1068,6 @@ var LoginManagerContent = {
}
// Nothing to do if we have no matching logins available.
- // Only insecure pages reach this block and logs the same
- // telemetry flag.
if (foundLogins.length == 0) {
// We don't log() here since this is a very common case.
autofillResult = AUTOFILL_RESULT.NO_SAVED_LOGINS;
@@ -1234,9 +1232,6 @@ var LoginManagerContent = {
}
if (!userTriggered) {
- // Ignore fills as a result of user action for this probe.
- Services.telemetry.getHistogramById("PWMGR_FORM_AUTOFILL_RESULT").add(autofillResult);
-
if (usernameField) {
let focusedElement = this._formFillService.focusedInput;
if (usernameField == focusedElement &&
diff --git a/toolkit/components/passwordmgr/content/passwordManager.js b/toolkit/components/passwordmgr/content/passwordManager.js
index de601f4dd8..4db3e81b9a 100644
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -90,7 +90,6 @@ function Startup() {
}
SignonColumnSort(sortField);
- Services.telemetry.getKeyedHistogramById("PWMGR_MANAGE_SORTED").add(sortField);
});
LoadSignons();
@@ -100,9 +99,6 @@ function Startup() {
window.arguments[0] &&
window.arguments[0].filterString) {
setFilter(window.arguments[0].filterString);
- Services.telemetry.getHistogramById("PWMGR_MANAGE_OPENED").add(1);
- } else {
- Services.telemetry.getHistogramById("PWMGR_MANAGE_OPENED").add(0);
}
FocusFilterBox();
@@ -434,7 +430,6 @@ function DeleteAllSignons() {
removeButton.setAttribute("disabled", "true");
removeAllButton.setAttribute("disabled", "true");
FinalizeSignonDeletions(syncNeeded);
- Services.telemetry.getHistogramById("PWMGR_MANAGE_DELETED_ALL").add(1);
}
function TogglePasswordVisible() {
@@ -449,7 +444,6 @@ function TogglePasswordVisible() {
// Notify observers that the password visibility toggling is
// completed. (Mostly useful for tests)
Services.obs.notifyObservers(null, "passwordmgr-password-toggle-complete", null);
- Services.telemetry.getHistogramById("PWMGR_MANAGE_VISIBILITY_TOGGLED").add(showingPasswords);
}
function AskUserShowPasswords() {
@@ -466,7 +460,6 @@ function AskUserShowPasswords() {
function FinalizeSignonDeletions(syncNeeded) {
for (let s = 0; s < deletedSignons.length; s++) {
Services.logins.removeLogin(deletedSignons[s]);
- Services.telemetry.getHistogramById("PWMGR_MANAGE_DELETED").add(1);
}
// If the deletion has been performed in a filtered view, reflect the deletion in the unfiltered table.
// See bug 405389.
@@ -640,7 +633,6 @@ function CopyPassword() {
let row = signonsTree.currentIndex;
let password = signonsTreeView.getCellText(row, {id : "passwordCol" });
clipboard.copyString(password);
- Services.telemetry.getHistogramById("PWMGR_MANAGE_COPIED_PASSWORD").add(1);
}
function CopyUsername() {
@@ -650,7 +642,6 @@ function CopyUsername() {
let row = signonsTree.currentIndex;
let username = signonsTreeView.getCellText(row, {id : "userCol" });
clipboard.copyString(username);
- Services.telemetry.getHistogramById("PWMGR_MANAGE_COPIED_USERNAME").add(1);
}
function EditCellInSelectedRow(columnName) {
@@ -729,7 +720,7 @@ function escapeKeyHandler() {
#if defined(MC_BASILISK) || defined(HYPE_ICEWEASEL)
function OpenMigrator() {
const { MigrationUtils } = Cu.import("resource:///modules/MigrationUtils.jsm", {});
- // We pass in the type of source we're using for use in telemetry:
+ // We pass in the type of source we're using:
MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_PASSWORDS]);
}
#endif
diff --git a/toolkit/components/passwordmgr/nsLoginManager.js b/toolkit/components/passwordmgr/nsLoginManager.js
index 84b0319cb5..7d249ab9e6 100644
--- a/toolkit/components/passwordmgr/nsLoginManager.js
+++ b/toolkit/components/passwordmgr/nsLoginManager.js
@@ -107,7 +107,6 @@ LoginManager.prototype = {
this._initStorage();
}
- Services.obs.addObserver(this._observer, "gather-telemetry", false);
},
@@ -168,91 +167,17 @@ LoginManager.prototype = {
Services.obs.notifyObservers(null,
"passwordmgr-storage-replace-complete", null);
}.bind(this));
- } else if (topic == "gather-telemetry") {
- // When testing, the "data" parameter is a string containing the
- // reference time in milliseconds for time-based statistics.
- this._pwmgr._gatherTelemetry(data ? parseInt(data)
- : new Date().getTime());
} else {
log.debug("Oops! Unexpected notification:", topic);
}
}
},
- /**
- * Collects statistics about the current logins and settings. The telemetry
- * histograms used here are not accumulated, but are reset each time this
- * function is called, since it can be called multiple times in a session.
- *
- * This function might also not be called at all in the current session.
- *
- * @param referenceTimeMs
- * Current time used to calculate time-based statistics, expressed as
- * the number of milliseconds since January 1, 1970, 00:00:00 UTC.
- * This is set to a fake value during unit testing.
- */
- _gatherTelemetry(referenceTimeMs) {
- function clearAndGetHistogram(histogramId) {
- let histogram = Services.telemetry.getHistogramById(histogramId);
- histogram.clear();
- return histogram;
- }
-
- clearAndGetHistogram("PWMGR_BLOCKLIST_NUM_SITES").add(
- this.getAllDisabledHosts({}).length
- );
- clearAndGetHistogram("PWMGR_NUM_SAVED_PASSWORDS").add(
- this.countLogins("", "", "")
- );
- clearAndGetHistogram("PWMGR_NUM_HTTPAUTH_PASSWORDS").add(
- this.countLogins("", null, "")
- );
-
- // This is a boolean histogram, and not a flag, because we don't want to
- // record any value if _gatherTelemetry is not called.
- clearAndGetHistogram("PWMGR_SAVING_ENABLED").add(this._remember);
-
- // Don't try to get logins if MP is enabled, since we don't want to show a MP prompt.
- if (!this.isLoggedIn) {
- return;
- }
-
- let logins = this.getAllLogins({});
-
- let usernamePresentHistogram = clearAndGetHistogram("PWMGR_USERNAME_PRESENT");
- let loginLastUsedDaysHistogram = clearAndGetHistogram("PWMGR_LOGIN_LAST_USED_DAYS");
-
- let hostnameCount = new Map();
- for (let login of logins) {
- usernamePresentHistogram.add(!!login.username);
-
- let hostname = login.hostname;
- hostnameCount.set(hostname, (hostnameCount.get(hostname) || 0 ) + 1);
-
- login.QueryInterface(Ci.nsILoginMetaInfo);
- let timeLastUsedAgeMs = referenceTimeMs - login.timeLastUsed;
- if (timeLastUsedAgeMs > 0) {
- loginLastUsedDaysHistogram.add(
- Math.floor(timeLastUsedAgeMs / MS_PER_DAY)
- );
- }
- }
-
- let passwordsCountHistogram = clearAndGetHistogram("PWMGR_NUM_PASSWORDS_PER_HOSTNAME");
- for (let count of hostnameCount.values()) {
- passwordsCountHistogram.add(count);
- }
- },
-
-
-
/* ---------- Primary Public interfaces ---------- */
-
-
/**
* @type Promise
* This promise is resolved when initialization is complete, and is rejected
diff --git a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
index 5fb1ee83e6..7adabf2147 100644
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -19,14 +19,6 @@ const LoginInfo =
const BRAND_BUNDLE = "chrome://branding/locale/brand.properties";
/**
- * Constants for password prompt telemetry. */
-const PROMPT_DISPLAYED = 0;
-
-const PROMPT_ADD_OR_UPDATE = 1;
-const PROMPT_NOTNOW = 2;
-const PROMPT_NEVER = 3;
-
-/**
* Implements nsIPromptFactory
*
* Invoked by [toolkit/components/prompts/src/nsPrompter.js]
@@ -825,7 +817,7 @@ LoginManagerPrompter.prototype = {
* new password.
* @param {string} type
* This is "password-save" or "password-change" depending on the
- * original notification type. This is used for telemetry and tests.
+ * original notification type. This is used for tests.
*/
_showLoginCaptureDoorhanger(login, type) {
let { browser } = this._getNotifyWindow();
@@ -855,11 +847,6 @@ LoginManagerPrompter.prototype = {
let promptMsg = type == "password-save" ? this._getLocalizedString(saveMsgNames.prompt, [brandShortName])
: this._getLocalizedString(changeMsgNames.prompt);
- let histogramName = type == "password-save" ? "PWMGR_PROMPT_REMEMBER_ACTION"
- : "PWMGR_PROMPT_UPDATE_ACTION";
- let histogram = Services.telemetry.getHistogramById(histogramName);
- histogram.add(PROMPT_DISPLAYED);
-
let chromeDoc = browser.ownerDocument;
let currentNotification;
@@ -986,10 +973,6 @@ LoginManagerPrompter.prototype = {
label: this._getLocalizedString(initialMsgNames.buttonLabel),
accessKey: this._getLocalizedString(initialMsgNames.buttonAccessKey),
callback: () => {
- histogram.add(PROMPT_ADD_OR_UPDATE);
- if (histogramName == "PWMGR_PROMPT_REMEMBER_ACTION") {
- Services.obs.notifyObservers(null, 'LoginStats:NewSavedPassword', null);
- }
readDataFromUI();
persistData();
browser.focus();
@@ -1001,7 +984,6 @@ LoginManagerPrompter.prototype = {
label: this._getLocalizedString("notifyBarNeverRememberButtonText"),
accessKey: this._getLocalizedString("notifyBarNeverRememberButtonAccessKey"),
callback: () => {
- histogram.add(PROMPT_NEVER);
Services.logins.setLoginSavingEnabled(login.hostname, false);
browser.focus();
}
diff --git a/toolkit/components/perfmonitoring/AddonWatcher.jsm b/toolkit/components/perfmonitoring/AddonWatcher.jsm
index 58decba857..e5b95d1d80 100644
--- a/toolkit/components/perfmonitoring/AddonWatcher.jsm
+++ b/toolkit/components/perfmonitoring/AddonWatcher.jsm
@@ -19,9 +19,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/Console.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PerformanceWatcher",
"resource://gre/modules/PerformanceWatcher.jsm");
-XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
- "@mozilla.org/base/telemetry;1",
- Ci.nsITelemetry);
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "IdleService",
@@ -123,15 +120,6 @@ this.AddonWatcher = {
return;
}
- // Report immediately to Telemetry, regardless of whether we report to
- // the user.
- for (let {source: {addonId}, details} of addons) {
- Telemetry.getKeyedHistogramById("PERF_MONITORING_SLOW_ADDON_JANK_US").
- add(addonId, details.highestJank);
- Telemetry.getKeyedHistogramById("PERF_MONITORING_SLOW_ADDON_CPOW_US").
- add(addonId, details.highestCPOW);
- }
-
// We expect that users don't care about real-time alerts unless their
// browser is going very, very slowly. Therefore, we use the following
// heuristic:
diff --git a/toolkit/components/places/BookmarkHTMLUtils.jsm b/toolkit/components/places/BookmarkHTMLUtils.jsm
index c10ef85d60..6b4ea79340 100644
--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -220,14 +220,6 @@ this.BookmarkHTMLUtils = Object.freeze({
let exporter = new BookmarkExporter(bookmarks);
yield exporter.exportToFile(aFilePath);
- try {
- Services.telemetry
- .getHistogramById("PLACES_EXPORT_TOHTML_MS")
- .add(Date.now() - startTime);
- } catch (ex) {
- Components.utils.reportError("Unable to report telemetry.");
- }
-
return count;
});
},
diff --git a/toolkit/components/places/BookmarkJSONUtils.jsm b/toolkit/components/places/BookmarkJSONUtils.jsm
index 7f8d3fd8f5..f212ba07db 100644
--- a/toolkit/components/places/BookmarkJSONUtils.jsm
+++ b/toolkit/components/places/BookmarkJSONUtils.jsm
@@ -144,14 +144,6 @@ this.BookmarkJSONUtils = Object.freeze({
let [bookmarks, count] = yield PlacesBackups.getBookmarksTree();
let startTime = Date.now();
let jsonString = JSON.stringify(bookmarks);
- // Report the time taken to convert the tree to JSON.
- try {
- Services.telemetry
- .getHistogramById("PLACES_BACKUPS_TOJSON_MS")
- .add(Date.now() - startTime);
- } catch (ex) {
- Components.utils.reportError("Unable to report telemetry.");
- }
let hash = generateHash(jsonString);
diff --git a/toolkit/components/places/PlacesBackups.jsm b/toolkit/components/places/PlacesBackups.jsm
index 8315aeb3ac..3cf89d530a 100644
--- a/toolkit/components/places/PlacesBackups.jsm
+++ b/toolkit/components/places/PlacesBackups.jsm
@@ -1,5 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=2 sts=2 expandtab filetype=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/. */
@@ -537,13 +536,6 @@ this.PlacesBackups = {
includeItemIds: true
});
- try {
- Services.telemetry
- .getHistogramById("PLACES_BACKUPS_BOOKMARKSTREE_MS")
- .add(Date.now() - startTime);
- } catch (ex) {
- Components.utils.reportError("Unable to report telemetry.");
- }
return [root, root.itemsCount];
})
}
diff --git a/toolkit/components/places/PlacesCategoriesStarter.js b/toolkit/components/places/PlacesCategoriesStarter.js
index bab14db52d..dd0ff2a252 100644
--- a/toolkit/components/places/PlacesCategoriesStarter.js
+++ b/toolkit/components/places/PlacesCategoriesStarter.js
@@ -1,5 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=2 sts=2 expandtab
* 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/. */
@@ -10,9 +9,6 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
-// Fired by TelemetryController when async telemetry data should be collected.
-const TOPIC_GATHER_TELEMETRY = "gather-telemetry";
-
// Seconds between maintenance runs.
const MAINTENANCE_INTERVAL_SECONDS = 7 * 86400;
@@ -30,7 +26,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesDBUtils",
*/
function PlacesCategoriesStarter()
{
- Services.obs.addObserver(this, TOPIC_GATHER_TELEMETRY, false);
Services.obs.addObserver(this, PlacesUtils.TOPIC_SHUTDOWN, false);
// nsINavBookmarkObserver implementation.
@@ -63,7 +58,6 @@ PlacesCategoriesStarter.prototype = {
switch (aTopic) {
case PlacesUtils.TOPIC_SHUTDOWN:
Services.obs.removeObserver(this, PlacesUtils.TOPIC_SHUTDOWN);
- Services.obs.removeObserver(this, TOPIC_GATHER_TELEMETRY);
let globalObj =
Cu.getGlobalForObject(PlacesCategoriesStarter.prototype);
let descriptor =
@@ -72,9 +66,6 @@ PlacesCategoriesStarter.prototype = {
PlacesDBUtils.shutdown();
}
break;
- case TOPIC_GATHER_TELEMETRY:
- PlacesDBUtils.telemetry();
- break;
case "idle-daily":
// Once a week run places.sqlite maintenance tasks.
let lastMaintenance =
diff --git a/toolkit/components/places/PlacesDBUtils.jsm b/toolkit/components/places/PlacesDBUtils.jsm
index 4ac6ea2610..cfb38db70b 100644
--- a/toolkit/components/places/PlacesDBUtils.jsm
+++ b/toolkit/components/places/PlacesDBUtils.jsm
@@ -1,5 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=2 sts=2 expandtab filetype=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/. */
@@ -51,13 +50,6 @@ this.PlacesDBUtils = {
}
else {
// All tasks have been completed.
- // Telemetry the time it took for maintenance, if a start time exists.
- if (aTasks._telemetryStart) {
- Services.telemetry.getHistogramById("PLACES_IDLE_MAINTENANCE_TIME_MS")
- .add(Date.now() - aTasks._telemetryStart);
- aTasks._telemetryStart = 0;
- }
-
if (aTasks.callback) {
let scope = aTasks.scope || Cu.getGlobalForObject(aTasks.callback);
aTasks.callback.call(scope, aTasks.messages);
@@ -89,7 +81,6 @@ this.PlacesDBUtils = {
, this.checkCoherence
, this._refreshUI
]);
- tasks._telemetryStart = Date.now();
tasks.callback = function() {
Services.prefs.setIntPref("places.database.lastMaintenance",
parseInt(Date.now() / 1000));
@@ -857,181 +848,6 @@ this.PlacesDBUtils = {
},
/**
- * Collects telemetry data and reports it to Telemetry.
- *
- * @param [optional] aTasks
- * Tasks object to execute.
- */
- telemetry: function PDBU_telemetry(aTasks)
- {
- let tasks = new Tasks(aTasks);
-
- // This will be populated with one integer property for each probe result,
- // using the histogram name as key.
- let probeValues = {};
-
- // The following array contains an ordered list of entries that are
- // processed to collect telemetry data. Each entry has these properties:
- //
- // histogram: Name of the telemetry histogram to update.
- // query: This is optional. If present, contains a database command
- // that will be executed asynchronously, and whose result will
- // be added to the telemetry histogram.
- // callback: This is optional. If present, contains a function that must
- // return the value that will be added to the telemetry
- // histogram. If a query is also present, its result is passed
- // as the first argument of the function. If the function
- // raises an exception, no data is added to the histogram.
- //
- // Since all queries are executed in order by the database backend, the
- // callbacks can also use the result of previous queries stored in the
- // probeValues object.
- let probes = [
- { histogram: "PLACES_PAGES_COUNT",
- query: "SELECT count(*) FROM moz_places" },
-
- { histogram: "PLACES_BOOKMARKS_COUNT",
- query: `SELECT count(*) FROM moz_bookmarks b
- JOIN moz_bookmarks t ON t.id = b.parent
- AND t.parent <> :tags_folder
- WHERE b.type = :type_bookmark` },
-
- { histogram: "PLACES_TAGS_COUNT",
- query: `SELECT count(*) FROM moz_bookmarks
- WHERE parent = :tags_folder` },
-
- { histogram: "PLACES_KEYWORDS_COUNT",
- query: "SELECT count(*) FROM moz_keywords" },
-
- { histogram: "PLACES_SORTED_BOOKMARKS_PERC",
- query: `SELECT IFNULL(ROUND((
- SELECT count(*) FROM moz_bookmarks b
- JOIN moz_bookmarks t ON t.id = b.parent
- AND t.parent <> :tags_folder AND t.parent > :places_root
- WHERE b.type = :type_bookmark
- ) * 100 / (
- SELECT count(*) FROM moz_bookmarks b
- JOIN moz_bookmarks t ON t.id = b.parent
- AND t.parent <> :tags_folder
- WHERE b.type = :type_bookmark
- )), 0)` },
-
- { histogram: "PLACES_TAGGED_BOOKMARKS_PERC",
- query: `SELECT IFNULL(ROUND((
- SELECT count(*) FROM moz_bookmarks b
- JOIN moz_bookmarks t ON t.id = b.parent
- AND t.parent = :tags_folder
- ) * 100 / (
- SELECT count(*) FROM moz_bookmarks b
- JOIN moz_bookmarks t ON t.id = b.parent
- AND t.parent <> :tags_folder
- WHERE b.type = :type_bookmark
- )), 0)` },
-
- { histogram: "PLACES_DATABASE_FILESIZE_MB",
- callback: function () {
- let DBFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
- DBFile.append("places.sqlite");
- return parseInt(DBFile.fileSize / BYTES_PER_MEBIBYTE);
- }
- },
-
- { histogram: "PLACES_DATABASE_PAGESIZE_B",
- query: "PRAGMA page_size /* PlacesDBUtils.jsm PAGESIZE_B */" },
-
- { histogram: "PLACES_DATABASE_SIZE_PER_PAGE_B",
- query: "PRAGMA page_count",
- callback: function (aDbPageCount) {
- // Note that the database file size would not be meaningful for this
- // calculation, because the file grows in fixed-size chunks.
- let dbPageSize = probeValues.PLACES_DATABASE_PAGESIZE_B;
- let placesPageCount = probeValues.PLACES_PAGES_COUNT;
- return Math.round((dbPageSize * aDbPageCount) / placesPageCount);
- }
- },
-
- { histogram: "PLACES_ANNOS_BOOKMARKS_COUNT",
- query: "SELECT count(*) FROM moz_items_annos" },
-
- { histogram: "PLACES_ANNOS_PAGES_COUNT",
- query: "SELECT count(*) FROM moz_annos" },
-
- { histogram: "PLACES_MAINTENANCE_DAYSFROMLAST",
- callback: function () {
- try {
- let lastMaintenance = Services.prefs.getIntPref("places.database.lastMaintenance");
- let nowSeconds = parseInt(Date.now() / 1000);
- return parseInt((nowSeconds - lastMaintenance) / 86400);
- } catch (ex) {
- return 60;
- }
- }
- },
- ];
-
- let params = {
- tags_folder: PlacesUtils.tagsFolderId,
- type_folder: PlacesUtils.bookmarks.TYPE_FOLDER,
- type_bookmark: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- places_root: PlacesUtils.placesRootId
- };
-
- for (let i = 0; i < probes.length; i++) {
- let probe = probes[i];
-
- let promiseDone = new Promise((resolve, reject) => {
- if (!("query" in probe)) {
- resolve([probe]);
- return;
- }
-
- let stmt = DBConn.createAsyncStatement(probe.query);
- for (let param in params) {
- if (probe.query.indexOf(":" + param) > 0) {
- stmt.params[param] = params[param];
- }
- }
-
- try {
- stmt.executeAsync({
- handleError: reject,
- handleResult: function (aResultSet) {
- let row = aResultSet.getNextRow();
- resolve([probe, row.getResultByIndex(0)]);
- },
- handleCompletion: function () {}
- });
- } finally {
- stmt.finalize();
- }
- });
-
- // Report the result of the probe through Telemetry.
- // The resulting promise cannot reject.
- promiseDone.then(
- // On success
- ([aProbe, aValue]) => {
- let value = aValue;
- try {
- if ("callback" in aProbe) {
- value = aProbe.callback(value);
- }
- probeValues[aProbe.histogram] = value;
- Services.telemetry.getHistogramById(aProbe.histogram).add(value);
- } catch (ex) {
- Components.utils.reportError("Error adding value " + value +
- " to histogram " + aProbe.histogram +
- ": " + ex);
- }
- },
- // On failure
- this._handleError);
- }
-
- PlacesDBUtils._executeTasks(tasks);
- },
-
- /**
* Runs a list of tasks, notifying log messages to the callback.
*
* @param aTasks
@@ -1068,7 +884,6 @@ function Tasks(aTasks)
this._log = aTasks.messages;
this.callback = aTasks.callback;
this.scope = aTasks.scope;
- this._telemetryStart = aTasks._telemetryStart;
}
}
}
@@ -1078,7 +893,6 @@ Tasks.prototype = {
_log: [],
callback: null,
scope: null,
- _telemetryStart: 0,
/**
* Adds a task to the top of the list.
diff --git a/toolkit/components/places/UnifiedComplete.js b/toolkit/components/places/UnifiedComplete.js
index 7b63e29bb4..3cce88b389 100644
--- a/toolkit/components/places/UnifiedComplete.js
+++ b/toolkit/components/places/UnifiedComplete.js
@@ -1,5 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=2 sts=2 expandtab
* 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/. */
@@ -58,9 +57,6 @@ const QUERYTYPE_AUTOFILL_URL = 2;
// "comment" back into the title and the tag.
const TITLE_TAGS_SEPARATOR = " \u2013 ";
-// Telemetry probes.
-const TELEMETRY_1ST_RESULT = "PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS";
-const TELEMETRY_6_FIRST_RESULTS = "PLACES_AUTOCOMPLETE_6_FIRST_RESULTS_TIME_MS";
// The default frecency value used when inserting matches with unknown frecency.
const FRECENCY_DEFAULT = 1000;
diff --git a/toolkit/components/places/nsPlacesAutoComplete.js b/toolkit/components/places/nsPlacesAutoComplete.js
index 9c6452ecd6..88de3a1f9f 100644
--- a/toolkit/components/places/nsPlacesAutoComplete.js
+++ b/toolkit/components/places/nsPlacesAutoComplete.js
@@ -81,9 +81,6 @@ const kBrowserUrlbarAutofillPref = "autoFill";
// Whether to search only typed entries.
const kBrowserUrlbarAutofillTypedPref = "autoFill.typed";
-// The Telemetry histogram for urlInlineComplete query on domain
-const DOMAIN_QUERY_TELEMETRY = "PLACES_AUTOCOMPLETE_URLINLINE_DOMAIN_QUERY_TIME_MS";
-
////////////////////////////////////////////////////////////////////////////////
//// Globals
@@ -553,7 +550,6 @@ nsPlacesAutoComplete.prototype = {
queries.push(query);
// Start executing our queries.
- this._telemetryStartTime = Date.now();
this._executeQueries(queries);
// Set up our persistent state for the duration of the search.
@@ -810,19 +806,6 @@ nsPlacesAutoComplete.prototype = {
}
result.setSearchResult(Ci.nsIAutoCompleteResult[resultCode]);
this._listener.onSearchResult(this, result);
- if (this._telemetryStartTime) {
- let elapsed = Date.now() - this._telemetryStartTime;
- if (elapsed > 50) {
- try {
- Services.telemetry
- .getHistogramById("PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS")
- .add(elapsed);
- } catch (ex) {
- Components.utils.reportError("Unable to report telemetry.");
- }
- }
- this._telemetryStartTime = null;
- }
},
/**
diff --git a/toolkit/components/places/nsPlacesExpiration.js b/toolkit/components/places/nsPlacesExpiration.js
index 767a4d3458..0f376626da 100644
--- a/toolkit/components/places/nsPlacesExpiration.js
+++ b/toolkit/components/places/nsPlacesExpiration.js
@@ -1,5 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=2 sts=2 expandtab
* 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/. */
@@ -708,22 +707,12 @@ nsPlacesExpiration.prototype = {
aError.result + "', '" + aError.message + "'");
},
- // Number of expiration steps needed to reach a CLEAN status.
- _telemetrySteps: 1,
handleCompletion: function PEX_handleCompletion(aReason)
{
if (aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED) {
if (this._mostRecentExpiredVisitDays) {
- try {
- Services.telemetry
- .getHistogramById("PLACES_MOST_RECENT_EXPIRED_VISIT_DAYS")
- .add(this._mostRecentExpiredVisitDays);
- } catch (ex) {
- Components.utils.reportError("Unable to report telemetry.");
- } finally {
- delete this._mostRecentExpiredVisitDays;
- }
+ delete this._mostRecentExpiredVisitDays;
}
if ("_expectedResultsCount" in this) {
@@ -734,25 +723,6 @@ nsPlacesExpiration.prototype = {
this.status = this._expectedResultsCount == 0 ? STATUS.DIRTY
: STATUS.CLEAN;
- // Collect or send telemetry data.
- if (this.status == STATUS.DIRTY) {
- this._telemetrySteps++;
- }
- else {
- // Avoid reporting the common cases where the database is clean, or
- // a single step is needed.
- if (oldStatus == STATUS.DIRTY) {
- try {
- Services.telemetry
- .getHistogramById("PLACES_EXPIRATION_STEPS_TO_CLEAN2")
- .add(this._telemetrySteps);
- } catch (ex) {
- Components.utils.reportError("Unable to report telemetry.");
- }
- }
- this._telemetrySteps = 1;
- }
-
delete this._expectedResultsCount;
}
diff --git a/toolkit/components/printing/content/printUtils.js b/toolkit/components/printing/content/printUtils.js
index 4169541880..62602396c3 100644
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -198,9 +198,6 @@ var PrintUtils = {
this._sourceBrowser = aListenerObj.getSourceBrowser();
this._originalTitle = this._sourceBrowser.contentTitle;
this._originalURL = this._sourceBrowser.currentURI.spec;
-
- // Here we log telemetry data for when the user enters print preview.
- this.logTelemetry("PRINT_PREVIEW_OPENED_COUNT");
} else {
// collapse the browser here -- it will be shown in
// enterPrintPreview; this forces a reflow which fixes display
@@ -536,9 +533,6 @@ var PrintUtils = {
URL: this._originalURL,
windowID: this._sourceBrowser.outerWindowID,
});
-
- // Here we log telemetry data for when the user enters simplify mode.
- this.logTelemetry("PRINT_PREVIEW_SIMPLIFY_PAGE_OPENED_COUNT");
}
} else {
sendEnterPreviewMessage(this._sourceBrowser, false);
@@ -597,7 +591,6 @@ var PrintUtils = {
if (this._sourceBrowser.isArticle) {
printPreviewTB.enableSimplifyPage();
} else {
- this.logTelemetry("PRINT_PREVIEW_SIMPLIFY_PAGE_UNAVAILABLE_COUNT");
printPreviewTB.disableSimplifyPage();
}
@@ -652,12 +645,6 @@ var PrintUtils = {
this._listener.onExit();
},
- logTelemetry: function (ID)
- {
- let histogram = Services.telemetry.getHistogramById(ID);
- histogram.add(true);
- },
-
onKeyDownPP: function (aEvent)
{
// Esc exits the PP
diff --git a/toolkit/components/terminator/terminator.manifest b/toolkit/components/terminator/terminator.manifest
index c1757ba86a..33cb143de9 100644
--- a/toolkit/components/terminator/terminator.manifest
+++ b/toolkit/components/terminator/terminator.manifest
@@ -1,5 +1 @@
category profile-after-change nsTerminator @mozilla.org/toolkit/shutdown-terminator;1
-
-component {3f78ada1-cba2-442a-82dd-d5fb300ddea7} nsTerminatorTelemetry.js
-contract @mozilla.org/toolkit/shutdown-terminator-telemetry;1 {3f78ada1-cba2-442a-82dd-d5fb300ddea7}
-category profile-after-change nsTerminatorTelemetry @mozilla.org/toolkit/shutdown-terminator-telemetry;1
diff --git a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
index 3ed32665de..77b7c8e2ca 100644
--- a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
+++ b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
@@ -10,8 +10,6 @@ const DEFAULT_CAPTURE_TIMEOUT = 30000; // ms
const DESTROY_BROWSER_TIMEOUT = 60000; // ms
const FRAME_SCRIPT_URL = "chrome://global/content/backgroundPageThumbsContent.js";
-const TELEMETRY_HISTOGRAM_ID_PREFIX = "FX_THUMBNAILS_BG_";
-
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const HTML_NS = "http://www.w3.org/1999/xhtml";
@@ -22,19 +20,6 @@ Cu.import("resource://gre/modules/PageThumbs.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
-// possible FX_THUMBNAILS_BG_CAPTURE_DONE_REASON_2 telemetry values
-const TEL_CAPTURE_DONE_OK = 0;
-const TEL_CAPTURE_DONE_TIMEOUT = 1;
-// 2 and 3 were used when we had special handling for private-browsing.
-const TEL_CAPTURE_DONE_CRASHED = 4;
-const TEL_CAPTURE_DONE_BAD_URI = 5;
-
-// These are looked up on the global as properties below.
-XPCOMUtils.defineConstant(this, "TEL_CAPTURE_DONE_OK", TEL_CAPTURE_DONE_OK);
-XPCOMUtils.defineConstant(this, "TEL_CAPTURE_DONE_TIMEOUT", TEL_CAPTURE_DONE_TIMEOUT);
-XPCOMUtils.defineConstant(this, "TEL_CAPTURE_DONE_CRASHED", TEL_CAPTURE_DONE_CRASHED);
-XPCOMUtils.defineConstant(this, "TEL_CAPTURE_DONE_BAD_URI", TEL_CAPTURE_DONE_BAD_URI);
-
const global = this;
// contains base64 version of a placeholder thumbnail
@@ -67,8 +52,6 @@ const BackgroundPageThumbs = {
this._captureQueue = this._captureQueue || [];
this._capturesByURL = this._capturesByURL || new Map();
- tel("QUEUE_SIZE_ON_CAPTURE", this._captureQueue.length);
-
// We want to avoid duplicate captures for the same URL. If there is an
// existing one, we just add the callback to that one and we are done.
let existing = this._capturesByURL.get(url);
@@ -237,7 +220,7 @@ const BackgroundPageThumbs = {
// listener. Trying to send a message to the manager in that case
// throws NS_ERROR_NOT_INITIALIZED.
Services.tm.currentThread.dispatch(() => {
- curCapture._done(null, TEL_CAPTURE_DONE_CRASHED);
+ curCapture._done(null);
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
}
// else: we must have been idle and not currently doing a capture (eg,
@@ -286,9 +269,6 @@ const BackgroundPageThumbs = {
throw new Error("The capture should be at the head of the queue.");
this._captureQueue.shift();
this._capturesByURL.delete(capture.url);
- if (capture.doneReason != TEL_CAPTURE_DONE_OK) {
- Services.obs.notifyObservers(null, "page-thumbnail:error", capture.url);
- }
// Start the destroy-browser timer *before* processing the capture queue.
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
@@ -324,7 +304,6 @@ function Capture(url, captureCallback, options) {
this.id = Capture.nextID++;
this.creationDate = new Date();
this.doneCallbacks = [];
- this.doneReason;
if (options.onDone)
this.doneCallbacks.push(options.onDone);
}
@@ -342,7 +321,6 @@ Capture.prototype = {
*/
start: function (messageManager) {
this.startDate = new Date();
- tel("CAPTURE_QUEUE_TIME_MS", this.startDate - this.creationDate);
// timeout timer
let timeout;
@@ -386,46 +364,30 @@ Capture.prototype = {
// Called when the didCapture message is received.
receiveMessage: function (msg) {
- if (msg.data.imageData)
- tel("CAPTURE_SERVICE_TIME_MS", new Date() - this.startDate);
-
// A different timed-out capture may have finally successfully completed, so
// discard messages that aren't meant for this capture.
if (msg.data.id != this.id)
return;
if (msg.data.failReason) {
- let reason = global["TEL_CAPTURE_DONE_" + msg.data.failReason];
- this._done(null, reason);
+ this._done(null);
return;
}
- this._done(msg.data, TEL_CAPTURE_DONE_OK);
+ this._done(msg.data);
},
// Called when the timeout timer fires.
notify: function () {
- this._done(null, TEL_CAPTURE_DONE_TIMEOUT);
+ this._done(null);
},
- _done: function (data, reason) {
+ _done: function (data) {
// Note that _done will be called only once, by either receiveMessage or
// notify, since it calls destroy here, which cancels the timeout timer and
// removes the didCapture message listener.
let { captureCallback, doneCallbacks, options } = this;
this.destroy();
- this.doneReason = reason;
-
- if (typeof(reason) != "number") {
- throw new Error("A done reason must be given.");
- }
- tel("CAPTURE_DONE_REASON_2", reason);
- if (data && data.telemetry) {
- // Telemetry is currently disabled in the content process (bug 680508).
- for (let id in data.telemetry) {
- tel(id, data.telemetry[id]);
- }
- }
let done = () => {
captureCallback(this);
@@ -454,17 +416,6 @@ Capture.prototype = {
Capture.nextID = 0;
-/**
- * Adds a value to one of this module's telemetry histograms.
- *
- * @param histogramID This is prefixed with this module's ID.
- * @param value The value to add.
- */
-function tel(histogramID, value) {
- let id = TELEMETRY_HISTOGRAM_ID_PREFIX + histogramID;
- Services.telemetry.getHistogramById(id).add(value);
-}
-
function schedule(callback) {
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
}
diff --git a/toolkit/components/thumbnails/PageThumbs.jsm b/toolkit/components/thumbnails/PageThumbs.jsm
index b0affee928..714bbbb77a 100644
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -215,14 +215,10 @@ this.PageThumbs = {
* fullScale - request that a non-downscaled image be returned.
*/
captureToCanvas: function (aBrowser, aCanvas, aCallback, aArgs) {
- let telemetryCaptureTime = new Date();
let args = {
fullScale: aArgs ? aArgs.fullScale : false
};
this._captureToCanvas(aBrowser, aCanvas, args, (aCanvas) => {
- Services.telemetry
- .getHistogramById("FX_THUMBNAILS_CAPTURE_TIME_MS")
- .add(new Date() - telemetryCaptureTime);
if (aCallback) {
aCallback(aCanvas);
}
@@ -450,10 +446,7 @@ this.PageThumbs = {
*/
_store: function PageThumbs__store(aOriginalURL, aFinalURL, aData, aNoOverwrite) {
return Task.spawn(function* () {
- let telemetryStoreTime = new Date();
yield PageThumbsStorage.writeData(aFinalURL, aData, aNoOverwrite);
- Services.telemetry.getHistogramById("FX_THUMBNAILS_STORE_TIME_MS")
- .add(new Date() - telemetryStoreTime);
Services.obs.notifyObservers(null, "page-thumbnail:create", aFinalURL);
// We've been redirected. Create a copy of the current thumbnail for
diff --git a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
index 2103833b7b..ab39e73f72 100644
--- a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
+++ b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
@@ -169,10 +169,6 @@ const backgroundPageThumbsContent = {
id: capture.id,
imageData: fileReader.result,
finalURL: capture.finalURL,
- telemetry: {
- CAPTURE_PAGE_LOAD_TIME_MS: capture.pageLoadTime,
- CAPTURE_CANVAS_DRAW_TIME_MS: capture.canvasDrawTime,
- },
});
};
fileReader.readAsArrayBuffer(capture.imageBlob);
diff --git a/toolkit/components/viewsource/content/viewSourceUtils.js b/toolkit/components/viewsource/content/viewSourceUtils.js
index 11b39ca54b..72f5dd787a 100644
--- a/toolkit/components/viewsource/content/viewSourceUtils.js
+++ b/toolkit/components/viewsource/content/viewSourceUtils.js
@@ -90,9 +90,6 @@ var gViewSourceUtils = {
* The line number to focus on once the source is loaded.
*/
viewSourceInBrowser: function(aArgs) {
- Services.telemetry
- .getHistogramById("VIEW_SOURCE_IN_BROWSER_OPENED_BOOLEAN")
- .add(true);
let viewSourceBrowser = new ViewSourceBrowser(aArgs.viewSourceBrowser);
viewSourceBrowser.loadViewSource(aArgs);
},
@@ -160,9 +157,6 @@ var gViewSourceUtils = {
} catch (ex) {
}
}
- Services.telemetry
- .getHistogramById("VIEW_SOURCE_IN_WINDOW_OPENED_BOOLEAN")
- .add(true);
openDialog("chrome://global/content/viewSource.xul",
"_blank",
"all,dialog=no",
@@ -347,9 +341,6 @@ var gViewSourceUtils = {
// Calls the callback, keeping in mind undefined or null values.
handleCallBack: function(aCallBack, result, data)
{
- Services.telemetry
- .getHistogramById("VIEW_SOURCE_EXTERNAL_RESULT_BOOLEAN")
- .add(result);
// if callback is undefined, default to the internal viewer
if (aCallBack === undefined) {
this.internalViewerFallback(result, data);
diff --git a/toolkit/content/aboutTelemetry.css b/toolkit/content/aboutTelemetry.css
deleted file mode 100644
index 6acf82c201..0000000000
--- a/toolkit/content/aboutTelemetry.css
+++ /dev/null
@@ -1,271 +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/. */
-
-.hidden {
- display: none;
-}
-
-html {
- background-color: -moz-Dialog;
- color: -moz-DialogText;
- font: message-box;
-}
-
-body {
- padding: 0px;
- margin: 0px;
-}
-
-h2 {
- font-size: medium;
-}
-
-#page-description {
- border: 1px solid threedshadow;
- margin: 0px;
- padding: 10px;
-}
-
-#settings {
- border: 1px solid lightgrey;
- padding: 5px;
-}
-
-.description-enabled,
-.description-disabled {
- margin: 0px;
-}
-
-.description-enabled > span {
- color: green;
-}
-
-.description-disabled > span {
- color: red;
-}
-
-#ping-picker {
- margin-top: 10px;
- border: 1px solid lightgrey;
- padding: 5px;
-}
-
-#ping-source-picker {
- margin-left: 5px;
- margin-bottom: 10px;
-}
-
-.data-section,
-.data-subsection {
- background-color: -moz-Field;
- color: -moz-FieldText;
- border-top: 1px solid threedshadow;
- border-bottom: 1px solid threedshadow;
- margin: 0px;
- padding: 10px;
-}
-
-.data-section:not(.has-data),
-.data-subsection:not(.has-subdata) {
- color: gray;
-}
-
-
-.section-name {
- font-size: x-large;
- display: inline;
-}
-
-.has-data .section-name {
- cursor: pointer;
-}
-
-
-.toggle-caption {
- font-style: italic;
- cursor: pointer;
-}
-
-.data-section:not(.has-data) .toggle-caption,
-.data-subsection:not(.has-subdata) .toggle-caption {
- display: none;
-}
-
-
-.empty-caption {
- font-style: italic;
-}
-
-.has-data .empty-caption,
-.has-subdata .empty-caption {
- display: none; /* invisible when has-data */
-}
-
-.data,
-.subdata {
- margin: 15px;
- display: none;
-}
-
-.has-data.expanded .data,
-.has-subdata.expanded .subdata {
- display: block;
-}
-
-
-.stack-title {
- font-size: medium;
- font-weight: bold;
- text-decoration: underline;
-}
-
-#histograms, #addon-histograms, #thread-hang-stats>div {
- overflow: hidden;
-}
-
-.histogram {
- float: left;
- border: 1px solid gray;
- white-space: nowrap;
- padding: 10px;
- position: relative; /* required for position:absolute of the contained .copy-node */
-}
-
-body[dir="rtl"] .histogram {
- float: right;
-}
-
-.histogram-title {
- text-overflow: ellipsis;
- width: 100%;
- white-space: nowrap;
- overflow: hidden;
-}
-
-.keyed-histogram {
- white-space: nowrap;
- padding: 15px;
- position: relative; /* required for position:absolute of the contained .copy-node */
- display: block;
- overflow: hidden;
-}
-
-.keyed-histogram-title {
- text-overflow: ellipsis;
- width: 100%;
- margin: 10px;
- font-weight: bold;
- font-size: 120%;
- white-space: nowrap;
-}
-
-
-.bar {
- width: 2em;
- margin: 2px;
- text-align: center;
- float: left;
- font-family: monospace;
-}
-
-body[dir="rtl"] .bar {
- float: right;
-}
-
-.bar-inner {
- background-color: DeepSkyBlue;
- border: 1px solid #0000b0;
-}
-
-th {
- font-weight: bold;
- white-space: nowrap;
- text-align: left;
-}
-
-body[dir="rtl"] th {
- text-align: right;
-}
-
-caption {
- font-weight: bold;
- white-space: nowrap;
- text-align: left;
- font-size: large;
-}
-
-body[dir="rtl"] caption {
- text-align: right;
-}
-
-.copy-node {
- visibility: hidden;
- position: absolute;
- bottom: 1px;
- right: 1px;
-}
-
-body[dir="rtl"] .copy-node {
- left: 1px;
-}
-
-.histogram:hover .copy-node {
- visibility: visible;
-}
-
-
-.statebox {
- display: none;
-}
-
-
-.filter-ui {
- padding-inline-start: 10em;
- display: none;
-}
-
-.has-data.expanded .filter-ui {
- display: inline;
-}
-
-.processes-ui {
- display: none;
-}
-
-.has-data.expanded .processes-ui {
- display: initial;
-}
-
-.filter-blocked {
- display: none;
-}
-
-#raw-ping-data-section {
- width: 100%;
- height: 100%;
- background-color:-moz-Dialog;
-}
-
-#raw-ping-data {
- background-color:white;
- margin: 0px;
-}
-
-#hide-raw-ping {
- float: right;
- cursor: pointer;
- font-size: 20px;
- background-color:#d8d8d8;
- padding: 5px 10px;
-}
-
-/* addon subsection style */
-.addon-caption {
- font-size: larger;
- margin: 5px 0;
-}
-
-.process-picker {
- margin: 0 0.5em;
-}
diff --git a/toolkit/content/aboutTelemetry.js b/toolkit/content/aboutTelemetry.js
deleted file mode 100644
index 97dcba9e26..0000000000
--- a/toolkit/content/aboutTelemetry.js
+++ /dev/null
@@ -1,2168 +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/. */
-
-'use strict';
-
-var Ci = Components.interfaces;
-var Cc = Components.classes;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/TelemetryTimestamps.jsm");
-Cu.import("resource://gre/modules/TelemetryController.jsm");
-Cu.import("resource://gre/modules/TelemetrySession.jsm");
-Cu.import("resource://gre/modules/TelemetryArchive.jsm");
-Cu.import("resource://gre/modules/TelemetryUtils.jsm");
-Cu.import("resource://gre/modules/TelemetryLog.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-
-const Telemetry = Services.telemetry;
-const bundle = Services.strings.createBundle(
- "chrome://global/locale/aboutTelemetry.properties");
-const brandBundle = Services.strings.createBundle(
- "chrome://branding/locale/brand.properties");
-
-// Maximum height of a histogram bar (in em for html, in chars for text)
-const MAX_BAR_HEIGHT = 18;
-const MAX_BAR_CHARS = 25;
-const PREF_TELEMETRY_SERVER_OWNER = "toolkit.telemetry.server_owner";
-const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
-const PREF_DEBUG_SLOW_SQL = "toolkit.telemetry.debugSlowSql";
-const PREF_SYMBOL_SERVER_URI = "profiler.symbolicationUrl";
-const DEFAULT_SYMBOL_SERVER_URI = "http://symbolapi.mozilla.org";
-const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
-
-// ms idle before applying the filter (allow uninterrupted typing)
-const FILTER_IDLE_TIMEOUT = 500;
-
-const isWindows = (Services.appinfo.OS == "WINNT");
-const EOL = isWindows ? "\r\n" : "\n";
-
-// This is the ping object currently displayed in the page.
-var gPingData = null;
-
-// Cached value of document's RTL mode
-var documentRTLMode = "";
-
-/**
- * Helper function for determining whether the document direction is RTL.
- * Caches result of check on first invocation.
- */
-function isRTL() {
- if (!documentRTLMode)
- documentRTLMode = window.getComputedStyle(document.body).direction;
- return (documentRTLMode == "rtl");
-}
-
-function isArray(arg) {
- return Object.prototype.toString.call(arg) === '[object Array]';
-}
-
-function isFlatArray(obj) {
- if (!isArray(obj)) {
- return false;
- }
- return !obj.some(e => typeof(e) == "object");
-}
-
-/**
- * This is a helper function for explodeObject.
- */
-function flattenObject(obj, map, path, array) {
- if (!obj) {
- return;
- }
-
- for (let k of Object.keys(obj)) {
- let newPath = [...path, array ? "[" + k + "]" : k];
- let v = obj[k];
- if (!v || (typeof(v) != "object")) {
- map.set(newPath.join("."), v);
- } else if (isFlatArray(v)) {
- map.set(newPath.join("."), "[" + v.join(", ") + "]");
- } else {
- flattenObject(v, map, newPath, isArray(v));
- }
- }
-}
-
-/**
- * This turns a JSON object into a "flat" stringified form.
- *
- * For an object like {a: "1", b: {c: "2", d: "3"}} it returns a Map of the
- * form Map(["a","1"], ["b.c", "2"], ["b.d", "3"]).
- */
-function explodeObject(obj) {
- let map = new Map();
- flattenObject(obj, map, []);
- return map;
-}
-
-function filterObject(obj, filterOut) {
- let ret = {};
- for (let k of Object.keys(obj)) {
- if (filterOut.indexOf(k) == -1) {
- ret[k] = obj[k];
- }
- }
- return ret;
-}
-
-
-/**
- * This turns a JSON object into a "flat" stringified form, separated into top-level sections.
- *
- * For an object like:
- * {
- * a: {b: "1"},
- * c: {d: "2", e: {f: "3"}}
- * }
- * it returns a Map of the form:
- * Map([
- * ["a", Map(["b","1"])],
- * ["c", Map([["d", "2"], ["e.f", "3"]])]
- * ])
- */
-function sectionalizeObject(obj) {
- let map = new Map();
- for (let k of Object.keys(obj)) {
- map.set(k, explodeObject(obj[k]));
- }
- return map;
-}
-
-/**
- * Obtain the main DOMWindow for the current context.
- */
-function getMainWindow() {
- return window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
-}
-
-/**
- * Obtain the DOMWindow that can open a preferences pane.
- *
- * This is essentially "get the browser chrome window" with the added check
- * that the supposed browser chrome window is capable of opening a preferences
- * pane.
- *
- * This may return null if we can't find the browser chrome window.
- */
-function getMainWindowWithPreferencesPane() {
- let mainWindow = getMainWindow();
- if (mainWindow && "openAdvancedPreferences" in mainWindow) {
- return mainWindow;
- }
- return null;
-}
-
-/**
- * Remove all child nodes of a document node.
- */
-function removeAllChildNodes(node) {
- while (node.hasChildNodes()) {
- node.removeChild(node.lastChild);
- }
-}
-
-/**
- * Pad a number to two digits with leading "0".
- */
-function padToTwoDigits(n) {
- return (n > 9) ? n: "0" + n;
-}
-
-/**
- * Return yesterdays date with the same time.
- */
-function yesterday(date) {
- let d = new Date(date);
- d.setDate(d.getDate() - 1);
- return d;
-}
-
-/**
- * This returns a short date string of the form YYYY/MM/DD.
- */
-function shortDateString(date) {
- return date.getFullYear()
- + "/" + padToTwoDigits(date.getMonth() + 1)
- + "/" + padToTwoDigits(date.getDate());
-}
-
-/**
- * This returns a short time string of the form hh:mm:ss.
- */
-function shortTimeString(date) {
- return padToTwoDigits(date.getHours())
- + ":" + padToTwoDigits(date.getMinutes())
- + ":" + padToTwoDigits(date.getSeconds());
-}
-
-var Settings = {
- SETTINGS: [
- // data upload
- {
- pref: PREF_FHR_UPLOAD_ENABLED,
- defaultPrefValue: false,
- descriptionEnabledId: "description-upload-enabled",
- descriptionDisabledId: "description-upload-disabled",
- },
- // extended "Telemetry" recording
- {
- pref: PREF_TELEMETRY_ENABLED,
- defaultPrefValue: false,
- descriptionEnabledId: "description-extended-recording-enabled",
- descriptionDisabledId: "description-extended-recording-disabled",
- },
- ],
-
- attachObservers: function() {
- for (let s of this.SETTINGS) {
- let setting = s;
- Preferences.observe(setting.pref, this.render, this);
- }
-
- let elements = document.getElementsByClassName("change-data-choices-link");
- for (let el of elements) {
- el.addEventListener("click", function() {
- // Show the data choices preferences on desktop.
- let mainWindow = getMainWindowWithPreferencesPane();
- mainWindow.openAdvancedPreferences("dataChoicesTab");
- }, false);
- }
- },
-
- detachObservers: function() {
- for (let setting of this.SETTINGS) {
- Preferences.ignore(setting.pref, this.render, this);
- }
- },
-
- /**
- * Updates the button & text at the top of the page to reflect Telemetry state.
- */
- render: function() {
- for (let setting of this.SETTINGS) {
- let enabledElement = document.getElementById(setting.descriptionEnabledId);
- let disabledElement = document.getElementById(setting.descriptionDisabledId);
-
- if (Preferences.get(setting.pref, setting.defaultPrefValue)) {
- enabledElement.classList.remove("hidden");
- disabledElement.classList.add("hidden");
- } else {
- enabledElement.classList.add("hidden");
- disabledElement.classList.remove("hidden");
- }
- }
- }
-};
-
-var PingPicker = {
- viewCurrentPingData: null,
- viewStructuredPingData: null,
- _archivedPings: null,
-
- attachObservers: function() {
- let elements = document.getElementsByName("choose-ping-source");
- for (let el of elements) {
- el.addEventListener("change", () => this.onPingSourceChanged(), false);
- }
-
- let displays = document.getElementsByName("choose-ping-display");
- for (let el of displays) {
- el.addEventListener("change", () => this.onPingDisplayChanged(), false);
- }
-
- document.getElementById("show-subsession-data").addEventListener("change", () => {
- this._updateCurrentPingData();
- });
-
- document.getElementById("choose-ping-week").addEventListener("change", () => {
- this._renderPingList();
- this._updateArchivedPingData();
- }, false);
- document.getElementById("choose-ping-id").addEventListener("change", () => {
- this._updateArchivedPingData()
- }, false);
-
- document.getElementById("newer-ping")
- .addEventListener("click", () => this._movePingIndex(-1), false);
- document.getElementById("older-ping")
- .addEventListener("click", () => this._movePingIndex(1), false);
- document.getElementById("choose-payload")
- .addEventListener("change", () => displayPingData(gPingData), false);
- document.getElementById("histograms-processes")
- .addEventListener("change", () => displayPingData(gPingData), false);
- document.getElementById("keyed-histograms-processes")
- .addEventListener("change", () => displayPingData(gPingData), false);
- },
-
- onPingSourceChanged: function() {
- this.update();
- },
-
- onPingDisplayChanged: function() {
- this.update();
- },
-
- update: Task.async(function*() {
- let viewCurrent = document.getElementById("ping-source-current").checked;
- let viewStructured = document.getElementById("ping-source-structured").checked;
- let currentChanged = viewCurrent !== this.viewCurrentPingData;
- let structuredChanged = viewStructured !== this.viewStructuredPingData;
- this.viewCurrentPingData = viewCurrent;
- this.viewStructuredPingData = viewStructured;
-
- // If we have no archived pings, disable the ping archive selection.
- // This can happen on new profiles or if the ping archive is disabled.
- let archivedPingList = yield TelemetryArchive.promiseArchivedPingList();
- let sourceArchived = document.getElementById("ping-source-archive");
- sourceArchived.disabled = (archivedPingList.length == 0);
-
- if (currentChanged) {
- if (this.viewCurrentPingData) {
- document.getElementById("current-ping-picker").classList.remove("hidden");
- document.getElementById("archived-ping-picker").classList.add("hidden");
- this._updateCurrentPingData();
- } else {
- document.getElementById("current-ping-picker").classList.add("hidden");
- yield this._updateArchivedPingList(archivedPingList);
- document.getElementById("archived-ping-picker").classList.remove("hidden");
- }
- }
-
- if (structuredChanged) {
- if (this.viewStructuredPingData) {
- this._showStructuredPingData();
- } else {
- this._showRawPingData();
- }
- }
- }),
-
- _updateCurrentPingData: function() {
- const subsession = document.getElementById("show-subsession-data").checked;
- const ping = TelemetryController.getCurrentPingData(subsession);
- if (!ping) {
- return;
- }
- displayPingData(ping, true);
- },
-
- _updateArchivedPingData: function() {
- let id = this._getSelectedPingId();
- return TelemetryArchive.promiseArchivedPingById(id)
- .then((ping) => displayPingData(ping, true));
- },
-
- _updateArchivedPingList: Task.async(function*(pingList) {
- // The archived ping list is sorted in ascending timestamp order,
- // but descending is more practical for the operations we do here.
- pingList.reverse();
-
- this._archivedPings = pingList;
-
- // Collect the start dates for all the weeks we have pings for.
- let weekStart = (date) => {
- let weekDay = (date.getDay() + 6) % 7;
- let monday = new Date(date);
- monday.setDate(date.getDate() - weekDay);
- return TelemetryUtils.truncateToDays(monday);
- };
-
- let weekStartDates = new Set();
- for (let p of pingList) {
- weekStartDates.add(weekStart(new Date(p.timestampCreated)).getTime());
- }
-
- // Build a list of the week date ranges we have ping data for.
- let plusOneWeek = (date) => {
- let d = date;
- d.setDate(d.getDate() + 7);
- return d;
- };
-
- this._weeks = Array.from(weekStartDates.values(), startTime => ({
- startDate: new Date(startTime),
- endDate: plusOneWeek(new Date(startTime)),
- }));
-
- // Render the archive data.
- this._renderWeeks();
- this._renderPingList();
-
- // Update the displayed ping.
- yield this._updateArchivedPingData();
- }),
-
- _renderWeeks: function() {
- let weekSelector = document.getElementById("choose-ping-week");
- removeAllChildNodes(weekSelector);
-
- let index = 0;
- for (let week of this._weeks) {
- let text = shortDateString(week.startDate)
- + " - " + shortDateString(yesterday(week.endDate));
-
- let option = document.createElement("option");
- let content = document.createTextNode(text);
- option.appendChild(content);
- weekSelector.appendChild(option);
- }
- },
-
- _getSelectedWeek: function() {
- let weekSelector = document.getElementById("choose-ping-week");
- return this._weeks[weekSelector.selectedIndex];
- },
-
- _renderPingList: function(id = null) {
- let pingSelector = document.getElementById("choose-ping-id");
- removeAllChildNodes(pingSelector);
-
- let weekRange = this._getSelectedWeek();
- let pings = this._archivedPings.filter(
- (p) => p.timestampCreated >= weekRange.startDate.getTime() &&
- p.timestampCreated < weekRange.endDate.getTime());
-
- for (let p of pings) {
- let date = new Date(p.timestampCreated);
- let text = shortDateString(date)
- + " " + shortTimeString(date)
- + " - " + p.type;
-
- let option = document.createElement("option");
- let content = document.createTextNode(text);
- option.appendChild(content);
- option.setAttribute("value", p.id);
- if (id && p.id == id) {
- option.selected = true;
- }
- pingSelector.appendChild(option);
- }
- },
-
- _getSelectedPingId: function() {
- let pingSelector = document.getElementById("choose-ping-id");
- let selected = pingSelector.selectedOptions.item(0);
- return selected.getAttribute("value");
- },
-
- _movePingIndex: function(offset) {
- const id = this._getSelectedPingId();
- const index = this._archivedPings.findIndex((p) => p.id == id);
- const newIndex = Math.min(Math.max(index + offset, 0), this._archivedPings.length - 1);
- const ping = this._archivedPings[newIndex];
-
- const weekIndex = this._weeks.findIndex(
- (week) => ping.timestampCreated >= week.startDate.getTime() &&
- ping.timestampCreated < week.endDate.getTime());
- const options = document.getElementById("choose-ping-week").options;
- options.item(weekIndex).selected = true;
-
- this._renderPingList(ping.id);
- this._updateArchivedPingData();
- },
-
- _showRawPingData: function() {
- document.getElementById("raw-ping-data-section").classList.remove("hidden");
- document.getElementById("structured-ping-data-section").classList.add("hidden");
- },
-
- _showStructuredPingData: function() {
- document.getElementById("raw-ping-data-section").classList.add("hidden");
- document.getElementById("structured-ping-data-section").classList.remove("hidden");
- },
-};
-
-var GeneralData = {
- /**
- * Renders the general data
- */
- render: function(aPing) {
- setHasData("general-data-section", true);
- let table = document.createElement("table");
-
- let caption = document.createElement("caption");
- let captionString = bundle.GetStringFromName("generalDataTitle");
- caption.appendChild(document.createTextNode(captionString + "\n"));
- table.appendChild(caption);
-
- let headings = document.createElement("tr");
- this.appendColumn(headings, "th", bundle.GetStringFromName("generalDataHeadingName") + "\t");
- this.appendColumn(headings, "th", bundle.GetStringFromName("generalDataHeadingValue") + "\t");
- table.appendChild(headings);
-
- // The payload & environment parts are handled by other renderers.
- let ignoreSections = ["payload", "environment"];
- let data = explodeObject(filterObject(aPing, ignoreSections));
-
- for (let [path, value] of data) {
- let row = document.createElement("tr");
- this.appendColumn(row, "td", path + "\t");
- this.appendColumn(row, "td", value + "\t");
- table.appendChild(row);
- }
-
- let dataDiv = document.getElementById("general-data");
- removeAllChildNodes(dataDiv);
- dataDiv.appendChild(table);
- },
-
- /**
- * Helper function for appending a column to the data table.
- *
- * @param aRowElement Parent row element
- * @param aColType Column's tag name
- * @param aColText Column contents
- */
- appendColumn: function(aRowElement, aColType, aColText) {
- let colElement = document.createElement(aColType);
- let colTextElement = document.createTextNode(aColText);
- colElement.appendChild(colTextElement);
- aRowElement.appendChild(colElement);
- },
-};
-
-var EnvironmentData = {
- /**
- * Renders the environment data
- */
- render: function(ping) {
- let dataDiv = document.getElementById("environment-data");
- removeAllChildNodes(dataDiv);
- const hasData = !!ping.environment;
- setHasData("environment-data-section", hasData);
- if (!hasData) {
- return;
- }
-
- let data = sectionalizeObject(ping.environment);
-
- for (let [section, sectionData] of data) {
- if (section == "addons") {
- break;
- }
-
- let table = document.createElement("table");
- this.appendHeading(table);
-
- for (let [path, value] of sectionData) {
- let row = document.createElement("tr");
- this.appendColumn(row, "td", path);
- this.appendColumn(row, "td", value);
- table.appendChild(row);
- }
-
- let hasData = sectionData.size > 0;
- this.createSubsection(section, hasData, table, dataDiv);
- }
-
- // We use specialized rendering here to make the addon and plugin listings
- // more readable.
- this.createAddonSection(dataDiv, ping);
- },
-
- createSubsection: function(title, hasSubdata, subSectionData, dataDiv) {
- let dataSection = document.createElement("section");
- dataSection.classList.add("data-subsection");
-
- if (hasSubdata) {
- dataSection.classList.add("has-subdata");
- }
-
- // Create section heading
- let sectionName = document.createElement("h2");
- sectionName.setAttribute("class", "section-name");
- sectionName.appendChild(document.createTextNode(title));
- sectionName.addEventListener("click", toggleSection, false);
-
- // Create caption for toggling the subsection visibility.
- let toggleCaption = document.createElement("span");
- toggleCaption.setAttribute("class", "toggle-caption");
- let toggleText = bundle.GetStringFromName("environmentDataSubsectionToggle");
- toggleCaption.appendChild(document.createTextNode(" " + toggleText));
- toggleCaption.addEventListener("click", toggleSection, false);
-
- // Create caption for empty subsections.
- let emptyCaption = document.createElement("span");
- emptyCaption.setAttribute("class", "empty-caption");
- let emptyText = bundle.GetStringFromName("environmentDataSubsectionEmpty");
- emptyCaption.appendChild(document.createTextNode(" " + emptyText));
-
- // Create data container
- let data = document.createElement("div");
- data.setAttribute("class", "subsection-data subdata");
- data.appendChild(subSectionData);
-
- // Append elements
- dataSection.appendChild(sectionName);
- dataSection.appendChild(toggleCaption);
- dataSection.appendChild(emptyCaption);
- dataSection.appendChild(data);
-
- dataDiv.appendChild(dataSection);
- },
-
- renderPersona: function(addonObj, addonSection, sectionTitle) {
- let table = document.createElement("table");
- table.setAttribute("id", sectionTitle);
- this.appendAddonSubsectionTitle(sectionTitle, table);
- this.appendRow(table, "persona", addonObj.persona);
- addonSection.appendChild(table);
- },
-
- renderActivePlugins: function(addonObj, addonSection, sectionTitle) {
- let data = explodeObject(addonObj);
- let table = document.createElement("table");
- table.setAttribute("id", sectionTitle);
- this.appendAddonSubsectionTitle(sectionTitle, table);
-
- for (let plugin of addonObj) {
- let data = explodeObject(plugin);
- this.appendHeadingName(table, data.get("name"));
-
- for (let [key, value] of data) {
- this.appendRow(table, key, value);
- }
- }
-
- addonSection.appendChild(table);
- },
-
- renderAddonsObject: function(addonObj, addonSection, sectionTitle) {
- let table = document.createElement("table");
- table.setAttribute("id", sectionTitle);
- this.appendAddonSubsectionTitle(sectionTitle, table);
-
- for (let id of Object.keys(addonObj)) {
- let addon = addonObj[id];
- this.appendHeadingName(table, addon.name || id);
- this.appendAddonID(table, id);
- let data = explodeObject(addon);
-
- for (let [key, value] of data) {
- this.appendRow(table, key, value);
- }
- }
-
- addonSection.appendChild(table);
- },
-
- renderKeyValueObject: function(addonObj, addonSection, sectionTitle) {
- let data = explodeObject(addonObj);
- let table = document.createElement("table");
- table.setAttribute("class", sectionTitle);
- this.appendAddonSubsectionTitle(sectionTitle, table);
- this.appendHeading(table);
-
- for (let [key, value] of data) {
- this.appendRow(table, key, value);
- }
-
- addonSection.appendChild(table);
- },
-
- appendAddonID: function(table, addonID) {
- this.appendRow(table, "id", addonID);
- },
-
- appendHeading: function(table) {
- let headings = document.createElement("tr");
- this.appendColumn(headings, "th", bundle.GetStringFromName("environmentDataHeadingName"));
- this.appendColumn(headings, "th", bundle.GetStringFromName("environmentDataHeadingValue"));
- table.appendChild(headings);
- },
-
- appendHeadingName: function(table, name) {
- let headings = document.createElement("tr");
- this.appendColumn(headings, "th", name);
- headings.cells[0].colSpan = 2;
- table.appendChild(headings);
- },
-
- appendAddonSubsectionTitle: function(section, table) {
- let caption = document.createElement("caption");
- caption.setAttribute("class", "addon-caption");
- caption.appendChild(document.createTextNode(section));
- table.appendChild(caption);
- },
-
- createAddonSection: function(dataDiv, ping) {
- let addonSection = document.createElement("div");
- let addons = ping.environment.addons;
- this.renderAddonsObject(addons.activeAddons, addonSection, "activeAddons");
- this.renderActivePlugins(addons.activePlugins, addonSection, "activePlugins");
- this.renderKeyValueObject(addons.theme, addonSection, "theme");
- this.renderKeyValueObject(addons.activeExperiment, addonSection, "activeExperiment");
- this.renderAddonsObject(addons.activeGMPlugins, addonSection, "activeGMPlugins");
- this.renderPersona(addons, addonSection, "persona");
-
- let hasAddonData = Object.keys(ping.environment.addons).length > 0;
- this.createSubsection("addons", hasAddonData, addonSection, dataDiv);
- },
-
- appendRow: function(table, id, value) {
- let row = document.createElement("tr");
- this.appendColumn(row, "td", id);
- this.appendColumn(row, "td", value);
- table.appendChild(row);
- },
- /**
- * Helper function for appending a column to the data table.
- *
- * @param aRowElement Parent row element
- * @param aColType Column's tag name
- * @param aColText Column contents
- */
- appendColumn: function(aRowElement, aColType, aColText) {
- let colElement = document.createElement(aColType);
- let colTextElement = document.createTextNode(aColText);
- colElement.appendChild(colTextElement);
- aRowElement.appendChild(colElement);
- },
-};
-
-var TelLog = {
- /**
- * Renders the telemetry log
- */
- render: function(aPing) {
- let entries = aPing.payload.log;
- const hasData = entries && entries.length > 0;
- setHasData("telemetry-log-section", hasData);
- if (!hasData) {
- return;
- }
-
- let table = document.createElement("table");
-
- let caption = document.createElement("caption");
- let captionString = bundle.GetStringFromName("telemetryLogTitle");
- caption.appendChild(document.createTextNode(captionString + "\n"));
- table.appendChild(caption);
-
- let headings = document.createElement("tr");
- this.appendColumn(headings, "th", bundle.GetStringFromName("telemetryLogHeadingId") + "\t");
- this.appendColumn(headings, "th", bundle.GetStringFromName("telemetryLogHeadingTimestamp") + "\t");
- this.appendColumn(headings, "th", bundle.GetStringFromName("telemetryLogHeadingData") + "\t");
- table.appendChild(headings);
-
- for (let entry of entries) {
- let row = document.createElement("tr");
- for (let elem of entry) {
- this.appendColumn(row, "td", elem + "\t");
- }
- table.appendChild(row);
- }
-
- let dataDiv = document.getElementById("telemetry-log");
- removeAllChildNodes(dataDiv);
- dataDiv.appendChild(table);
- },
-
- /**
- * Helper function for appending a column to the data table.
- *
- * @param aRowElement Parent row element
- * @param aColType Column's tag name
- * @param aColText Column contents
- */
- appendColumn: function(aRowElement, aColType, aColText) {
- let colElement = document.createElement(aColType);
- let colTextElement = document.createTextNode(aColText);
- colElement.appendChild(colTextElement);
- aRowElement.appendChild(colElement);
- },
-};
-
-var SlowSQL = {
-
- slowSqlHits: bundle.GetStringFromName("slowSqlHits"),
-
- slowSqlAverage: bundle.GetStringFromName("slowSqlAverage"),
-
- slowSqlStatement: bundle.GetStringFromName("slowSqlStatement"),
-
- mainThreadTitle: bundle.GetStringFromName("slowSqlMain"),
-
- otherThreadTitle: bundle.GetStringFromName("slowSqlOther"),
-
- /**
- * Render slow SQL statistics
- */
- render: function SlowSQL_render(aPing) {
- // We can add the debug SQL data to the current ping later.
- // However, we need to be careful to never send that debug data
- // out due to privacy concerns.
- // We want to show the actual ping data for archived pings,
- // so skip this there.
- let debugSlowSql = PingPicker.viewCurrentPingData && Preferences.get(PREF_DEBUG_SLOW_SQL, false);
- let slowSql = debugSlowSql ? Telemetry.debugSlowSQL : aPing.payload.slowSQL;
- if (!slowSql) {
- setHasData("slow-sql-section", false);
- return;
- }
-
- let {mainThread, otherThreads} =
- debugSlowSql ? Telemetry.debugSlowSQL : aPing.payload.slowSQL;
-
- let mainThreadCount = Object.keys(mainThread).length;
- let otherThreadCount = Object.keys(otherThreads).length;
- if (mainThreadCount == 0 && otherThreadCount == 0) {
- setHasData("slow-sql-section", false);
- return;
- }
-
- setHasData("slow-sql-section", true);
- if (debugSlowSql) {
- document.getElementById("sql-warning").classList.remove("hidden");
- }
-
- let slowSqlDiv = document.getElementById("slow-sql-tables");
- removeAllChildNodes(slowSqlDiv);
-
- // Main thread
- if (mainThreadCount > 0) {
- let table = document.createElement("table");
- this.renderTableHeader(table, this.mainThreadTitle);
- this.renderTable(table, mainThread);
-
- slowSqlDiv.appendChild(table);
- slowSqlDiv.appendChild(document.createElement("hr"));
- }
-
- // Other threads
- if (otherThreadCount > 0) {
- let table = document.createElement("table");
- this.renderTableHeader(table, this.otherThreadTitle);
- this.renderTable(table, otherThreads);
-
- slowSqlDiv.appendChild(table);
- slowSqlDiv.appendChild(document.createElement("hr"));
- }
- },
-
- /**
- * Creates a header row for a Slow SQL table
- * Tabs & newlines added to cells to make it easier to copy-paste.
- *
- * @param aTable Parent table element
- * @param aTitle Table's title
- */
- renderTableHeader: function SlowSQL_renderTableHeader(aTable, aTitle) {
- let caption = document.createElement("caption");
- caption.appendChild(document.createTextNode(aTitle + "\n"));
- aTable.appendChild(caption);
-
- let headings = document.createElement("tr");
- this.appendColumn(headings, "th", this.slowSqlHits + "\t");
- this.appendColumn(headings, "th", this.slowSqlAverage + "\t");
- this.appendColumn(headings, "th", this.slowSqlStatement + "\n");
- aTable.appendChild(headings);
- },
-
- /**
- * Fills out the table body
- * Tabs & newlines added to cells to make it easier to copy-paste.
- *
- * @param aTable Parent table element
- * @param aSql SQL stats object
- */
- renderTable: function SlowSQL_renderTable(aTable, aSql) {
- for (let [sql, [hitCount, totalTime]] of Object.entries(aSql)) {
- let averageTime = totalTime / hitCount;
-
- let sqlRow = document.createElement("tr");
-
- this.appendColumn(sqlRow, "td", hitCount + "\t");
- this.appendColumn(sqlRow, "td", averageTime.toFixed(0) + "\t");
- this.appendColumn(sqlRow, "td", sql + "\n");
-
- aTable.appendChild(sqlRow);
- }
- },
-
- /**
- * Helper function for appending a column to a Slow SQL table.
- *
- * @param aRowElement Parent row element
- * @param aColType Column's tag name
- * @param aColText Column contents
- */
- appendColumn: function SlowSQL_appendColumn(aRowElement, aColType, aColText) {
- let colElement = document.createElement(aColType);
- let colTextElement = document.createTextNode(aColText);
- colElement.appendChild(colTextElement);
- aRowElement.appendChild(colElement);
- }
-};
-
-var StackRenderer = {
-
- stackTitle: bundle.GetStringFromName("stackTitle"),
-
- memoryMapTitle: bundle.GetStringFromName("memoryMapTitle"),
-
- /**
- * Outputs the memory map associated with this hang report
- *
- * @param aDiv Output div
- */
- renderMemoryMap: function StackRenderer_renderMemoryMap(aDiv, memoryMap) {
- aDiv.appendChild(document.createTextNode(this.memoryMapTitle));
- aDiv.appendChild(document.createElement("br"));
-
- for (let currentModule of memoryMap) {
- aDiv.appendChild(document.createTextNode(currentModule.join(" ")));
- aDiv.appendChild(document.createElement("br"));
- }
-
- aDiv.appendChild(document.createElement("br"));
- },
-
- /**
- * Outputs the raw PCs from the hang's stack
- *
- * @param aDiv Output div
- * @param aStack Array of PCs from the hang stack
- */
- renderStack: function StackRenderer_renderStack(aDiv, aStack) {
- aDiv.appendChild(document.createTextNode(this.stackTitle));
- let stackText = " " + aStack.join(" ");
- aDiv.appendChild(document.createTextNode(stackText));
-
- aDiv.appendChild(document.createElement("br"));
- aDiv.appendChild(document.createElement("br"));
- },
- renderStacks: function StackRenderer_renderStacks(aPrefix, aStacks,
- aMemoryMap, aRenderHeader) {
- let div = document.getElementById(aPrefix + '-data');
- removeAllChildNodes(div);
-
- let fetchE = document.getElementById(aPrefix + '-fetch-symbols');
- if (fetchE) {
- fetchE.classList.remove("hidden");
- }
- let hideE = document.getElementById(aPrefix + '-hide-symbols');
- if (hideE) {
- hideE.classList.add("hidden");
- }
-
- if (aStacks.length == 0) {
- return;
- }
-
- setHasData(aPrefix + '-section', true);
-
- this.renderMemoryMap(div, aMemoryMap);
-
- for (let i = 0; i < aStacks.length; ++i) {
- let stack = aStacks[i];
- aRenderHeader(i);
- this.renderStack(div, stack)
- }
- },
-
- /**
- * Renders the title of the stack: e.g. "Late Write #1" or
- * "Hang Report #1 (6 seconds)".
- *
- * @param aFormatArgs formating args to be passed to formatStringFromName.
- */
- renderHeader: function StackRenderer_renderHeader(aPrefix, aFormatArgs) {
- let div = document.getElementById(aPrefix + "-data");
-
- let titleElement = document.createElement("span");
- titleElement.className = "stack-title";
-
- let titleText = bundle.formatStringFromName(
- aPrefix + "-title", aFormatArgs, aFormatArgs.length);
- titleElement.appendChild(document.createTextNode(titleText));
-
- div.appendChild(titleElement);
- div.appendChild(document.createElement("br"));
- }
-};
-
-var RawPayload = {
- /**
- * Renders the raw payload
- */
- render: function(aPing) {
- setHasData("raw-payload-section", true);
- let pre = document.getElementById("raw-payload-data-pre");
- pre.textContent = JSON.stringify(aPing.payload, null, 2);
- }
-};
-
-function SymbolicationRequest(aPrefix, aRenderHeader,
- aMemoryMap, aStacks, aDurations = null) {
- this.prefix = aPrefix;
- this.renderHeader = aRenderHeader;
- this.memoryMap = aMemoryMap;
- this.stacks = aStacks;
- this.durations = aDurations;
-}
-/**
- * A callback for onreadystatechange. It replaces the numeric stack with
- * the symbolicated one returned by the symbolication server.
- */
-SymbolicationRequest.prototype.handleSymbolResponse =
-function SymbolicationRequest_handleSymbolResponse() {
- if (this.symbolRequest.readyState != 4)
- return;
-
- let fetchElement = document.getElementById(this.prefix + "-fetch-symbols");
- fetchElement.classList.add("hidden");
- let hideElement = document.getElementById(this.prefix + "-hide-symbols");
- hideElement.classList.remove("hidden");
- let div = document.getElementById(this.prefix + "-data");
- removeAllChildNodes(div);
- let errorMessage = bundle.GetStringFromName("errorFetchingSymbols");
-
- if (this.symbolRequest.status != 200) {
- div.appendChild(document.createTextNode(errorMessage));
- return;
- }
-
- let jsonResponse = {};
- try {
- jsonResponse = JSON.parse(this.symbolRequest.responseText);
- } catch (e) {
- div.appendChild(document.createTextNode(errorMessage));
- return;
- }
-
- for (let i = 0; i < jsonResponse.length; ++i) {
- let stack = jsonResponse[i];
- this.renderHeader(i, this.durations);
-
- for (let symbol of stack) {
- div.appendChild(document.createTextNode(symbol));
- div.appendChild(document.createElement("br"));
- }
- div.appendChild(document.createElement("br"));
- }
-};
-/**
- * Send a request to the symbolication server to symbolicate this stack.
- */
-SymbolicationRequest.prototype.fetchSymbols =
-function SymbolicationRequest_fetchSymbols() {
- let symbolServerURI =
- Preferences.get(PREF_SYMBOL_SERVER_URI, DEFAULT_SYMBOL_SERVER_URI);
- let request = {"memoryMap" : this.memoryMap, "stacks" : this.stacks,
- "version" : 3};
- let requestJSON = JSON.stringify(request);
-
- this.symbolRequest = new XMLHttpRequest();
- this.symbolRequest.open("POST", symbolServerURI, true);
- this.symbolRequest.setRequestHeader("Content-type", "application/json");
- this.symbolRequest.setRequestHeader("Content-length",
- requestJSON.length);
- this.symbolRequest.setRequestHeader("Connection", "close");
- this.symbolRequest.onreadystatechange = this.handleSymbolResponse.bind(this);
- this.symbolRequest.send(requestJSON);
-}
-
-var ChromeHangs = {
-
- symbolRequest: null,
-
- /**
- * Renders raw chrome hang data
- */
- render: function ChromeHangs_render(aPing) {
- let hangs = aPing.payload.chromeHangs;
- setHasData("chrome-hangs-section", !!hangs);
- if (!hangs) {
- return;
- }
-
- let stacks = hangs.stacks;
- let memoryMap = hangs.memoryMap;
- let durations = hangs.durations;
-
- StackRenderer.renderStacks("chrome-hangs", stacks, memoryMap,
- (index) => this.renderHangHeader(index, durations));
- },
-
- renderHangHeader: function ChromeHangs_renderHangHeader(aIndex, aDurations) {
- StackRenderer.renderHeader("chrome-hangs", [aIndex + 1, aDurations[aIndex]]);
- }
-};
-
-var ThreadHangStats = {
-
- /**
- * Renders raw thread hang stats data
- */
- render: function(aPayload) {
- let div = document.getElementById("thread-hang-stats");
- removeAllChildNodes(div);
-
- let stats = aPayload.threadHangStats;
- setHasData("thread-hang-stats-section", stats && (stats.length > 0));
- if (!stats) {
- return;
- }
-
- stats.forEach((thread) => {
- div.appendChild(this.renderThread(thread));
- });
- },
-
- /**
- * Creates and fills data corresponding to a thread
- */
- renderThread: function(aThread) {
- let div = document.createElement("div");
-
- let title = document.createElement("h2");
- title.textContent = aThread.name;
- div.appendChild(title);
-
- // Don't localize the histogram name, because the
- // name is also used as the div element's ID
- Histogram.render(div, aThread.name + "-Activity",
- aThread.activity, {exponential: true}, true);
- aThread.hangs.forEach((hang, index) => {
- let hangName = aThread.name + "-Hang-" + (index + 1);
- let hangDiv = Histogram.render(
- div, hangName, hang.histogram, {exponential: true}, true);
- let stackDiv = document.createElement("div");
- let stack = hang.nativeStack || hang.stack;
- stack.forEach((frame) => {
- stackDiv.appendChild(document.createTextNode(frame));
- // Leave an extra <br> at the end of the stack listing
- stackDiv.appendChild(document.createElement("br"));
- });
- // Insert stack after the histogram title
- hangDiv.insertBefore(stackDiv, hangDiv.childNodes[1]);
- });
- return div;
- },
-};
-
-var Histogram = {
-
- hgramSamplesCaption: bundle.GetStringFromName("histogramSamples"),
-
- hgramAverageCaption: bundle.GetStringFromName("histogramAverage"),
-
- hgramSumCaption: bundle.GetStringFromName("histogramSum"),
-
- hgramCopyCaption: bundle.GetStringFromName("histogramCopy"),
-
- /**
- * Renders a single Telemetry histogram
- *
- * @param aParent Parent element
- * @param aName Histogram name
- * @param aHgram Histogram information
- * @param aOptions Object with render options
- * * exponential: bars follow logarithmic scale
- * @param aIsBHR whether or not requires fixing the labels for TimeHistogram
- */
- render: function Histogram_render(aParent, aName, aHgram, aOptions, aIsBHR) {
- let options = aOptions || {};
- let hgram = this.processHistogram(aHgram, aName, aIsBHR);
-
- let outerDiv = document.createElement("div");
- outerDiv.className = "histogram";
- outerDiv.id = aName;
-
- let divTitle = document.createElement("div");
- divTitle.className = "histogram-title";
- divTitle.appendChild(document.createTextNode(aName));
- outerDiv.appendChild(divTitle);
-
- let stats = hgram.sample_count + " " + this.hgramSamplesCaption + ", " +
- this.hgramAverageCaption + " = " + hgram.pretty_average + ", " +
- this.hgramSumCaption + " = " + hgram.sum;
-
- let divStats = document.createElement("div");
- divStats.appendChild(document.createTextNode(stats));
- outerDiv.appendChild(divStats);
-
- if (isRTL()) {
- hgram.buckets.reverse();
- hgram.values.reverse();
- }
-
- let textData = this.renderValues(outerDiv, hgram, options);
-
- // The 'Copy' button contains the textual data, copied to clipboard on click
- let copyButton = document.createElement("button");
- copyButton.className = "copy-node";
- copyButton.appendChild(document.createTextNode(this.hgramCopyCaption));
- copyButton.histogramText = aName + EOL + stats + EOL + EOL + textData;
- copyButton.addEventListener("click", function() {
- Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
- .copyString(this.histogramText);
- });
- outerDiv.appendChild(copyButton);
-
- aParent.appendChild(outerDiv);
- return outerDiv;
- },
-
- processHistogram: function(aHgram, aName, aIsBHR) {
- const values = Object.keys(aHgram.values).map(k => aHgram.values[k]);
- if (!values.length) {
- // If we have no values collected for this histogram, just return
- // zero values so we still render it.
- return {
- values: [],
- pretty_average: 0,
- max: 0,
- sample_count: 0,
- sum: 0
- };
- }
-
- const sample_count = values.reduceRight((a, b) => a + b);
- const average = Math.round(aHgram.sum * 10 / sample_count) / 10;
- const max_value = Math.max(...values);
-
- function labelFunc(k) {
- // - BHR histograms are TimeHistograms: Exactly power-of-two buckets (from 0)
- // (buckets: [0..1], [2..3], [4..7], [8..15], ... note the 0..1 anomaly - same bucket)
- // - TimeHistogram's JS representation adds a dummy (empty) "0" bucket, and
- // the rest of the buckets have the label as the upper value of the
- // bucket (non TimeHistograms have the lower value of the bucket as label).
- // So JS TimeHistograms bucket labels are: 0 (dummy), 1, 3, 7, 15, ...
- // - see toolkit/components/telemetry/Telemetry.cpp
- // (CreateJSTimeHistogram, CreateJSThreadHangStats, CreateJSHangHistogram)
- // - see toolkit/components/telemetry/ThreadHangStats.h
- // Fix BHR labels to the "standard" format for about:telemetry as follows:
- // - The dummy 0 label+bucket will be filtered before arriving here
- // - If it's 1 -> manually correct it to 0 (the 0..1 anomaly)
- // - For the rest, set the label as the bottom value instead of the upper.
- // --> so we'll end with the following (non dummy) labels: 0, 2, 4, 8, 16, ...
- if (!aIsBHR) {
- return k;
- }
- return k == 1 ? 0 : (k + 1) / 2;
- }
-
- const labelledValues = Object.keys(aHgram.values)
- .filter(label => !aIsBHR || Number(label) != 0) // remove dummy 0 label for BHR
- .map(k => [labelFunc(Number(k)), aHgram.values[k]]);
-
- let result = {
- values: labelledValues,
- pretty_average: average,
- max: max_value,
- sample_count: sample_count,
- sum: aHgram.sum
- };
-
- return result;
- },
-
- /**
- * Return a non-negative, logarithmic representation of a non-negative number.
- * e.g. 0 => 0, 1 => 1, 10 => 2, 100 => 3
- *
- * @param aNumber Non-negative number
- */
- getLogValue: function(aNumber) {
- return Math.max(0, Math.log10(aNumber) + 1);
- },
-
- /**
- * Create histogram HTML bars, also returns a textual representation
- * Both aMaxValue and aSumValues must be positive.
- * Values are assumed to use 0 as baseline.
- *
- * @param aDiv Outer parent div
- * @param aHgram The histogram data
- * @param aOptions Object with render options (@see #render)
- */
- renderValues: function Histogram_renderValues(aDiv, aHgram, aOptions) {
- let text = "";
- // If the last label is not the longest string, alignment will break a little
- let labelPadTo = 0;
- if (aHgram.values.length) {
- labelPadTo = String(aHgram.values[aHgram.values.length - 1][0]).length;
- }
- let maxBarValue = aOptions.exponential ? this.getLogValue(aHgram.max) : aHgram.max;
-
- for (let [label, value] of aHgram.values) {
- let barValue = aOptions.exponential ? this.getLogValue(value) : value;
-
- // Create a text representation: <right-aligned-label> |<bar-of-#><value> <percentage>
- text += EOL
- + " ".repeat(Math.max(0, labelPadTo - String(label).length)) + label // Right-aligned label
- + " |" + "#".repeat(Math.round(MAX_BAR_CHARS * barValue / maxBarValue)) // Bar
- + " " + value // Value
- + " " + Math.round(100 * value / aHgram.sample_count) + "%"; // Percentage
-
- // Construct the HTML labels + bars
- let belowEm = Math.round(MAX_BAR_HEIGHT * (barValue / maxBarValue) * 10) / 10;
- let aboveEm = MAX_BAR_HEIGHT - belowEm;
-
- let barDiv = document.createElement("div");
- barDiv.className = "bar";
- barDiv.style.paddingTop = aboveEm + "em";
-
- // Add value label or an nbsp if no value
- barDiv.appendChild(document.createTextNode(value ? value : '\u00A0'));
-
- // Create the blue bar
- let bar = document.createElement("div");
- bar.className = "bar-inner";
- bar.style.height = belowEm + "em";
- barDiv.appendChild(bar);
-
- // Add bucket label
- barDiv.appendChild(document.createTextNode(label));
-
- aDiv.appendChild(barDiv);
- }
-
- return text.substr(EOL.length); // Trim the EOL before the first line
- },
-
- /**
- * Helper function for filtering histogram elements by their id
- * Adds the "filter-blocked" class to histogram nodes whose IDs don't match the filter.
- *
- * @param aContainerNode Container node containing the histogram class nodes to filter
- * @param aFilterText either text or /RegEx/. If text, case-insensitive and AND words
- */
- filterHistograms: function _filterHistograms(aContainerNode, aFilterText) {
- let filter = aFilterText.toString();
-
- // Pass if: all non-empty array items match (case-sensitive)
- function isPassText(subject, filter) {
- for (let item of filter) {
- if (item.length && subject.indexOf(item) < 0) {
- return false; // mismatch and not a spurious space
- }
- }
- return true;
- }
-
- function isPassRegex(subject, filter) {
- return filter.test(subject);
- }
-
- // Setup normalized filter string (trimmed, lower cased and split on spaces if not RegEx)
- let isPassFunc; // filter function, set once, then applied to all elements
- filter = filter.trim();
- if (filter[0] != "/") { // Plain text: case insensitive, AND if multi-string
- isPassFunc = isPassText;
- filter = filter.toLowerCase().split(" ");
- } else {
- isPassFunc = isPassRegex;
- var r = filter.match(/^\/(.*)\/(i?)$/);
- try {
- filter = RegExp(r[1], r[2]);
- }
- catch (e) { // Incomplete or bad RegExp - always no match
- isPassFunc = function() {
- return false;
- };
- }
- }
-
- let needLower = (isPassFunc === isPassText);
-
- let histograms = aContainerNode.getElementsByClassName("histogram");
- for (let hist of histograms) {
- hist.classList[isPassFunc((needLower ? hist.id.toLowerCase() : hist.id), filter) ? "remove" : "add"]("filter-blocked");
- }
- },
-
- /**
- * Event handler for change at histograms filter input
- *
- * When invoked, 'this' is expected to be the filter HTML node.
- */
- histogramFilterChanged: function _histogramFilterChanged() {
- if (this.idleTimeout) {
- clearTimeout(this.idleTimeout);
- }
-
- this.idleTimeout = setTimeout( () => {
- Histogram.filterHistograms(document.getElementById(this.getAttribute("target_id")), this.value);
- }, FILTER_IDLE_TIMEOUT);
- }
-};
-
-/*
- * Helper function to render JS objects with white space between top level elements
- * so that they look better in the browser
- * @param aObject JavaScript object or array to render
- * @return String
- */
-function RenderObject(aObject) {
- let output = "";
- if (Array.isArray(aObject)) {
- if (aObject.length == 0) {
- return "[]";
- }
- output = "[" + JSON.stringify(aObject[0]);
- for (let i = 1; i < aObject.length; i++) {
- output += ", " + JSON.stringify(aObject[i]);
- }
- return output + "]";
- }
- let keys = Object.keys(aObject);
- if (keys.length == 0) {
- return "{}";
- }
- output = "{\"" + keys[0] + "\":\u00A0" + JSON.stringify(aObject[keys[0]]);
- for (let i = 1; i < keys.length; i++) {
- output += ", \"" + keys[i] + "\":\u00A0" + JSON.stringify(aObject[keys[i]]);
- }
- return output + "}";
-}
-
-var KeyValueTable = {
- /**
- * Returns a 2-column table with keys and values
- * @param aMeasurements Each key in this JS object is rendered as a row in
- * the table with its corresponding value
- * @param aKeysLabel Column header for the keys column
- * @param aValuesLabel Column header for the values column
- */
- render: function KeyValueTable_render(aMeasurements, aKeysLabel, aValuesLabel) {
- let table = document.createElement("table");
- this.renderHeader(table, aKeysLabel, aValuesLabel);
- this.renderBody(table, aMeasurements);
- return table;
- },
-
- /**
- * Create the table header
- * Tabs & newlines added to cells to make it easier to copy-paste.
- *
- * @param aTable Table element
- * @param aKeysLabel Column header for the keys column
- * @param aValuesLabel Column header for the values column
- */
- renderHeader: function KeyValueTable_renderHeader(aTable, aKeysLabel, aValuesLabel) {
- let headerRow = document.createElement("tr");
- aTable.appendChild(headerRow);
-
- let keysColumn = document.createElement("th");
- keysColumn.appendChild(document.createTextNode(aKeysLabel + "\t"));
- let valuesColumn = document.createElement("th");
- valuesColumn.appendChild(document.createTextNode(aValuesLabel + "\n"));
-
- headerRow.appendChild(keysColumn);
- headerRow.appendChild(valuesColumn);
- },
-
- /**
- * Create the table body
- * Tabs & newlines added to cells to make it easier to copy-paste.
- *
- * @param aTable Table element
- * @param aMeasurements Key/value map
- */
- renderBody: function KeyValueTable_renderBody(aTable, aMeasurements) {
- for (let [key, value] of Object.entries(aMeasurements)) {
- // use .valueOf() to unbox Number, String, etc. objects
- if (value &&
- (typeof value == "object") &&
- (typeof value.valueOf() == "object")) {
- value = RenderObject(value);
- }
-
- let newRow = document.createElement("tr");
- aTable.appendChild(newRow);
-
- let keyField = document.createElement("td");
- keyField.appendChild(document.createTextNode(key + "\t"));
- newRow.appendChild(keyField);
-
- let valueField = document.createElement("td");
- valueField.appendChild(document.createTextNode(value + "\n"));
- newRow.appendChild(valueField);
- }
- }
-};
-
-var GenericTable = {
- /**
- * Returns a n-column table.
- * @param rows An array of arrays, each containing data to render
- * for one row.
- * @param headings The column header strings.
- */
- render: function(rows, headings) {
- let table = document.createElement("table");
- this.renderHeader(table, headings);
- this.renderBody(table, rows);
- return table;
- },
-
- /**
- * Create the table header.
- * Tabs & newlines added to cells to make it easier to copy-paste.
- *
- * @param table Table element
- * @param headings Array of column header strings.
- */
- renderHeader: function(table, headings) {
- let headerRow = document.createElement("tr");
- table.appendChild(headerRow);
-
- for (let i = 0; i < headings.length; ++i) {
- let suffix = (i == (headings.length - 1)) ? "\n" : "\t";
- let column = document.createElement("th");
- column.appendChild(document.createTextNode(headings[i] + suffix));
- headerRow.appendChild(column);
- }
- },
-
- /**
- * Create the table body
- * Tabs & newlines added to cells to make it easier to copy-paste.
- *
- * @param table Table element
- * @param rows An array of arrays, each containing data to render
- * for one row.
- */
- renderBody: function(table, rows) {
- for (let row of rows) {
- row = row.map(value => {
- // use .valueOf() to unbox Number, String, etc. objects
- if (value &&
- (typeof value == "object") &&
- (typeof value.valueOf() == "object")) {
- return RenderObject(value);
- }
- return value;
- });
-
- let newRow = document.createElement("tr");
- table.appendChild(newRow);
-
- for (let i = 0; i < row.length; ++i) {
- let suffix = (i == (row.length - 1)) ? "\n" : "\t";
- let field = document.createElement("td");
- field.appendChild(document.createTextNode(row[i] + suffix));
- newRow.appendChild(field);
- }
- }
- }
-};
-
-var KeyedHistogram = {
- render: function(parent, id, keyedHistogram) {
- let outerDiv = document.createElement("div");
- outerDiv.className = "keyed-histogram";
- outerDiv.id = id;
-
- let divTitle = document.createElement("div");
- divTitle.className = "keyed-histogram-title";
- divTitle.appendChild(document.createTextNode(id));
- outerDiv.appendChild(divTitle);
-
- for (let [name, hgram] of Object.entries(keyedHistogram)) {
- Histogram.render(outerDiv, name, hgram);
- }
-
- parent.appendChild(outerDiv);
- return outerDiv;
- },
-};
-
-var AddonDetails = {
- tableIDTitle: bundle.GetStringFromName("addonTableID"),
- tableDetailsTitle: bundle.GetStringFromName("addonTableDetails"),
-
- /**
- * Render the addon details section as a series of headers followed by key/value tables
- * @param aPing A ping object to render the data from.
- */
- render: function AddonDetails_render(aPing) {
- let addonSection = document.getElementById("addon-details");
- removeAllChildNodes(addonSection);
- let addonDetails = aPing.payload.addonDetails;
- const hasData = addonDetails && Object.keys(addonDetails).length > 0;
- setHasData("addon-details-section", hasData);
- if (!hasData) {
- return;
- }
-
- for (let provider in addonDetails) {
- let providerSection = document.createElement("h2");
- let titleText = bundle.formatStringFromName("addonProvider", [provider], 1);
- providerSection.appendChild(document.createTextNode(titleText));
- addonSection.appendChild(providerSection);
- addonSection.appendChild(
- KeyValueTable.render(addonDetails[provider],
- this.tableIDTitle, this.tableDetailsTitle));
- }
- }
-};
-
-var Scalars = {
- /**
- * Render the scalar data - if present - from the payload in a simple key-value table.
- * @param aPayload A payload object to render the data from.
- */
- render: function(aPayload) {
- let scalarsSection = document.getElementById("scalars");
- removeAllChildNodes(scalarsSection);
-
- if (!aPayload.processes || !aPayload.processes.parent) {
- return;
- }
-
- let scalars = aPayload.processes.parent.scalars;
- const hasData = scalars && Object.keys(scalars).length > 0;
- setHasData("scalars-section", hasData);
- if (!hasData) {
- return;
- }
-
- const headingName = bundle.GetStringFromName("namesHeader");
- const headingValue = bundle.GetStringFromName("valuesHeader");
- const table = KeyValueTable.render(scalars, headingName, headingValue);
- scalarsSection.appendChild(table);
- }
-};
-
-var KeyedScalars = {
- /**
- * Render the keyed scalar data - if present - from the payload in a simple key-value table.
- * @param aPayload A payload object to render the data from.
- */
- render: function(aPayload) {
- let scalarsSection = document.getElementById("keyed-scalars");
- removeAllChildNodes(scalarsSection);
-
- if (!aPayload.processes || !aPayload.processes.parent) {
- return;
- }
-
- let keyedScalars = aPayload.processes.parent.keyedScalars;
- const hasData = keyedScalars && Object.keys(keyedScalars).length > 0;
- setHasData("keyed-scalars-section", hasData);
- if (!hasData) {
- return;
- }
-
- const headingName = bundle.GetStringFromName("namesHeader");
- const headingValue = bundle.GetStringFromName("valuesHeader");
- for (let scalar in keyedScalars) {
- // Add the name of the scalar.
- let scalarNameSection = document.createElement("h2");
- scalarNameSection.appendChild(document.createTextNode(scalar));
- scalarsSection.appendChild(scalarNameSection);
- // Populate the section with the key-value pairs from the scalar.
- const table = KeyValueTable.render(keyedScalars[scalar], headingName, headingValue);
- scalarsSection.appendChild(table);
- }
- }
-};
-
-var Events = {
- /**
- * Render the event data - if present - from the payload in a simple table.
- * @param aPayload A payload object to render the data from.
- */
- render: function(aPayload) {
- let eventsSection = document.getElementById("events");
- removeAllChildNodes(eventsSection);
-
- if (!aPayload.processes || !aPayload.processes.parent) {
- return;
- }
-
- const events = aPayload.processes.parent.events;
- const hasData = events && Object.keys(events).length > 0;
- setHasData("events-section", hasData);
- if (!hasData) {
- return;
- }
-
- const headings = [
- "timestamp",
- "category",
- "method",
- "object",
- "value",
- "extra",
- ];
-
- const table = GenericTable.render(events, headings);
- eventsSection.appendChild(table);
- }
-};
-
-/**
- * Helper function for showing either the toggle element or "No data collected" message for a section
- *
- * @param aSectionID ID of the section element that needs to be changed
- * @param aHasData true (default) indicates that toggle should be displayed
- */
-function setHasData(aSectionID, aHasData) {
- let sectionElement = document.getElementById(aSectionID);
- sectionElement.classList[aHasData ? "add" : "remove"]("has-data");
-}
-
-/**
- * Helper function that expands and collapses sections +
- * changes caption on the toggle text
- */
-function toggleSection(aEvent) {
- let parentElement = aEvent.target.parentElement;
- if (!parentElement.classList.contains("has-data") &&
- !parentElement.classList.contains("has-subdata")) {
- return; // nothing to toggle
- }
-
- parentElement.classList.toggle("expanded");
-
- // Store section opened/closed state in a hidden checkbox (which is then used on reload)
- let statebox = parentElement.getElementsByClassName("statebox")[0];
- if (statebox) {
- statebox.checked = parentElement.classList.contains("expanded");
- }
-}
-
-/**
- * Sets the text of the page header based on a config pref + bundle strings
- */
-function setupPageHeader()
-{
- let serverOwner = Preferences.get(PREF_TELEMETRY_SERVER_OWNER, "Mozilla");
- let brandName = brandBundle.GetStringFromName("brandFullName");
- let subtitleText = bundle.formatStringFromName(
- "pageSubtitle", [serverOwner, brandName], 2);
-
- let subtitleElement = document.getElementById("page-subtitle");
- subtitleElement.appendChild(document.createTextNode(subtitleText));
-}
-
-/**
- * Initializes load/unload, pref change and mouse-click listeners
- */
-function setupListeners() {
- Settings.attachObservers();
- PingPicker.attachObservers();
-
- // Clean up observers when page is closed
- window.addEventListener("unload",
- function unloadHandler(aEvent) {
- window.removeEventListener("unload", unloadHandler);
- Settings.detachObservers();
- }, false);
-
- document.getElementById("chrome-hangs-fetch-symbols").addEventListener("click",
- function () {
- if (!gPingData) {
- return;
- }
-
- let hangs = gPingData.payload.chromeHangs;
- let req = new SymbolicationRequest("chrome-hangs",
- ChromeHangs.renderHangHeader,
- hangs.memoryMap,
- hangs.stacks,
- hangs.durations);
- req.fetchSymbols();
- }, false);
-
- document.getElementById("chrome-hangs-hide-symbols").addEventListener("click",
- function () {
- if (!gPingData) {
- return;
- }
-
- ChromeHangs.render(gPingData);
- }, false);
-
- document.getElementById("late-writes-fetch-symbols").addEventListener("click",
- function () {
- if (!gPingData) {
- return;
- }
-
- let lateWrites = gPingData.payload.lateWrites;
- let req = new SymbolicationRequest("late-writes",
- LateWritesSingleton.renderHeader,
- lateWrites.memoryMap,
- lateWrites.stacks);
- req.fetchSymbols();
- }, false);
-
- document.getElementById("late-writes-hide-symbols").addEventListener("click",
- function () {
- if (!gPingData) {
- return;
- }
-
- LateWritesSingleton.renderLateWrites(gPingData.payload.lateWrites);
- }, false);
-
- // Clicking on the section name will toggle its state
- let sectionHeaders = document.getElementsByClassName("section-name");
- for (let sectionHeader of sectionHeaders) {
- sectionHeader.addEventListener("click", toggleSection, false);
- }
-
- // Clicking on the "toggle" text will also toggle section's state
- let toggleLinks = document.getElementsByClassName("toggle-caption");
- for (let toggleLink of toggleLinks) {
- toggleLink.addEventListener("click", toggleSection, false);
- }
-}
-
-function onLoad() {
- window.removeEventListener("load", onLoad);
-
- // Set the text in the page header
- setupPageHeader();
-
- // Set up event listeners
- setupListeners();
-
- // Render settings.
- Settings.render();
-
- // Restore sections states
- let stateboxes = document.getElementsByClassName("statebox");
- for (let box of stateboxes) {
- if (box.checked) { // Was open. Will still display as empty if not has-data
- box.parentElement.classList.add("expanded");
- }
- }
-
- // Update ping data when async Telemetry init is finished.
- Telemetry.asyncFetchTelemetryData(() => PingPicker.update());
-}
-
-var LateWritesSingleton = {
- renderHeader: function LateWritesSingleton_renderHeader(aIndex) {
- StackRenderer.renderHeader("late-writes", [aIndex + 1]);
- },
-
- renderLateWrites: function LateWritesSingleton_renderLateWrites(lateWrites) {
- setHasData("late-writes-section", !!lateWrites);
- if (!lateWrites) {
- return;
- }
-
- let stacks = lateWrites.stacks;
- let memoryMap = lateWrites.memoryMap;
- StackRenderer.renderStacks('late-writes', stacks, memoryMap,
- LateWritesSingleton.renderHeader);
- }
-};
-
-/**
- * Helper function for sorting the startup milestones in the Simple Measurements
- * section into temporal order.
- *
- * @param aSimpleMeasurements Telemetry ping's "Simple Measurements" data
- * @return Sorted measurements
- */
-function sortStartupMilestones(aSimpleMeasurements) {
- const telemetryTimestamps = TelemetryTimestamps.get();
- let startupEvents = Services.startup.getStartupInfo();
- delete startupEvents['process'];
-
- function keyIsMilestone(k) {
- return (k in startupEvents) || (k in telemetryTimestamps);
- }
-
- let sortedKeys = Object.keys(aSimpleMeasurements);
-
- // Sort the measurements, with startup milestones at the front + ordered by time
- sortedKeys.sort(function keyCompare(keyA, keyB) {
- let isKeyAMilestone = keyIsMilestone(keyA);
- let isKeyBMilestone = keyIsMilestone(keyB);
-
- // First order by startup vs non-startup measurement
- if (isKeyAMilestone && !isKeyBMilestone)
- return -1;
- if (!isKeyAMilestone && isKeyBMilestone)
- return 1;
- // Don't change order of non-startup measurements
- if (!isKeyAMilestone && !isKeyBMilestone)
- return 0;
-
- // If both keys are startup measurements, order them by value
- return aSimpleMeasurements[keyA] - aSimpleMeasurements[keyB];
- });
-
- // Insert measurements into a result object in sort-order
- let result = {};
- for (let key of sortedKeys) {
- result[key] = aSimpleMeasurements[key];
- }
-
- return result;
-}
-
-function renderProcessList(ping, selectEl) {
- removeAllChildNodes(selectEl);
- let option = document.createElement("option");
- option.appendChild(document.createTextNode("parent"));
- option.setAttribute("value", "");
- option.selected = true;
- selectEl.appendChild(option);
-
- if (!("processes" in ping.payload)) {
- selectEl.disabled = true;
- return;
- }
- selectEl.disabled = false;
-
- for (let process of Object.keys(ping.payload.processes)) {
- // TODO: parent hgrams are on root payload, not in payload.processes.parent
- // When/If that gets moved, you'll need to remove this:
- if (process === "parent") {
- continue;
- }
- option = document.createElement("option");
- option.appendChild(document.createTextNode(process));
- option.setAttribute("value", process);
- selectEl.appendChild(option);
- }
-}
-
-function renderPayloadList(ping) {
- // Rebuild the payload select with options:
- // Parent Payload (selected)
- // Child Payload 1..ping.payload.childPayloads.length
- let listEl = document.getElementById("choose-payload");
- removeAllChildNodes(listEl);
-
- let option = document.createElement("option");
- let text = bundle.GetStringFromName("parentPayload");
- let content = document.createTextNode(text);
- let payloadIndex = 0;
- option.appendChild(content);
- option.setAttribute("value", payloadIndex++);
- option.selected = true;
- listEl.appendChild(option);
-
- if (!ping.payload.childPayloads) {
- listEl.disabled = true;
- return
- }
- listEl.disabled = false;
-
- for (; payloadIndex <= ping.payload.childPayloads.length; ++payloadIndex) {
- option = document.createElement("option");
- text = bundle.formatStringFromName("childPayloadN", [payloadIndex], 1);
- content = document.createTextNode(text);
- option.appendChild(content);
- option.setAttribute("value", payloadIndex);
- listEl.appendChild(option);
- }
-}
-
-function toggleElementHidden(element, isHidden) {
- if (isHidden) {
- element.classList.add("hidden");
- } else {
- element.classList.remove("hidden");
- }
-}
-
-function togglePingSections(isMainPing) {
- // We always show the sections that are "common" to all pings.
- // The raw payload section is only used for pings other than "main" and "saved-session".
- let commonSections = new Set(["general-data-section", "environment-data-section"]);
- let otherPingSections = new Set(["raw-payload-section"]);
-
- let elements = document.getElementById("structured-ping-data-section").children;
- for (let section of elements) {
- if (commonSections.has(section.id)) {
- continue;
- }
-
- let showElement = isMainPing != otherPingSections.has(section.id);
- toggleElementHidden(section, !showElement);
- }
-}
-
-function displayPingData(ping, updatePayloadList = false) {
- gPingData = ping;
-
- // Render raw ping data.
- let pre = document.getElementById("raw-ping-data");
- pre.textContent = JSON.stringify(gPingData, null, 2);
-
- // Update the structured data rendering.
- const keysHeader = bundle.GetStringFromName("keysHeader");
- const valuesHeader = bundle.GetStringFromName("valuesHeader");
-
- // Update the payload list and process lists
- if (updatePayloadList) {
- renderPayloadList(ping);
- renderProcessList(ping, document.getElementById("histograms-processes"));
- renderProcessList(ping, document.getElementById("keyed-histograms-processes"));
- }
-
- // Show general data.
- GeneralData.render(ping);
-
- // Show environment data.
- EnvironmentData.render(ping);
-
- // We only have special rendering code for the payloads from "main" pings.
- // For any other pings we just render the raw JSON payload.
- let isMainPing = (ping.type == "main" || ping.type == "saved-session");
- togglePingSections(isMainPing);
-
- if (!isMainPing) {
- RawPayload.render(ping);
- return;
- }
-
- // Show telemetry log.
- TelLog.render(ping);
-
- // Show slow SQL stats
- SlowSQL.render(ping);
-
- // Show chrome hang stacks
- ChromeHangs.render(ping);
-
- // Render Addon details.
- AddonDetails.render(ping);
-
- // Select payload to render
- let payloadSelect = document.getElementById("choose-payload");
- let payloadOption = payloadSelect.selectedOptions.item(0);
- let payloadIndex = payloadOption.getAttribute("value");
-
- let payload = ping.payload;
- if (payloadIndex > 0) {
- payload = ping.payload.childPayloads[payloadIndex - 1];
- }
-
- // Show thread hang stats
- ThreadHangStats.render(payload);
-
- // Show simple measurements
- let simpleMeasurements = sortStartupMilestones(payload.simpleMeasurements);
- let hasData = Object.keys(simpleMeasurements).length > 0;
- setHasData("simple-measurements-section", hasData);
- let simpleSection = document.getElementById("simple-measurements");
- removeAllChildNodes(simpleSection);
-
- if (hasData) {
- simpleSection.appendChild(KeyValueTable.render(simpleMeasurements,
- keysHeader, valuesHeader));
- }
-
- LateWritesSingleton.renderLateWrites(payload.lateWrites);
-
- // Show basic session info gathered
- hasData = Object.keys(ping.payload.info).length > 0;
- setHasData("session-info-section", hasData);
- let infoSection = document.getElementById("session-info");
- removeAllChildNodes(infoSection);
-
- if (hasData) {
- infoSection.appendChild(KeyValueTable.render(ping.payload.info,
- keysHeader, valuesHeader));
- }
-
- // Show scalar data.
- Scalars.render(payload);
- KeyedScalars.render(payload);
-
- // Show histogram data
- let hgramDiv = document.getElementById("histograms");
- removeAllChildNodes(hgramDiv);
-
- let histograms = payload.histograms;
-
- let hgramsSelect = document.getElementById("histograms-processes");
- let hgramsOption = hgramsSelect.selectedOptions.item(0);
- let hgramsProcess = hgramsOption.getAttribute("value");
- if (hgramsProcess &&
- "processes" in ping.payload &&
- hgramsProcess in ping.payload.processes) {
- histograms = ping.payload.processes[hgramsProcess].histograms;
- }
-
- hasData = Object.keys(histograms).length > 0;
- setHasData("histograms-section", hasData || hgramsSelect.options.length);
-
- if (hasData) {
- for (let [name, hgram] of Object.entries(histograms)) {
- Histogram.render(hgramDiv, name, hgram, {unpacked: true});
- }
-
- let filterBox = document.getElementById("histograms-filter");
- filterBox.addEventListener("input", Histogram.histogramFilterChanged, false);
- if (filterBox.value.trim() != "") { // on load, no need to filter if empty
- Histogram.filterHistograms(hgramDiv, filterBox.value);
- }
-
- setHasData("histograms-section", true);
- }
-
- // Show keyed histogram data
- let keyedDiv = document.getElementById("keyed-histograms");
- removeAllChildNodes(keyedDiv);
-
- let keyedHistograms = payload.keyedHistograms;
-
- let keyedHgramsSelect = document.getElementById("keyed-histograms-processes");
- let keyedHgramsOption = keyedHgramsSelect.selectedOptions.item(0);
- let keyedHgramsProcess = keyedHgramsOption.getAttribute("value");
- if (keyedHgramsProcess &&
- "processes" in ping.payload &&
- keyedHgramsProcess in ping.payload.processes) {
- keyedHistograms = ping.payload.processes[keyedHgramsProcess].keyedHistograms;
- }
-
- setHasData("keyed-histograms-section", keyedHgramsSelect.options.length);
- if (keyedHistograms) {
- let hasData = false;
- for (let [id, keyed] of Object.entries(keyedHistograms)) {
- if (Object.keys(keyed).length > 0) {
- hasData = true;
- KeyedHistogram.render(keyedDiv, id, keyed, {unpacked: true});
- }
- }
- setHasData("keyed-histograms-section", hasData || keyedHgramsSelect.options.length);
- }
-
- // Show event data.
- Events.render(payload);
-
- // Show addon histogram data
- let addonDiv = document.getElementById("addon-histograms");
- removeAllChildNodes(addonDiv);
-
- let addonHistogramsRendered = false;
- let addonData = payload.addonHistograms;
- if (addonData) {
- for (let [addon, histograms] of Object.entries(addonData)) {
- for (let [name, hgram] of Object.entries(histograms)) {
- addonHistogramsRendered = true;
- Histogram.render(addonDiv, addon + ": " + name, hgram, {unpacked: true});
- }
- }
- }
-
- setHasData("addon-histograms-section", addonHistogramsRendered);
-}
-
-window.addEventListener("load", onLoad, false);
diff --git a/toolkit/content/aboutTelemetry.xhtml b/toolkit/content/aboutTelemetry.xhtml
deleted file mode 100644
index 24b78b9933..0000000000
--- a/toolkit/content/aboutTelemetry.xhtml
+++ /dev/null
@@ -1,290 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- 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/. -->
-
-<!DOCTYPE html [
- <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> %htmlDTD;
- <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> %globalDTD;
- <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
- <!ENTITY % aboutTelemetryDTD SYSTEM "chrome://global/locale/aboutTelemetry.dtd"> %aboutTelemetryDTD;
-]>
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>&aboutTelemetry.pageTitle;</title>
-
- <link rel="stylesheet" href="chrome://global/content/aboutTelemetry.css"
- type="text/css"/>
-
- <script type="application/javascript;version=1.7"
- src="chrome://global/content/aboutTelemetry.js"/>
- </head>
-
- <body dir="&locale.dir;">
-
- <header id="page-description">
- <h1>&aboutTelemetry.pageTitle;</h1>
-
- <h2 id="page-subtitle"></h2>
-
- <table id="settings">
- <tr>
- <td>
- <p id="description-upload-enabled" class="description-enabled">&aboutTelemetry.uploadEnabled;</p>
- <p id="description-upload-disabled" class="description-disabled">&aboutTelemetry.uploadDisabled;</p>
- </td>
- <td>
- <a href="" class="change-data-choices-link">&aboutTelemetry.changeDataChoices;</a>
- </td>
- </tr>
- <tr>
- <td>
- <p id="description-extended-recording-enabled" class="description-enabled">&aboutTelemetry.extendedRecordingEnabled;</p>
- <p id="description-extended-recording-disabled" class="description-disabled">&aboutTelemetry.extendedRecordingDisabled;</p>
- </td>
- <td>
- <a href="" class="change-data-choices-link">&aboutTelemetry.changeDataChoices;</a>
- </td>
- </tr>
- </table>
-
- <div id="ping-picker">
- <div id="ping-source-picker">
- &aboutTelemetry.pingDataSource;<br/>
- <input type="radio" id="ping-source-current" name="choose-ping-source" value="current" checked="checked" />
- &aboutTelemetry.showCurrentPingData;<br />
- <input type="radio" id="ping-source-archive" name="choose-ping-source" value="archive" />
- &aboutTelemetry.showArchivedPingData;<br />
- </div>
- <div id="ping-source-picker">
- &aboutTelemetry.pingDataDisplay;<br/>
- <input type="radio" id="ping-source-structured" name="choose-ping-display" value="structured" checked="checked" />
- &aboutTelemetry.structured;<br />
- <input type="radio" id="ping-source-raw" name="choose-ping-display" value="raw" />
- &aboutTelemetry.raw;<br />
- </div>
- <div id="current-ping-picker">
- <input id="show-subsession-data" type="checkbox" checked="checked" />&aboutTelemetry.showSubsessionData;
- </div>
- <div id="archived-ping-picker" class="hidden">
- &aboutTelemetry.choosePing;<br />
- <button id="newer-ping" type="button">&aboutTelemetry.showNewerPing;</button>
- <button id="older-ping" type="button">&aboutTelemetry.showOlderPing;</button><br />
- <table>
- <tr>
- <th>&aboutTelemetry.archiveWeekHeader;</th>
- <th>&aboutTelemetry.archivePingHeader;</th>
- </tr>
- <tr>
- <td>
- <select id="choose-ping-week">
- </select>
- </td>
- <td>
- <select id="choose-ping-id">
- </select>
- </td>
- </tr>
- </table>
- </div>
- <table>
- <tr>
- <th>&aboutTelemetry.payloadChoiceHeader;</th>
- </tr>
- <tr>
- <td>
- <select id="choose-payload">
- </select>
- </td>
- </tr>
- </table>
- </div>
- </header>
-
- <div id="raw-ping-data-section" class="hidden">
- <pre id="raw-ping-data"></pre>
- </div>
-
- <div id="structured-ping-data-section">
- <section id="general-data-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.generalDataSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="general-data" class="data">
- </div>
- </section>
-
- <section id="environment-data-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.environmentDataSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="environment-data" class="data">
- </div>
- </section>
-
- <section id="session-info-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.sessionInfoSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="session-info" class="data">
- </div>
- </section>
-
- <section id="scalars-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.scalarsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="scalars" class="data">
- </div>
- </section>
-
- <section id="keyed-scalars-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.keyedScalarsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="keyed-scalars" class="data">
- </div>
- </section>
-
- <section id="histograms-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.histogramsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <span class="filter-ui">
- &aboutTelemetry.filterText; <input type="text" class="filter" id="histograms-filter" target_id="histograms"/>
- </span>
- <div class="processes-ui">
- <select id="histograms-processes" class="process-picker"></select>
- </div>
- <div id="histograms" class="data">
- </div>
- </section>
-
- <section id="keyed-histograms-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.keyedHistogramsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div class="processes-ui">
- <select id="keyed-histograms-processes" class="process-picker"></select>
- </div>
- <div id="keyed-histograms" class="data">
- </div>
- </section>
-
- <section id="events-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">Events</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="events" class="data">
- </div>
- </section>
-
- <section id="simple-measurements-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.simpleMeasurementsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="simple-measurements" class="data">
- </div>
- </section>
-
- <section id="telemetry-log-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.telemetryLogSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="telemetry-log" class="data">
- </div>
- </section>
-
- <section id="slow-sql-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.slowSqlSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="slow-sql-tables" class="data">
- <p id="sql-warning" class="hidden">&aboutTelemetry.fullSqlWarning;</p>
- </div>
- </section>
-
- <section id="chrome-hangs-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.chromeHangsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="chrome-hangs" class="data">
- <a id="chrome-hangs-fetch-symbols" href="#">&aboutTelemetry.fetchSymbols;</a>
- <a id="chrome-hangs-hide-symbols" class="hidden" href="#">&aboutTelemetry.hideSymbols;</a>
- <br/>
- <br/>
- <div id="chrome-hangs-data">
- </div>
- </div>
- </section>
-
- <section id="thread-hang-stats-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.threadHangStatsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="thread-hang-stats" class="data">
- </div>
- </section>
-
- <section id="late-writes-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.lateWritesSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="late-writes" class="data">
- <a id="late-writes-fetch-symbols" href="#">&aboutTelemetry.fetchSymbols;</a>
- <a id="late-writes-hide-symbols" class="hidden" href="#">&aboutTelemetry.hideSymbols;</a>
- <br/>
- <br/>
- <div id="late-writes-data">
- </div>
- </div>
- </section>
-
- <section id="addon-details-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.addonDetailsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="addon-details" class="data">
- </div>
- </section>
-
- <section id="addon-histograms-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.addonHistogramsSection;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="addon-histograms" class="data">
- </div>
- </section>
-
- <section id="raw-payload-section" class="data-section">
- <input type="checkbox" class="statebox"/>
- <h1 class="section-name">&aboutTelemetry.rawPayload;</h1>
- <span class="toggle-caption">&aboutTelemetry.toggle;</span>
- <span class="empty-caption">&aboutTelemetry.emptySection;</span>
- <div id="raw-payload-data" class="data">
- <pre id="raw-payload-data-pre"></pre>
- </div>
- </section>
- </div>
-
- </body>
-
-</html>
diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn
index 7a1ce80b9a..1f1c880397 100644
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -30,9 +30,6 @@ toolkit.jar:
#endif
* content/global/aboutSupport.js
* content/global/aboutSupport.xhtml
- content/global/aboutTelemetry.js
- content/global/aboutTelemetry.xhtml
- content/global/aboutTelemetry.css
content/global/directionDetector.html
content/global/plugins.html
content/global/plugins.css
diff --git a/toolkit/mozapps/extensions/AddonManager.jsm b/toolkit/mozapps/extensions/AddonManager.jsm
index f69daa0eb9..aef5c6acba 100644
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -168,7 +168,6 @@ function safeCall(aCallback, ...aArgs) {
*/
function reportProviderError(aProvider, aMethod, aError) {
let method = `provider ${providerName(aProvider)}.${aMethod}`;
- AddonManagerPrivate.recordException("AMI", method, aError);
logger.error("Exception calling " + method, aError);
}
@@ -631,12 +630,6 @@ var AddonManagerInternal = {
providerShutdowns: new Map(),
types: {},
startupChanges: {},
- // Store telemetry details per addon provider
- telemetryDetails: {},
-
- recordTimestamp: function(name, value) {
- this.TelemetryTimestamps.add(name, value);
- },
validateBlocklist: function() {
let appBlocklist = FileUtils.getFile(KEY_APPDIR, [FILE_BLOCKLIST]);
@@ -748,7 +741,6 @@ var AddonManagerInternal = {
})
.catch(err => {
logger.warn("Failure during shutdown of " + name, err);
- AddonManagerPrivate.recordException("AMI", "Async shutdown of " + name, err);
});
};
logger.debug("Registering shutdown blocker for " + name);
@@ -770,12 +762,6 @@ var AddonManagerInternal = {
if (gStarted)
return;
- this.recordTimestamp("AMI_startup_begin");
-
- // clear this for xpcshell test restarts
- for (let provider in this.telemetryDetails)
- delete this.telemetryDetails[provider];
-
let appChanged = undefined;
let oldAppVersion = null;
@@ -822,7 +808,6 @@ var AddonManagerInternal = {
Services.prefs.addObserver(PREF_EM_AUTOUPDATE_DEFAULT, this, false);
let defaultProvidersEnabled = Services.prefs.getBoolPref(PREF_DEFAULT_PROVIDERS_ENABLED, true);
- AddonManagerPrivate.recordSimpleMeasure("default_providers", defaultProvidersEnabled);
// Ensure all default providers have had a chance to register themselves
if (defaultProvidersEnabled) {
@@ -836,12 +821,10 @@ var AddonManagerInternal = {
if ((syms.length < 1) ||
(typeof scope[syms[0]].startup != "function")) {
logger.warn("Provider " + url + " has no startup()");
- AddonManagerPrivate.recordException("AMI", "provider " + url, "no startup()");
}
logger.debug("Loaded provider scope for " + url + ": " + Object.keys(scope).toSource());
}
catch (e) {
- AddonManagerPrivate.recordException("AMI", "provider " + url + " load failed", e);
logger.error("Exception loading default provider \"" + url + "\"", e);
}
};
@@ -860,7 +843,6 @@ var AddonManagerInternal = {
logger.debug(`Loaded provider scope for ${url}`);
}
catch (e) {
- AddonManagerPrivate.recordException("AMI", "provider " + url + " load failed", e);
logger.error("Exception loading provider " + entry + " from category \"" +
url + "\"", e);
}
@@ -886,11 +868,9 @@ var AddonManagerInternal = {
}
gStartupComplete = true;
- this.recordTimestamp("AMI_startup_end");
}
catch (e) {
logger.error("startup failed", e);
- AddonManagerPrivate.recordException("AMI", "startup failed", e);
}
logger.debug("Completed startup sequence");
@@ -1105,7 +1085,6 @@ var AddonManagerInternal = {
catch(err) {
savedError = err;
logger.error("Failure during wait for shutdown barrier", err);
- AddonManagerPrivate.recordException("AMI", "Async shutdown of AddonManager providers", err);
}
}
@@ -1118,7 +1097,6 @@ var AddonManagerInternal = {
catch(err) {
savedError = err;
logger.error("Failure during AddonRepository shutdown", err);
- AddonManagerPrivate.recordException("AMI", "Async shutdown of AddonRepository", err);
}
logger.debug("Async provider shutdown done");
@@ -2518,56 +2496,6 @@ this.AddonManagerPrivate = {
AddonType: AddonType,
- recordTimestamp: function(name, value) {
- AddonManagerInternal.recordTimestamp(name, value);
- },
-
- _simpleMeasures: {},
- recordSimpleMeasure: function(name, value) {
- this._simpleMeasures[name] = value;
- },
-
- recordException: function(aModule, aContext, aException) {
- let report = {
- module: aModule,
- context: aContext
- };
-
- if (typeof aException == "number") {
- report.message = Components.Exception("", aException).name;
- }
- else {
- report.message = aException.toString();
- if (aException.fileName) {
- report.file = aException.fileName;
- report.line = aException.lineNumber;
- }
- }
-
- this._simpleMeasures.exception = report;
- },
-
- getSimpleMeasures: function() {
- return this._simpleMeasures;
- },
-
- getTelemetryDetails: function() {
- return AddonManagerInternal.telemetryDetails;
- },
-
- setTelemetryDetails: function(aProvider, aDetails) {
- AddonManagerInternal.telemetryDetails[aProvider] = aDetails;
- },
-
- // Start a timer, record a simple measure of the time interval when
- // timer.done() is called
- simpleTimer: function(aName) {
- let startTime = Cu.now();
- return {
- done: () => this.recordSimpleMeasure(aName, Math.round(Cu.now() - startTime))
- };
- },
-
/**
* Helper to call update listeners when no update is available.
*
@@ -2969,7 +2897,6 @@ this.AddonManager = {
};
// load the timestamps module into AddonManagerInternal
-Cu.import("resource://gre/modules/TelemetryTimestamps.jsm", AddonManagerInternal);
Object.freeze(AddonManagerInternal);
Object.freeze(AddonManagerPrivate);
Object.freeze(AddonManager);
diff --git a/toolkit/mozapps/extensions/content/update.js b/toolkit/mozapps/extensions/content/update.js
index afc74dca8e..98495b4266 100644
--- a/toolkit/mozapps/extensions/content/update.js
+++ b/toolkit/mozapps/extensions/content/update.js
@@ -243,17 +243,6 @@ var gVersionInfoPage = {
onAllUpdatesFinished: function gVersionInfoPage_onAllUpdatesFinished() {
AddonManager.removeAddonListener(listener);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_disabled",
- gUpdateWizard.disabled);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_enabled",
- gUpdateWizard.metadataEnabled);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_disabled",
- gUpdateWizard.metadataDisabled);
- // Record 0 for these here in case we exit early; values will be replaced
- // later if we actually upgrade any.
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded", 0);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed", 0);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined", 0);
// Filter out any add-ons that are now enabled.
// Tycho:
// logger.debug("VersionInfo updates finished: found " +
@@ -563,12 +552,6 @@ var gInstallingPage = {
if (this._installs.length == this._currentInstall) {
Services.obs.notifyObservers(null, "TEST:all-updates-done", null);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded",
- gUpdateWizard.upgraded);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed",
- gUpdateWizard.upgradeFailed);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined",
- gUpdateWizard.upgradeDeclined);
this._installing = false;
if (gUpdateWizard.shuttingDown) {
return;
diff --git a/toolkit/mozapps/extensions/internal/GMPProvider.jsm b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
index 2ebde08bb1..c894271018 100644
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -454,7 +454,6 @@ var GMPProvider = {
configureLogging();
this._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP",
"GMPProvider.");
- let telemetry = {};
this.buildPluginList();
this.ensureProperCDMInstallState();
@@ -476,14 +475,6 @@ var GMPProvider = {
e.name + " - sandboxing not available?", e);
}
}
-
- if (this.isEnabled) {
- telemetry[id] = {
- userDisabled: wrapper.userDisabled,
- version: wrapper.version,
- applyBackgroundUpdates: wrapper.applyBackgroundUpdates,
- };
- }
}
if (Preferences.get(GMPPrefs.KEY_EME_ENABLED, false)) {
@@ -500,8 +491,6 @@ var GMPProvider = {
this._log.warn("startup - adding clearkey CDM failed", e);
}
}
-
- AddonManagerPrivate.setTelemetryDetails("GMP", telemetry);
},
shutdown: function() {
diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
index 02275b8c49..eb4e54720a 100644
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -201,7 +201,7 @@ const RESTARTLESS_TYPES = new Set([
"locale",
]);
-// Keep track of where we are in startup for telemetry
+// Keep track of where we are in startup.
// event happened during XPIDatabase.startup()
const XPI_STARTING = "XPIStarting";
// event happened after startup() but before the final-ui-startup event
@@ -1828,13 +1828,11 @@ this.XPIProvider = {
allAppGlobal: true,
// A string listing the enabled add-ons for annotating crash reports
enabledAddons: null,
- // Keep track of startup phases for telemetry
+ // Keep track of startup phases.
runPhase: XPI_STARTING,
// Keep track of the newest file in each add-on, in case we want to
- // report it to telemetry.
+ // report it.
_mostRecentlyModifiedFile: {},
- // Per-addon telemetry information
- _telemetryDetails: {},
// Experiments are disabled by default. Track ones that are locally enabled.
_enabledExperiments: null,
// A Map from an add-on install to its ID
@@ -2004,8 +2002,6 @@ this.XPIProvider = {
}
try {
- AddonManagerPrivate.recordTimestamp("XPI_startup_begin");
-
logger.debug("startup");
this.runPhase = XPI_STARTING;
this.installs = [];
@@ -2013,8 +2009,6 @@ this.XPIProvider = {
this.installLocationsByName = {};
// Hook for tests to detect when saving database at shutdown time fails
this._shutdownError = null;
- // Clear this at startup for xpcshell test restarts
- this._telemetryDetails = {};
// Clear the set of enabled experiments (experiments disabled by default).
this._enabledExperiments = new Set();
@@ -2139,21 +2133,7 @@ this.XPIProvider = {
this.enabledAddons = Preferences.get(PREF_EM_ENABLED_ADDONS, "");
- if ("nsICrashReporter" in Ci &&
- Services.appinfo instanceof Ci.nsICrashReporter) {
- // Annotate the crash report with relevant add-on information.
- try {
- Services.appinfo.annotateCrashReport("Theme", this.currentSkin);
- } catch (e) { }
- try {
- Services.appinfo.annotateCrashReport("EMCheckCompatibility",
- AddonManager.checkCompatibility);
- } catch (e) { }
- this.addAddonsToCrashReporter();
- }
-
try {
- AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_begin");
for (let id in this.bootstrappedAddons) {
try {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
@@ -2172,11 +2152,9 @@ this.XPIProvider = {
this.bootstrappedAddons[id].descriptor, e);
}
}
- AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_end");
}
catch (e) {
logger.error("bootstrap startup failed", e);
- AddonManagerPrivate.recordException("XPI-BOOTSTRAP", "startup failed", e);
}
// Let these shutdown a little earlier when they still have access to most
@@ -2195,23 +2173,11 @@ this.XPIProvider = {
}
}, "quit-application-granted", false);
- // Detect final-ui-startup for telemetry reporting
- Services.obs.addObserver({
- observe: function uiStartupObserver(aSubject, aTopic, aData) {
- AddonManagerPrivate.recordTimestamp("XPI_finalUIStartup");
- XPIProvider.runPhase = XPI_AFTER_UI_STARTUP;
- Services.obs.removeObserver(this, "final-ui-startup");
- }
- }, "final-ui-startup", false);
-
- AddonManagerPrivate.recordTimestamp("XPI_startup_end");
-
this.extensionsActive = true;
this.runPhase = XPI_BEFORE_UI_STARTUP;
}
catch (e) {
logger.error("startup failed", e);
- AddonManagerPrivate.recordException("XPI", "startup failed", e);
}
},
@@ -2235,7 +2201,6 @@ this.XPIProvider = {
// If there are pending operations then we must update the list of active
// add-ons
if (Preferences.get(PREF_PENDING_OPERATIONS, false)) {
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_pending_ops", 1);
XPIDatabase.updateActiveAddons();
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS,
!XPIDatabase.writeAddonsList());
@@ -2302,11 +2267,8 @@ this.XPIProvider = {
* to be updated, but the metadata check needs to be performed.
*/
shouldForceUpdateCheck: function XPI_shouldForceUpdateCheck(aAppChanged) {
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_metadata_age", AddonRepository.metadataAge());
-
let startupChanges = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
logger.debug("shouldForceUpdateCheck startupChanges: " + startupChanges.toSource());
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startup_disabled", startupChanges.length);
let forceUpdate = [];
if (startupChanges.length > 0) {
@@ -2400,10 +2362,6 @@ this.XPIProvider = {
Services.appinfo.annotateCrashReport("Add-ons", data);
}
catch (e) { }
-
- let TelemetrySession =
- Cu.import("resource://gre/modules/TelemetrySession.jsm", {}).TelemetrySession;
- TelemetrySession.setAddOns(data);
},
/**
@@ -3549,11 +3507,7 @@ this.XPIProvider = {
}
}
- // Telemetry probe added around getInstallState() to check perf
- let telemetryCaptureTime = Cu.now();
let installChanged = XPIStates.getInstallState();
- let telemetry = Services.telemetry;
- telemetry.getHistogramById("CHECK_ADDONS_MODIFIED_MS").add(Math.round(Cu.now() - telemetryCaptureTime));
if (installChanged) {
updateReasons.push("directoryState");
}
@@ -3605,7 +3559,6 @@ this.XPIProvider = {
// If the database needs to be updated then open it and then update it
// from the filesystem
if (updateReasons.length > 0) {
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startup_load_reasons", updateReasons);
XPIDatabase.syncLoadDB(false);
try {
extensionListChanged = this.processFileChanges(manifests,
@@ -6421,7 +6374,6 @@ AddonInternal.prototype = {
let message = "Problem with addon " + this.id + " targetPlatforms "
+ JSON.stringify(this.targetPlatforms);
logger.error(message, e);
- AddonManagerPrivate.recordException("XPI", message, e);
// don't trust this add-on
return false;
}
diff --git a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
index 02c7fa29a8..9f3273b1a5 100644
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -428,7 +428,6 @@ this.XPIDatabase = {
// use an Error here so we get a stack trace.
let err = new Error("XPI database modified after shutdown began");
logger.warn(err);
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_late_stack", Log.stackTrace(err));
}
if (!this._deferredSave) {
@@ -536,7 +535,6 @@ this.XPIDatabase = {
let fstream = null;
let data = "";
try {
- let readTimer = AddonManagerPrivate.simpleTimer("XPIDB_syncRead_MS");
logger.debug("Opening XPI database " + this.jsonFile.path);
fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
@@ -554,14 +552,11 @@ this.XPIDatabase = {
data += str.value;
} while (read != 0);
- readTimer.done();
this.parseDB(data, aRebuildOnError);
}
catch(e) {
logger.error("Failed to load XPI JSON data from profile", e);
- let rebuildTimer = AddonManagerPrivate.simpleTimer("XPIDB_rebuildReadFailed_MS");
this.rebuildDatabase(aRebuildOnError);
- rebuildTimer.done();
}
finally {
if (cstream)
@@ -583,7 +578,6 @@ this.XPIDatabase = {
// If an async load was also in progress, resolve that promise with our DB;
// otherwise create a resolved promise
if (this._dbPromise) {
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_overlapped_load", 1);
this._dbPromise.resolve(this.addonDB);
}
else
@@ -596,27 +590,20 @@ this.XPIDatabase = {
* If true, synchronously reconstruct the database from installed add-ons
*/
parseDB: function(aData, aRebuildOnError) {
- let parseTimer = AddonManagerPrivate.simpleTimer("XPIDB_parseDB_MS");
try {
// dump("Loaded JSON:\n" + aData + "\n");
let inputAddons = JSON.parse(aData);
// Now do some sanity checks on our JSON db
if (!("schemaVersion" in inputAddons) || !("addons" in inputAddons)) {
- parseTimer.done();
// Content of JSON file is bad, need to rebuild from scratch
logger.error("bad JSON file contents");
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "badJSON");
- let rebuildTimer = AddonManagerPrivate.simpleTimer("XPIDB_rebuildBadJSON_MS");
this.rebuildDatabase(aRebuildOnError);
- rebuildTimer.done();
return;
}
if (inputAddons.schemaVersion != DB_SCHEMA) {
// Handle mismatched JSON schema version. For now, we assume
// compatibility for JSON data, though we throw away any fields we
// don't know about (bug 902956)
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError",
- "schemaMismatch-" + inputAddons.schemaVersion);
logger.debug("JSON schema mismatch: expected " + DB_SCHEMA +
", actual " + inputAddons.schemaVersion);
// When we rev the schema of the JSON database, we need to make sure we
@@ -630,7 +617,6 @@ this.XPIDatabase = {
let newAddon = new DBAddonInternal(loadedAddon);
addonDB.set(newAddon._key, newAddon);
};
- parseTimer.done();
this.addonDB = addonDB;
logger.debug("Successfully read XPI database");
this.initialized = true;
@@ -638,18 +624,13 @@ this.XPIDatabase = {
catch(e) {
// If we catch and log a SyntaxError from the JSON
// parser, the xpcshell test harness fails the test for us: bug 870828
- parseTimer.done();
if (e.name == "SyntaxError") {
logger.error("Syntax error parsing saved XPI JSON data");
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "syntax");
}
else {
logger.error("Failed to load XPI JSON data from profile", e);
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "other");
}
- let rebuildTimer = AddonManagerPrivate.simpleTimer("XPIDB_rebuildReadFailed_MS");
this.rebuildDatabase(aRebuildOnError);
- rebuildTimer.done();
}
},
@@ -657,7 +638,6 @@ this.XPIDatabase = {
* Upgrade database from earlier (sqlite or RDF) version if available
*/
upgradeDB: function(aRebuildOnError) {
- let upgradeTimer = AddonManagerPrivate.simpleTimer("XPIDB_upgradeDB_MS");
try {
let schemaVersion = Services.prefs.getIntPref(PREF_DB_SCHEMA);
if (schemaVersion <= LAST_SQLITE_DB_SCHEMA) {
@@ -668,7 +648,6 @@ this.XPIDatabase = {
else {
// we've upgraded before but the JSON file is gone, fall through
// and rebuild from scratch
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "dbMissing");
}
}
catch(e) {
@@ -678,7 +657,6 @@ this.XPIDatabase = {
}
this.rebuildDatabase(aRebuildOnError);
- upgradeTimer.done();
},
/**
@@ -686,15 +664,12 @@ this.XPIDatabase = {
* (for example because read permission is denied)
*/
rebuildUnreadableDB: function(aError, aRebuildOnError) {
- let rebuildTimer = AddonManagerPrivate.simpleTimer("XPIDB_rebuildUnreadableDB_MS");
logger.warn("Extensions database " + this.jsonFile.path +
" exists but is not readable; rebuilding", aError);
// Remember the error message until we try and write at least once, so
// we know at shutdown time that there was a problem
this._loadError = aError;
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "unreadable");
this.rebuildDatabase(aRebuildOnError);
- rebuildTimer.done();
},
/**
@@ -712,24 +687,19 @@ this.XPIDatabase = {
}
logger.debug("Starting async load of XPI database " + this.jsonFile.path);
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_async_load", XPIProvider.runPhase);
let readOptions = {
outExecutionDuration: 0
};
return this._dbPromise = OS.File.read(this.jsonFile.path, null, readOptions).then(
byteArray => {
logger.debug("Async JSON file read took " + readOptions.outExecutionDuration + " MS");
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_asyncRead_MS",
- readOptions.outExecutionDuration);
if (this._addonDB) {
logger.debug("Synchronous load completed while waiting for async load");
return this.addonDB;
}
logger.debug("Finished async read of XPI database, parsing...");
- let decodeTimer = AddonManagerPrivate.simpleTimer("XPIDB_decode_MS");
let decoder = new TextDecoder();
let data = decoder.decode(byteArray);
- decodeTimer.done();
this.parseDB(data, true);
return this.addonDB;
})
@@ -1006,21 +976,11 @@ this.XPIDatabase = {
this.initialized = false;
- if (this._deferredSave) {
- AddonManagerPrivate.recordSimpleMeasure(
- "XPIDB_saves_total", this._deferredSave.totalSaves);
- AddonManagerPrivate.recordSimpleMeasure(
- "XPIDB_saves_overlapped", this._deferredSave.overlappedSaves);
- AddonManagerPrivate.recordSimpleMeasure(
- "XPIDB_saves_late", this._deferredSave.dirty ? 1 : 0);
- }
-
// Return a promise that any pending writes of the DB are complete and we
// are finished cleaning up
let flushPromise = this.flush();
flushPromise.then(null, error => {
logger.error("Flush of XPI database failed", error);
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_shutdownFlush_failed", 1);
// If our last attempt to read or write the DB failed, force a new
// extensions.ini to be written to disk on the next startup
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, true);
@@ -1139,7 +1099,6 @@ this.XPIDatabase = {
// an XPI theme to a lightweight theme before the DB has loaded,
// because we're called from sync XPIProvider.addonChanged
logger.warn("Synchronous load of XPI database due to getAddonsByType(" + aType + ")");
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_byType", XPIProvider.runPhase);
this.syncLoadDB(true);
}
return _filterDB(this.addonDB, aAddon => (aAddon.type == aType));
@@ -1156,8 +1115,6 @@ this.XPIDatabase = {
if (!this.addonDB) {
// This may be called when the DB hasn't otherwise been loaded
logger.warn("Synchronous load of XPI database due to getVisibleAddonForInternalName");
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_forInternalName",
- XPIProvider.runPhase);
this.syncLoadDB(true);
}
@@ -1228,8 +1185,6 @@ this.XPIDatabase = {
*/
addAddonMetadata: function XPIDB_addAddonMetadata(aAddon, aDescriptor) {
if (!this.addonDB) {
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_addMetadata",
- XPIProvider.runPhase);
this.syncLoadDB(false);
}
@@ -1358,8 +1313,6 @@ this.XPIDatabase = {
if (!this.addonDB) {
logger.warn("updateActiveAddons called when DB isn't loaded");
// force the DB to load
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_updateActive",
- XPIProvider.runPhase);
this.syncLoadDB(true);
}
logger.debug("Updating add-on states");
@@ -1379,8 +1332,6 @@ this.XPIDatabase = {
writeAddonsList: function XPIDB_writeAddonsList() {
if (!this.addonDB) {
// force the DB to load
- AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_writeList",
- XPIProvider.runPhase);
this.syncLoadDB(true);
}
Services.appinfo.invalidateCachesOnRestart();