This patch enables sending the "update" ping with reason "success" after the browser is restarted when an update is successfully applied. MozReview-Commit-ID: 8LYxhTTrs7l
153 lines
4.9 KiB
JavaScript
153 lines
4.9 KiB
JavaScript
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|
|
|
Cu.import("resource://gre/modules/Log.jsm", this);
|
|
Cu.import("resource://gre/modules/Services.jsm", this);
|
|
Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
|
|
"resource://gre/modules/TelemetryController.jsm");
|
|
|
|
const LOGGER_NAME = "Toolkit.Telemetry";
|
|
const PING_TYPE = "update";
|
|
const UPDATE_DOWNLOADED_TOPIC = "update-downloaded";
|
|
|
|
this.EXPORTED_SYMBOLS = ["UpdatePing"];
|
|
|
|
/**
|
|
* This module is responsible for listening to all the relevant update
|
|
* signals, gathering the needed information and assembling the "update"
|
|
* ping.
|
|
*/
|
|
this.UpdatePing = {
|
|
earlyInit() {
|
|
this._log = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, "UpdatePing::");
|
|
this._enabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.UpdatePing, false);
|
|
|
|
this._log.trace("init - enabled: " + this._enabled);
|
|
|
|
if (!this._enabled) {
|
|
return;
|
|
}
|
|
|
|
Services.obs.addObserver(this, UPDATE_DOWNLOADED_TOPIC);
|
|
},
|
|
|
|
/**
|
|
* Get the information about the update we're going to apply/was just applied
|
|
* from the update manager.
|
|
*
|
|
* @return {nsIUpdate} The information about the update, if available, or null.
|
|
*/
|
|
_getActiveUpdate() {
|
|
let updateManager =
|
|
Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager);
|
|
if (!updateManager || !updateManager.activeUpdate) {
|
|
return null;
|
|
}
|
|
|
|
return updateManager.activeUpdate;
|
|
},
|
|
|
|
/**
|
|
* Generate an "update" ping with reason "success" and dispatch it
|
|
* to the Telemetry system.
|
|
*
|
|
* @param {String} aPreviousVersion The browser version we updated from.
|
|
* @param {String} aPreviousBuildId The browser build id we updated from.
|
|
*/
|
|
handleUpdateSuccess(aPreviousVersion, aPreviousBuildId) {
|
|
this._log.trace("handleUpdateSuccess");
|
|
|
|
// An update could potentially change the update channel. Moreover,
|
|
// updates can only be applied if the update's channel matches with the build channel.
|
|
// There's no way to pass this information from the caller nor the environment as,
|
|
// in that case, the environment would report the "new" channel. However, the
|
|
// update manager should still have information about the active update: given the
|
|
// previous assumptions, we can simply get the channel from the update and assume
|
|
// it matches with the state previous to the update.
|
|
let update = this._getActiveUpdate();
|
|
|
|
const payload = {
|
|
reason: "success",
|
|
previousChannel: update ? update.channel : null,
|
|
previousVersion: aPreviousVersion,
|
|
previousBuildId: aPreviousBuildId,
|
|
};
|
|
|
|
const options = {
|
|
addClientId: true,
|
|
addEnvironment: true,
|
|
usePingSender: false,
|
|
};
|
|
|
|
TelemetryController.submitExternalPing(PING_TYPE, payload, options)
|
|
.catch(e => this._log.error("handleUpdateSuccess - failed to submit update ping", e));
|
|
},
|
|
|
|
/**
|
|
* Generate an "update" ping with reason "ready" and dispatch it
|
|
* to the Telemetry system.
|
|
*
|
|
* @param {String} aUpdateState The state of the downloaded patch. See
|
|
* nsIUpdateService.idl for a list of possible values.
|
|
*/
|
|
_handleUpdateReady(aUpdateState) {
|
|
const ALLOWED_STATES = [
|
|
"applied", "applied-service", "pending", "pending-service", "pending-elevate"
|
|
];
|
|
if (!ALLOWED_STATES.includes(aUpdateState)) {
|
|
this._log.trace("Unexpected update state: " + aUpdateState);
|
|
return;
|
|
}
|
|
|
|
// Get the information about the update we're going to apply from the
|
|
// update manager.
|
|
let update = this._getActiveUpdate();
|
|
if (!update) {
|
|
this._log.trace("Cannot get the update manager or no update is currently active.");
|
|
return;
|
|
}
|
|
|
|
const payload = {
|
|
reason: "ready",
|
|
targetChannel: update.channel,
|
|
targetVersion: update.appVersion,
|
|
targetBuildId: update.buildID,
|
|
};
|
|
|
|
const options = {
|
|
addClientId: true,
|
|
addEnvironment: true,
|
|
usePingSender: true,
|
|
};
|
|
|
|
TelemetryController.submitExternalPing(PING_TYPE, payload, options)
|
|
.catch(e => this._log.error("_handleUpdateReady - failed to submit update ping", e));
|
|
},
|
|
|
|
/**
|
|
* The notifications handler.
|
|
*/
|
|
observe(aSubject, aTopic, aData) {
|
|
this._log.trace("observe - aTopic: " + aTopic);
|
|
if (aTopic == UPDATE_DOWNLOADED_TOPIC) {
|
|
this._handleUpdateReady(aData);
|
|
}
|
|
},
|
|
|
|
shutdown() {
|
|
if (!this._enabled) {
|
|
return;
|
|
}
|
|
Services.obs.removeObserver(this, UPDATE_DOWNLOADED_TOPIC);
|
|
},
|
|
};
|