roller.submitExternalPing(
      PING_TYPE,
      payload,
      options
    ).catch(e => {
      progress.pingFailed = true;
      this._log.error("handleUpdateSuccess - failed to submit update ping", e);
    });

    if (update) {
      Glean.update.previousChannel.set(update.channel);
    }
    Glean.update.previousVersion.set(aPreviousVersion);
    Glean.update.previousBuildId.set(aPreviousBuildId);
    GleanPings.update.submit("success");
  },

  /**
   * 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.
   */
  async _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 updateManager = Cc["@mozilla.org/updates/update-manager;1"].getService(
      Ci.nsIUpdateManager
    );
    let update = updateManager ? await updateManager.getReadyUpdate() : null;
    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,
      targetDisplayVersion: update.displayVersion,
    };

    const options = {
      addClientId: true,
      addEnvironment: true,
      usePingSender: true,
    };

    lazy.TelemetryController.submitExternalPing(
      PING_TYPE,
      payload,
      options
    ).catch(e =>
      this._log.error("_handleUpdateReady - failed to submit update ping", e)
    );

    Glean.update.targetChannel.set(update.channel);
    Glean.update.targetVersion.set(update.appVersion);
    Glean.update.targetBuildId.set(update.buildID);
    Glean.update.targetDisplayVersion.set(update.displayVersion);
    GleanPings.update.submit("ready");
  },

  /**
   * The notifications handler.
   */
  async observe(aSubject, aTopic, aData) {
    this._log.trace("observe - aTopic: " + aTopic);
    if (aTopic == UPDATE_DOWNLOADED_TOPIC || aTopic == UPDATE_STAGED_TOPIC) {
      await this._handleUpdateReady(aData);
    }
  },

  shutdown() {
    if (!this._enabled) {
      return;
    }
    if (this._observerRegistered) {
      Services.obs.removeObserver(this, UPDATE_DOWNLOADED_TOPIC);
      Services.obs.removeObserver(this, UPDATE_STAGED_TOPIC);
      this._observerRegistered = false;
    }
  },
};
PK