diff --git a/browser/components/migration/MigrationUtils.jsm b/browser/components/migration/MigrationUtils.jsm
index 7e1173f2e99c..0b559f9b1c32 100644
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -13,6 +13,7 @@ const TOPIC_DID_IMPORT_BOOKMARKS = "initial-migration-did-import-default-bookmar
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
+Cu.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
@@ -545,12 +546,21 @@ this.MigrationUtils = Object.freeze({
* Show the migration wizard. On mac, this may just focus the wizard if it's
* already running, in which case aOpener and aParams are ignored.
*
- * @param [optional] aOpener
- * the window that asks to open the wizard.
- * @param [optioanl] aParams
- * arguments for the migration wizard, in the form of an nsIArray.
+ * @param {Window} [aOpener]
+ * optional; the window that asks to open the wizard.
+ * @param {Array} [aParams]
+ * optional arguments for the migration wizard, in the form of an array
* This is passed as-is for the params argument of
- * nsIWindowWatcher.openWindow.
+ * nsIWindowWatcher.openWindow. The array elements we expect are, in
+ * order:
+ * - {Number} migration entry point constant (see below)
+ * - {String} source browser identifier
+ * - {nsIBrowserProfileMigrator} actual migrator object
+ * - {Boolean} whether this is a startup migration
+ * - {Boolean} whether to skip the 'source' page
+ * NB: If you add new consumers, please add a migration entry point
+ * constant below, and specify at least the first element of the array
+ * (the migration entry point for purposes of telemetry).
*/
showMigrationWizard:
function MU_showMigrationWizard(aOpener, aParams) {
@@ -636,18 +646,18 @@ this.MigrationUtils = Object.freeze({
}
}
- let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
- let keyCSTR = Cc["@mozilla.org/supports-cstring;1"].
- createInstance(Ci.nsISupportsCString);
- keyCSTR.data = migratorKey;
- let skipImportSourcePageBool = Cc["@mozilla.org/supports-PRBool;1"].
- createInstance(Ci.nsISupportsPRBool);
- skipImportSourcePageBool.data = skipSourcePage;
- params.appendElement(keyCSTR, false);
- params.appendElement(migrator, false);
- params.appendElement(aProfileStartup, false);
- params.appendElement(skipImportSourcePageBool, false);
+ let migrationEntryPoint = this.MIGRATION_ENTRYPOINT_FIRSTRUN;
+ if (migrator && skipSourcePage && migratorKey == AppConstants.MOZ_APP_NAME) {
+ migrationEntryPoint = this.MIGRATION_ENTRYPOINT_FXREFRESH;
+ }
+ let params = [
+ migrationEntryPoint,
+ migratorKey,
+ migrator,
+ aProfileStartup,
+ skipSourcePage
+ ];
this.showMigrationWizard(null, params);
},
@@ -658,5 +668,26 @@ this.MigrationUtils = Object.freeze({
gMigrators = null;
gProfileStartup = null;
gMigrationBundle = null;
- }
+ },
+
+ MIGRATION_ENTRYPOINT_UNKNOWN: 0,
+ MIGRATION_ENTRYPOINT_FIRSTRUN: 1,
+ MIGRATION_ENTRYPOINT_FXREFRESH: 2,
+ MIGRATION_ENTRYPOINT_PLACES: 3,
+ MIGRATION_ENTRYPOINT_PASSWORDS: 4,
+
+ _sourceNameToIdMapping: {
+ "nothing": 1,
+ "firefox": 2,
+ "edge": 3,
+ "ie": 4,
+ "chrome": 5,
+ "chromium": 6,
+ "canary": 7,
+ "safari": 8,
+ "360se": 9,
+ },
+ getSourceIdForTelemetry(sourceName) {
+ return this._sourceNameToIdMapping[sourceName] || 0;
+ },
});
diff --git a/browser/components/migration/content/migration.js b/browser/components/migration/content/migration.js
index 44dbdfeb8097..6fc87bf05738 100644
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -9,6 +9,7 @@ var Cu = Components.utils;
const kIMig = Ci.nsIBrowserProfileMigrator;
const kIPStartup = Ci.nsIProfileStartup;
+Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/MigrationUtils.jsm");
var MigrationWizard = {
@@ -21,8 +22,7 @@ var MigrationWizard = {
init: function ()
{
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
+ let os = Services.obs;
os.addObserver(this, "Migration:Started", false);
os.addObserver(this, "Migration:ItemBeforeMigrate", false);
os.addObserver(this, "Migration:ItemAfterMigrate", false);
@@ -31,18 +31,20 @@ var MigrationWizard = {
this._wiz = document.documentElement;
- if ("arguments" in window && window.arguments.length > 1) {
- this._source = window.arguments[0];
- this._migrator = window.arguments[1] instanceof kIMig ?
- window.arguments[1] : null;
- this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup);
- this._skipImportSourcePage = window.arguments[3];
+ let args = (window.arguments && window.arguments[0]) || [];
+ let entryPointId = args[0] || MigrationUtils.MIGRATION_ENTRYPOINT_UNKNOWN;
+ Services.telemetry.getHistogramById("FX_MIGRATION_ENTRY_POINT").add(entryPointId);
+
+ if (args.length > 1) {
+ this._source = args[1];
+ this._migrator = args[2] instanceof kIMig ? args[2] : null;
+ this._autoMigrate = args[3].QueryInterface(kIPStartup);
+ this._skipImportSourcePage = args[4];
if (this._autoMigrate) {
// Show the "nothing" option in the automigrate case to provide an
// easily identifiable way to avoid migration and create a new profile.
- var nothing = document.getElementById("nothing");
- nothing.hidden = false;
+ document.getElementById("nothing").hidden = false;
}
}
@@ -122,6 +124,11 @@ var MigrationWizard = {
var newSource = document.getElementById("importSourceGroup").selectedItem.id;
if (newSource == "nothing") {
+ // Need to do telemetry here because we're closing the dialog before we get to
+ // do actual migration. For actual migration, this doesn't happen until after
+ // migration takes place.
+ Services.telemetry.getHistogramById("FX_MIGRATION_SOURCE_BROWSER")
+ .add(MigrationUtils.getSourceIdForTelemetry("nothing"));
document.documentElement.cancel();
return false;
}
@@ -357,12 +364,27 @@ var MigrationWizard = {
this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
this._listItems("migratingItems");
- setTimeout(this.onMigratingMigrate, 0, this);
+ setTimeout(() => this.onMigratingMigrate(), 0);
},
- onMigratingMigrate: function (aOuter)
+ onMigratingMigrate: function ()
{
- aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile);
+ this._migrator.migrate(this._itemsFlags, this._autoMigrate, this._selectedProfile);
+
+ Services.telemetry.getHistogramById("FX_MIGRATION_SOURCE_BROWSER")
+ .add(MigrationUtils.getSourceIdForTelemetry(this._source));
+ if (!this._autoMigrate) {
+ let hist = Services.telemetry.getKeyedHistogramById("FX_MIGRATION_USAGE");
+ let exp = 0;
+ let items = this._itemsFlags;
+ while (items) {
+ if (items & 1) {
+ hist.add(this._source, exp);
+ }
+ items = items >> 1;
+ exp++
+ }
+ }
},
_listItems: function (aID)
@@ -409,6 +431,8 @@ var MigrationWizard = {
break;
case "Migration:Ended":
if (this._autoMigrate) {
+ Services.telemetry.getKeyedHistogramById("FX_MIGRATION_HOMEPAGE_IMPORTED")
+ .add(this._source, !!this._newHomePage);
if (this._newHomePage) {
try {
// set homepage properly
@@ -451,8 +475,9 @@ var MigrationWizard = {
}
break;
case "Migration:ItemError":
- var type = "undefined";
- switch (parseInt(aData)) {
+ let type = "undefined";
+ let numericType = parseInt(aData);
+ switch (numericType) {
case Ci.nsIBrowserProfileMigrator.SETTINGS:
type = "settings";
break;
@@ -478,6 +503,8 @@ var MigrationWizard = {
Cc["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService)
.logStringMessage("some " + type + " did not successfully migrate.");
+ Services.telemetry.getKeyedHistogramById("FX_MIGRATION_ERRORS")
+ .add(this._source, Math.log2(numericType));
break;
}
},
diff --git a/browser/components/migration/content/migration.xul b/browser/components/migration/content/migration.xul
index 679082390e8e..a11a4bb7f9ff 100644
--- a/browser/components/migration/content/migration.xul
+++ b/browser/components/migration/content/migration.xul
@@ -32,6 +32,7 @@
&importFromBookmarks.label;
+# NB: if you add items to this list, please also assign them a unique migrator ID in MigrationUtils.jsm
#ifdef XP_WIN
diff --git a/browser/components/places/content/places.js b/browser/components/places/content/places.js
index 81895105cc69..9a1b669fec87 100644
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -362,7 +362,8 @@ var PlacesOrganizer = {
* cookies, history, preferences, and bookmarks.
*/
importFromBrowser: function PO_importFromBrowser() {
- MigrationUtils.showMigrationWizard(window);
+ // We pass in the type of source we're using for use in telemetry:
+ MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_PLACES]);
},
/**
diff --git a/toolkit/components/passwordmgr/content/passwordManager.js b/toolkit/components/passwordmgr/content/passwordManager.js
index 5fc9e915292a..5ed30f892893 100644
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -452,5 +452,6 @@ function escapeKeyHandler() {
function OpenMigrator() {
const { MigrationUtils } = Cu.import("resource:///modules/MigrationUtils.jsm", {});
- MigrationUtils.showMigrationWizard(window);
+ // We pass in the type of source we're using for use in telemetry:
+ MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_PASSWORDS]);
}
diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json
index f6fb7453ceec..6879fde5c9fd 100644
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -4177,6 +4177,43 @@
"kind": "boolean",
"description": "THUMBNAILS: Thumbnail found"
},
+ "FX_MIGRATION_ENTRY_POINT": {
+ "expires_in_version": "49",
+ "kind": "enumerated",
+ "n_values": 10,
+ "releaseChannelCollection": "opt-out",
+ "description": "Where the migration wizard was entered from. 0=Other/catch-all, 1=first-run, 2=refresh-firefox, 3=Places window, 4=Password manager"
+ },
+ "FX_MIGRATION_SOURCE_BROWSER": {
+ "expires_in_version": "49",
+ "kind": "enumerated",
+ "n_values": 15,
+ "releaseChannelCollection": "opt-out",
+ "description": "The browser that data is pulled from. The values correspond to the internal browser ID (see MigrationUtils.jsm)"
+ },
+ "FX_MIGRATION_ERRORS": {
+ "expires_in_version": "49",
+ "kind": "enumerated",
+ "keyed": "true",
+ "n_values": 12,
+ "releaseChannelCollection": "opt-out",
+ "description": "Errors encountered during migration in buckets defined by the datatype, keyed by the string description of the browser."
+ },
+ "FX_MIGRATION_USAGE": {
+ "expires_in_version": "49",
+ "kind": "enumerated",
+ "keyed": "true",
+ "n_values": 12,
+ "releaseChannelCollection": "opt-out",
+ "description": "Usage of migration for each datatype when migration is run through the post-firstrun flow which allows individual datatypes, keyed by the string description of the browser."
+ },
+ "FX_MIGRATION_HOMEPAGE_IMPORTED": {
+ "expires_in_version": "49",
+ "kind": "boolean",
+ "keyed": "true",
+ "releaseChannelCollection": "opt-out",
+ "description": "Whether the homepage was imported during browser migration. Only available on release builds during firstrun."
+ },
"EVENTLOOP_UI_LAG_EXP_MS": {
"alert_emails": ["perf-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",