Bug 1137447 - New app update telemetry for patch type (complete or partial), extended error codes, and general cleanup. r=bbondy
authorRobert Strong <robert.bugzilla@gmail.com>
Sat, 28 Mar 2015 20:20:53 -0700
changeset 265268 5c7b6c34ec5c70117d3e382825d3231812f63520
parent 265267 3de12fe1b92743951aeb66ab08a2b05f0b0a2487
child 265269 880c836bd395fd012ef8831ce99ce636a77d1bea
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy
bugs1137447
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1137447 - New app update telemetry for patch type (complete or partial), extended error codes, and general cleanup. r=bbondy
toolkit/components/telemetry/Histograms.json
toolkit/mozapps/update/UpdateTelemetry.jsm
toolkit/mozapps/update/common/errors.h
toolkit/mozapps/update/content/updates.js
toolkit/mozapps/update/moz.build
toolkit/mozapps/update/nsUpdateService.js
toolkit/mozapps/update/nsUpdateServiceStub.js
toolkit/mozapps/update/nsUpdateTimerManager.js
toolkit/mozapps/update/tests/chrome/chrome.ini
toolkit/mozapps/update/tests/chrome/test_0104_background_restartNotification_NoIncompatAddons.xul
toolkit/mozapps/update/tests/chrome/test_0105_background_restartNotification_VersionCompatAddons.xul
toolkit/mozapps/update/tests/chrome/utils.js
toolkit/mozapps/update/tests/data/partial_log_failure
toolkit/mozapps/update/tests/data/partial_log_failure_mac
toolkit/mozapps/update/tests/data/sharedUpdateXML.js
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
toolkit/mozapps/update/tests/unit_base_updater/marAppInUseFallbackStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseFallbackStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseFallbackStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFallbackStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFallbackStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseFallbackStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseFallbackStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js
toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js
toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js
toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js
toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppInUseFallbackStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseFallbackStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseFallbackStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFallbackStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFallbackStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseFallbackStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseFallbackStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js
toolkit/mozapps/update/updater/archivereader.cpp
toolkit/mozapps/update/updater/bspatch.cpp
toolkit/mozapps/update/updater/updater.cpp
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -3433,115 +3433,277 @@
   "PLACES_MAINTENANCE_DAYSFROMLAST": {
     "expires_in_version" : "never",
     "kind": "exponential",
     "low": 7,
     "high": 60,
     "n_buckets" : 10,
     "description": "PLACES: Days from last maintenance"
   },
-  "UPDATER_BACKGROUND_CHECK_CODE_EXTERNAL": {
-    "expires_in_version": "default",
-    "kind": "enumerated",
-    "n_values": 50,
-    "description": "Updater: externally initiated (typically by the application) background update check result code (see PING_BGUC_* constants defined in /toolkit/mozapps/update/nsUpdateService.js)"
-  },
-  "UPDATER_BACKGROUND_CHECK_CODE_NOTIFY": {
-    "expires_in_version": "40",
+  "UPDATE_CHECK_NO_UPDATE_EXTERNAL" : {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of no updates were found for a background update check (externally initiated)"
+  },
+  "UPDATE_CHECK_NO_UPDATE_NOTIFY" : {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of no updates were found for a background update check (timer initiated)"
+  },
+  "UPDATE_CHECK_CODE_EXTERNAL": {
+    "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 50,
-    "description": "Updater: timer initiated background update check result code (see PING_BGUC_* constants defined in /toolkit/mozapps/update/nsUpdateService.js)"
-  },
-  "UPDATER_INVALID_LASTUPDATETIME_EXTERNAL": {
-    "expires_in_version": "40",
-    "kind": "boolean",
-    "description": "Updater: Whether the last update time is invalid when a background update check was externally requested (typically by the application)"
-  },
-  "UPDATER_INVALID_LASTUPDATETIME_NOTIFY": {
-    "expires_in_version": "40",
-    "kind": "boolean",
-    "description": "Updater: Whether the last update time is invalid when a background update check was timer initiated"
-  },
-  "UPDATER_LAST_NOTIFY_INTERVAL_DAYS_EXTERNAL": {
-    "expires_in_version": "40",
-    "kind": "exponential",
-    "n_buckets": 10,
-    "high": "60",
-    "description": "Updater: The interval in days between the previous and the current background update check when the check was externally requested (typically by the application)"
-  },
-  "UPDATER_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY": {
-    "expires_in_version": "40",
-    "kind": "exponential",
-    "n_buckets": 10,
-    "high": "60",
-    "description": "Updater: The interval in days between the previous and the current background update check when the check was timer initiated"
-  },
-  "UPDATER_STATUS_CODES": {
+    "description": "Update: background update check result code except for no updates found (externally initiated)"
+  },
+  "UPDATE_CHECK_CODE_NOTIFY": {
     "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 50,
-    "description": "Updater: the status of the latest update performed"
-  },
-  "UPDATER_UPDATES_ENABLED": {
-    "expires_in_version": "default",
-    "kind": "boolean",
-    "description": "Updater: Whether or not updates are enabled"
-  },
-  "UPDATER_UPDATES_METRO_ENABLED": {
-    "expires_in_version": "default",
-    "kind": "boolean",
-    "description": "Updater: Whether or not Metro updates are enabled"
-  },
-  "UPDATER_UPDATES_AUTOMATIC": {
-    "expires_in_version": "40",
-    "kind": "boolean",
-    "description": "Updater: Whether or not updates are automatic"
-  },
-  "UPDATER_SERVICE_ENABLED": {
-    "expires_in_version": "default",
-    "kind": "boolean",
-    "description": "Updater: Whether or not the MozillaMaintenance service is enabled"
-  },
-  "UPDATER_SERVICE_ERROR_CODE": {
-    "expires_in_version": "default",
+    "description": "Update: background update check result code except for no updates found (timer initiated)"
+  },
+  "UPDATE_CHECK_EXTENDED_ERROR_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "keyed": true,
+    "description": "Update: keyed count (key names are prefixed with AUS_CHECK_EX_ERR_) of background update check extended error code (externally initiated)"
+  },
+  "UPDATE_CHECK_EXTENDED_ERROR_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "keyed": true,
+    "description": "Update: keyed count (key names are prefixed with AUS_CHECK_EX_ERR_) of background update check extended error code (timer initiated)"
+  },
+  "UPDATE_INVALID_LASTUPDATETIME_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that have a last update time greater than the current time (externally initiated)"
+  },
+  "UPDATE_INVALID_LASTUPDATETIME_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that have a last update time greater than the current time (timer initiated)"
+  },
+  "UPDATE_LAST_NOTIFY_INTERVAL_DAYS_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "exponential",
+    "n_buckets": 60,
+    "high": "365",
+    "description": "Update: interval in days since the last background update check (externally initiated)"
+  },
+  "UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "exponential",
+    "n_buckets": 30,
+    "high": "180",
+    "description": "Update: interval in days since the last background update check (timer initiated)"
+  },
+  "UPDATE_SERVICE_INSTALLED_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "boolean",
+    "description": "Update: whether the service is installed (externally initiated)"
+  },
+  "UPDATE_SERVICE_INSTALLED_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "boolean",
+    "description": "Update: whether the service is installed (timer initiated)"
+  },
+  "UPDATE_SERVICE_MANUALLY_UNINSTALLED_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that manually uninstalled the service (externally initiated)"
+  },
+  "UPDATE_SERVICE_MANUALLY_UNINSTALLED_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that manually uninstalled the service (timer initiated)"
+  },
+  "UPDATE_CANNOT_APPLY_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "boolean",
+    "description": "Update: systems that cannot apply updates (externally initiated)"
+  },
+  "UPDATE_CANNOT_APPLY_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "boolean",
+    "description": "Update: systems that cannot apply updates (timer initiated)"
+  },
+  "UPDATE_CANNOT_STAGE_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that cannot stage updates (externally initiated)"
+  },
+  "UPDATE_CANNOT_STAGE_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that cannot stage updates (timer initiated)"
+  },
+  "UPDATE_HAS_PREF_URL_OVERRIDE_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that have an app.update.url.override preference (externally initiated)"
+  },
+  "UPDATE_HAS_PREF_URL_OVERRIDE_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of systems that have an app.update.url.override preference (timer initiated)"
+  },
+  "UPDATE_PREF_UPDATE_CANCELATIONS_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: number of sequential update elevation request cancelations greater than 0 (externally initiated)"
+  },
+  "UPDATE_PREF_UPDATE_CANCELATIONS_NOTIFY": {
+    "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 100,
-    "description": "Updater: 0=success else SERVICE_* error code defined in /toolkit/mozapps/update/common/errors.h"
-  },
-  "UPDATER_SERVICE_ERRORS": {
-    "expires_in_version": "default",
+    "description": "Update: number of sequential update elevation request cancelations greater than 0 (timer initiated)"
+  },
+  "UPDATE_PREF_SERVICE_ERRORS_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 30,
+    "description": "Update: number of sequential update service errors greater than 0 (externally initiated)"
+  },
+  "UPDATE_PREF_SERVICE_ERRORS_NOTIFY": {
+    "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 30,
-    "description": "Updater: The number of MozillaMaintenance service errors that have occurred"
-  },
-  "UPDATER_SERVICE_INSTALLED": {
-    "expires_in_version": "default",
-    "kind": "boolean",
-    "description": "Updater: Whether or not the MozillaMaintenance service is installed"
-  },
-  "UPDATER_SERVICE_MANUALLY_UNINSTALLED": {
-    "expires_in_version": "default",
-    "kind": "boolean",
-    "description": "Updater: Whether or not someone manually uninstalled the service."
-  },
-  "UPDATER_STAGE_ENABLED": {
-    "expires_in_version": "40",
-    "kind": "boolean",
-    "description": "Updater: Whether or not staging updates are enabled"
-  },
-  "UPDATER_HAS_PERMISSIONS": {
-    "expires_in_version": "40",
-    "kind": "boolean",
-    "description": "Updater: Whether or not the updater has permissions"
-  },
-  "UPDATER_WIZ_LAST_PAGE_CODE": {
-    "expires_in_version": "40",
-    "kind": "enumerated",
-    "n_values": 25,
-    "description": "Updater: The update wizard page displayed when the UI was closed (mapped in toolkit/mozapps/update/content/updates.js)"
+    "description": "Update: number of sequential update service errors greater than 0 (timer initiated)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_AUTO_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.auto boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_AUTO_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.auto boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.enabled boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.enabled boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.staging.enabled boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.staging.enabled boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_EXTERNAL": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.service.enabled boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_NOTIFY": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Update: count of when the app.update.service.enabled boolean preference is not the default value of true (true values are not submitted)"
+  },
+  "UPDATE_DOWNLOAD_CODE_COMPLETE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 50,
+    "description": "Update: complete patch download result code"
+  },
+  "UPDATE_DOWNLOAD_CODE_PARTIAL": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 50,
+    "description": "Update: complete patch download result code"
+  },
+  "UPDATE_STATE_CODE_COMPLETE_STARTUP": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 20,
+    "description": "Update: the state of a complete update from update.status on startup"
+  },
+  "UPDATE_STATE_CODE_PARTIAL_STARTUP": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 20,
+    "description": "Update: the state of a partial patch update from update.status on startup"
+  },
+  "UPDATE_STATE_CODE_UNKNOWN_STARTUP": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 20,
+    "description": "Update: the state of an unknown patch update from update.status on startup"
+  },
+  "UPDATE_STATE_CODE_COMPLETE_STAGE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 20,
+    "description": "Update: the state of a complete patch update from update.status after staging"
+  },
+  "UPDATE_STATE_CODE_PARTIAL_STAGE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 20,
+    "description": "Update: the state of a partial patch update from update.status after staging"
+  },
+  "UPDATE_STATE_CODE_UNKNOWN_STAGE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 20,
+    "description": "Update: the state of an unknown patch update from update.status after staging"
+  },
+  "UPDATE_STATUS_ERROR_CODE_COMPLETE_STARTUP": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: the status error code for a failed complete patch update from update.status on startup"
+  },
+  "UPDATE_STATUS_ERROR_CODE_PARTIAL_STARTUP": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: the status error code for a failed partial patch update from update.status on startup"
+  },
+  "UPDATE_STATUS_ERROR_CODE_UNKNOWN_STARTUP": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: the status error code for a failed unknown patch update from update.status on startup"
+  },
+  "UPDATE_STATUS_ERROR_CODE_COMPLETE_STAGE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: the status error code for a failed complete patch update from update.status after staging"
+  },
+  "UPDATE_STATUS_ERROR_CODE_PARTIAL_STAGE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: the status error code for a failed partial patch update from update.status after staging"
+  },
+  "UPDATE_STATUS_ERROR_CODE_UNKNOWN_STAGE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 100,
+    "description": "Update: the status error code for a failed unknown patch update from update.status after staging"
+  },
+  "UPDATE_WIZ_LAST_PAGE_CODE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 30,
+    "description": "Update: the update wizard page displayed when the UI was closed (mapped in toolkit/mozapps/update/UpdateTelemetry.jsm)"
   },
   "THUNDERBIRD_GLODA_SIZE_MB": {
     "expires_in_version": "40",
     "kind": "linear",
     "high": "1000",
     "n_buckets": 40,
     "description": "Gloda: size of global-messages-db.sqlite (MB)"
   },
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/UpdateTelemetry.jsm
@@ -0,0 +1,520 @@
+/* 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";
+
+this.EXPORTED_SYMBOLS = [
+  "AUSTLMY"
+];
+
+const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm", this);
+
+this.AUSTLMY = {
+  // Telemetry for the application update background update check occurs when
+  // the background update timer fires after the update interval which is
+  // determined by the app.update.interval preference and its telemetry
+  // histogram IDs have the suffix '_NOTIFY'.
+  // Telemetry for the externally initiated background update check occurs when
+  // a call is made to |checkForBackgroundUpdates| which is typically initiated
+  // by an application when it has determined that the application should have
+  // received an update. This has separate telemetry so it is possible to
+  // analyze using the telemetry data systems that have not been updating when
+  // they should have.
+
+  // The update check was performed by the call to checkForBackgroundUpdates in
+  // nsUpdateService.js.
+  EXTERNAL: "EXTERNAL",
+  // The update check was performed by the call to notify in nsUpdateService.js.
+  NOTIFY: "NOTIFY",
+
+  /**
+   * Values for the UPDATE_CHECK_CODE_NOTIFY and UPDATE_CHECK_CODE_EXTERNAL
+   * Telemetry histograms.
+   */
+  // No update found (no notification)
+  CHK_NO_UPDATE_FOUND: 0,
+  // No incompatible add-ons found during incompatible check (background download)
+  CHK_ADDON_NO_INCOMPAT: 1,
+  // Showing prompt due to the update.xml specifying showPrompt
+  // (update notification)
+  CHK_SHOWPROMPT_SNIPPET: 2,
+  // Showing prompt due to preference (update notification)
+  CHK_SHOWPROMPT_PREF: 3,
+  // Incompatible add-on check disabled by preference (background download)
+  CHK_ADDON_PREF_DISABLED: 4,
+  // Incompatible add-on checke not performed due to same app version as the
+  // update's app version (background download)
+  CHK_ADDON_SAME_APP_VER: 5,
+  // Incompatible add-ons found and all of them have updates (background download)
+  CHK_ADDON_UPDATES_FOR_INCOMPAT: 6,
+  // Incompatible add-ons found (update notification)
+  CHK_ADDON_HAVE_INCOMPAT: 7,
+  // Already has an active update in progress (no notification)
+  CHK_HAS_ACTIVEUPDATE: 8,
+  // A background download is already in progress (no notification)
+  CHK_IS_DOWNLOADING: 9,
+  // An update is already staged (no notification)
+  CHK_IS_STAGED: 10,
+  // An update is already downloaded (no notification)
+  CHK_IS_DOWNLOADED: 11,
+  // Background checks disabled by preference (no notification)
+  CHK_PREF_DISABLED: 12,
+  // Update checks disabled by admin locked preference (no notification)
+  CHK_ADMIN_DISABLED: 13,
+  // Unable to check for updates per hasUpdateMutex() (no notification)
+  CHK_NO_MUTEX: 14,
+  // Unable to check for updates per gCanCheckForUpdates (no notification). This
+  // should be covered by other codes and is recorded just in case.
+  CHK_UNABLE_TO_CHECK: 15,
+  // Background checks disabled for the current session (no notification)
+  CHK_DISABLED_FOR_SESSION: 16,
+  // Unable to perform a background check while offline (no notification)
+  CHK_OFFLINE: 17,
+  // No update found certificate check failed and threshold reached
+  // (possible mitm attack notification)
+  CHK_CERT_ATTR_NO_UPDATE_PROMPT: 18,
+  // No update found certificate check failed and threshold not reached
+  // (no notification)
+  CHK_CERT_ATTR_NO_UPDATE_SILENT: 19,
+  // Update found certificate check failed and threshold reached
+  // (possible mitm attack notification)
+  CHK_CERT_ATTR_WITH_UPDATE_PROMPT: 20,
+  // Update found certificate check failed and threshold not reached
+  // (no notification)
+  CHK_CERT_ATTR_WITH_UPDATE_SILENT: 21,
+  // General update check failure and threshold reached
+  // (check failure notification)
+  CHK_GENERAL_ERROR_PROMPT: 22,
+  // General update check failure and threshold not reached (no notification)
+  CHK_GENERAL_ERROR_SILENT: 23,
+  // No compatible update found though there were updates (no notification)
+  CHK_NO_COMPAT_UPDATE_FOUND: 24,
+  // Update found for a previous version (no notification)
+  CHK_UPDATE_PREVIOUS_VERSION: 25,
+  // Update found for a version with the never preference set (no notification)
+  CHK_UPDATE_NEVER_PREF: 26,
+  // Update found without a type attribute (no notification)
+  CHK_UPDATE_INVALID_TYPE: 27,
+  // The system is no longer supported (system unsupported notification)
+  CHK_UNSUPPORTED: 28,
+  // Unable to apply updates (manual install to update notification)
+  CHK_UNABLE_TO_APPLY: 29,
+  // Unable to check for updates due to no OS version (no notification)
+  CHK_NO_OS_VERSION: 30,
+  // Unable to check for updates due to no OS ABI (no notification)
+  CHK_NO_OS_ABI: 31,
+  // Invalid url for app.update.url default preference (no notification)
+  CHK_INVALID_DEFAULT_URL: 32,
+  // Invalid url for app.update.url user preference (no notification)
+  CHK_INVALID_USER_OVERRIDE_URL: 33,
+  // Invalid url for app.update.url.override user preference (no notification)
+  CHK_INVALID_DEFAULT_OVERRIDE_URL: 34,
+
+  /**
+   * Submit a telemetry ping for the update check result code or a telemetry
+   * ping for a count type histogram count when no update was found. The no
+   * update found ping is separate since it is the typical result, is less
+   * interesting than the other result codes, and it is easier to analyze the
+   * other codes without including it.
+   *
+   * @param  aSuffix
+   *         The histogram id suffix for histogram IDs:
+   *         UPDATE_CHECK_CODE_EXTERNAL
+   *         UPDATE_CHECK_CODE_NOTIFY
+   *         UPDATE_CHECK_NO_UPDATE_EXTERNAL
+   *         UPDATE_CHECK_NO_UPDATE_NOTIFY
+   * @param  aCode
+   *         An integer value as defined by the values that start with CHK_ in
+   *         the above section.
+   */
+  pingCheckCode: function UT_pingCheckCode(aSuffix, aCode) {
+    try {
+      if (aCode == this.CHK_NO_UPDATE_FOUND) {
+        let id = "UPDATE_CHECK_NO_UPDATE_" + aSuffix;
+        // count type histogram
+        Services.telemetry.getHistogramById(id).add();
+      } else {
+        let id = "UPDATE_CHECK_CODE_" + aSuffix;
+        // enumerated type histogram
+        Services.telemetry.getHistogramById(id).add(aCode);
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for a failed update check's unhandled error code
+   * when the pingCheckCode is CHK_GENERAL_ERROR_SILENT. The histogram is a
+   * keyed count type with key names that are prefixed with 'AUS_CHECK_EX_ERR_'.
+   *
+   * @param  aSuffix
+   *         The histogram id suffix for histogram IDs:
+   *         UPDATE_CHK_EXTENDED_ERROR_EXTERNAL
+   *         UPDATE_CHK_EXTENDED_ERROR_NOTIFY
+   * @param  aCode
+   *         The extended error value return by a failed update check.
+   */
+  pingCheckExError: function UT_pingCheckExError(aSuffix, aCode) {
+    try {
+      let id = "UPDATE_CHECK_EXTENDED_ERROR_" + aSuffix;
+      let val = "AUS_CHECK_EX_ERR_" + aCode;
+      // keyed count type histogram
+      Services.telemetry.getKeyedHistogramById(id).add(val);
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  },
+
+  // The state code and if present the status error code were read on startup.
+  STARTUP: "STARTUP",
+  // The state code and status error code if present were read after staging.
+  STAGE: "STAGE",
+
+  // Patch type Complete
+  PATCH_COMPLETE: "COMPLETE",
+  // Patch type partial
+  PATCH_PARTIAL: "PARTIAL",
+  // Patch type unknown
+  PATCH_UNKNOWN: "UNKNOWN",
+
+  /**
+   * Values for the UPDATE_DOWNLOAD_CODE_COMPLETE and
+   * UPDATE_DOWNLOAD_CODE_PARTIAL Telemetry histograms.
+   */
+  DWNLD_SUCCESS: 0,
+  DWNLD_RETRY_OFFLINE: 1,
+  DWNLD_RETRY_NET_TIMEOUT: 2,
+  DWNLD_RETRY_CONNECTION_REFUSED: 3,
+  DWNLD_RETRY_NET_RESET: 4,
+  DWNLD_ERR_NO_UPDATE: 5,
+  DWNLD_ERR_NO_UPDATE_PATCH: 6,
+  DWNLD_ERR_NO_PATCH_FILE: 7,
+  DWNLD_ERR_PATCH_SIZE_LARGER: 8,
+  DWNLD_ERR_PATCH_SIZE_NOT_EQUAL: 9,
+  DWNLD_ERR_BINDING_ABORTED: 10,
+  DWNLD_ERR_ABORT: 11,
+  DWNLD_ERR_DOCUMENT_NOT_CACHED: 12,
+  DWNLD_ERR_VERIFY_NO_REQUEST: 13,
+  DWNLD_ERR_VERIFY_PATCH_SIZE_NOT_EQUAL: 14,
+  DWNLD_ERR_VERIFY_NO_HASH_MATCH: 15,
+
+  /**
+   * Submit a telemetry ping for the update download result code.
+   *
+   * @param  aIsComplete
+   *         If true the histogram is for a patch type complete, if false the
+   *         histogram is for a patch type partial, and when undefined the
+   *         histogram is for an unknown patch type. This is used to determine
+   *         the histogram ID out of the following histogram IDs:
+   *         UPDATE_DOWNLOAD_CODE_COMPLETE
+   *         UPDATE_DOWNLOAD_CODE_PARTIAL
+   * @param  aCode
+   *         An integer value as defined by the values that start with DWNLD_ in
+   *         the above section.
+   */
+  pingDownloadCode: function UT_pingDownloadCode(aIsComplete, aCode) {
+    let patchType = this.PATCH_UNKNOWN;
+    if (aIsComplete === true) {
+      patchType = this.PATCH_COMPLETE;
+    } else if (aIsComplete === false) {
+      patchType = this.PATCH_PARTIAL;
+    }
+    try {
+      let id = "UPDATE_DOWNLOAD_CODE_" + patchType;
+      // enumerated type histogram
+      Services.telemetry.getHistogramById(id).add(aCode);
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for the update status state code.
+   *
+   * @param  aSuffix
+   *         The histogram id suffix for histogram IDs:
+   *         UPDATE_STATE_CODE_COMPLETE_STARTUP
+   *         UPDATE_STATE_CODE_PARTIAL_STARTUP
+   *         UPDATE_STATE_CODE_UNKNOWN_STARTUP
+   *         UPDATE_STATE_CODE_COMPLETE_STAGE
+   *         UPDATE_STATE_CODE_PARTIAL_STAGE
+   *         UPDATE_STATE_CODE_UNKNOWN_STAGE
+   * @param  aCode
+   *         An integer value as defined by the values that start with STATE_ in
+   *         the above section for the update state from the update.status file.
+   */
+  pingStateCode: function UT_pingStateCode(aSuffix, aCode) {
+    try {
+      let id = "UPDATE_STATE_CODE_" + aSuffix;
+      // enumerated type histogram
+      Services.telemetry.getHistogramById(id).add(aCode);
+    } catch(e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for the update status error code. This does not
+   * submit a success value which can be determined from the state code.
+   *
+   * @param  aSuffix
+   *         The histogram id suffix for histogram IDs:
+   *         UPDATE_STATUS_ERROR_CODE_COMPLETE_STARTUP
+   *         UPDATE_STATUS_ERROR_CODE_PARTIAL_STARTUP
+   *         UPDATE_STATUS_ERROR_CODE_UNKNOWN_STARTUP
+   *         UPDATE_STATUS_ERROR_CODE_COMPLETE_STAGE
+   *         UPDATE_STATUS_ERROR_CODE_PARTIAL_STAGE
+   *         UPDATE_STATUS_ERROR_CODE_UNKNOWN_STAGE
+   * @param  aCode
+   *         An integer value for the error code from the update.status file.
+   */
+  pingStatusErrorCode: function UT_pingStatusErrorCode(aSuffix, aCode) {
+    try {
+      let id = "UPDATE_STATUS_ERROR_CODE_" + aSuffix;
+      // enumerated type histogram
+      Services.telemetry.getHistogramById(id).add(aCode);
+    } catch(e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit the interval in days since the last notification for this background
+   * update check or a boolean if the last notification is in the future.
+   *
+   * @param  aSuffix
+   *         The histogram id suffix for histogram IDs:
+   *         UPDATE_INVALID_LASTUPDATETIME_EXTERNAL
+   *         UPDATE_INVALID_LASTUPDATETIME_NOTIFY
+   *         UPDATE_LAST_NOTIFY_INTERVAL_DAYS_EXTERNAL
+   *         UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY
+   */
+  pingLastUpdateTime: function UT_pingLastUpdateTime(aSuffix) {
+    const PREF_APP_UPDATE_LASTUPDATETIME = "app.update.lastUpdateTime.background-update-timer";
+    if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_LASTUPDATETIME)) {
+      let lastUpdateTimeSeconds = Services.prefs.getIntPref(PREF_APP_UPDATE_LASTUPDATETIME);
+      if (lastUpdateTimeSeconds) {
+        let currentTimeSeconds = Math.round(Date.now() / 1000);
+        if (lastUpdateTimeSeconds > currentTimeSeconds) {
+          try {
+            let id = "UPDATE_INVALID_LASTUPDATETIME_" + aSuffix;
+            // count type histogram
+            Services.telemetry.getHistogramById().add();
+          } catch(e) {
+            Cu.reportError(e);
+          }
+        } else {
+          let intervalDays = (currentTimeSeconds - lastUpdateTimeSeconds) /
+                             (60 * 60 * 24);
+          try {
+            let id = "UPDATE_LAST_NOTIFY_INTERVAL_DAYS_" + aSuffix;
+            // exponential type histogram
+            Services.telemetry.getHistogramById(id).add(intervalDays);
+          } catch(e) {
+            Cu.reportError(e);
+          }
+        }
+      }
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for the last page displayed by the update wizard.
+   *
+   * @param  aPageID
+   *         The page id for the last page displayed.
+   */
+  pingWizLastPageCode: function UT_pingWizLastPageCode(aPageID) {
+    let pageMap = { invalid: 0,
+                    dummy: 1,
+                    checking: 2,
+                    pluginupdatesfound: 3,
+                    noupdatesfound: 4,
+                    manualUpdate: 5,
+                    unsupported: 6,
+                    incompatibleCheck: 7,
+                    updatesfoundbasic: 8,
+                    updatesfoundbillboard: 9,
+                    license: 10,
+                    incompatibleList: 11,
+                    downloading: 12,
+                    errors: 13,
+                    errorextra: 14,
+                    errorpatching: 15,
+                    finished: 16,
+                    finishedBackground: 17,
+                    installed: 18 };
+    try {
+      let id = "UPDATE_WIZ_LAST_PAGE_CODE";
+      // enumerated type histogram
+      Services.telemetry.getHistogramById(id).add(pageMap[aPageID] ||
+                                                  pageMap.invalid);
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for a boolean type histogram that indicates if the
+   * service is installed and a telemetry ping for a boolean type histogram that
+   * indicates if the service was at some point installed and is now
+   * uninstalled.
+   * Note: the total for the following histogram IDs can be used to determine
+   *       the total number of telemetry timer and externally initiated
+   *       submissions for systems that build with MOZ_MAINTENANCE_SERVICE
+   *       defined:
+   *       UPDATE_SERVICE_INSTALLED_EXTERNAL
+   *       UPDATE_SERVICE_INSTALLED_NOTIFY
+   *
+   * @param  aSuffix
+   *         The histogram id suffix for histogram IDs:
+   *         UPDATE_SERVICE_INSTALLED_EXTERNAL
+   *         UPDATE_SERVICE_INSTALLED_NOTIFY
+   *         UPDATE_SERVICE_MANUALLY_UNINSTALLED_EXTERNAL
+   *         UPDATE_SERVICE_MANUALLY_UNINSTALLED_NOTIFY
+   * @param  aInstalled
+   *         Whether the service is installed.
+   */
+  pingServiceInstallStatus: function UT_PSIS(aSuffix, aInstalled) {
+    // Report the error but don't throw since it is more important to
+    // successfully update than to throw.
+    if (!("@mozilla.org/windows-registry-key;1" in Cc)) {
+      Cu.reportError(Cr.NS_ERROR_NOT_AVAILABLE);
+      return;
+    }
+
+    try {
+      let id = "UPDATE_SERVICE_INSTALLED_" + aSuffix;
+      // boolean type histogram
+      Services.telemetry.getHistogramById(id).add(aInstalled);
+    } catch(e) {
+      Cu.reportError(e);
+    }
+
+    let attempted = 0;
+    try {
+      let wrk = Cc["@mozilla.org/windows-registry-key;1"].
+                createInstance(Ci.nsIWindowsRegKey);
+      wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
+               "SOFTWARE\\Mozilla\\MaintenanceService",
+               wrk.ACCESS_READ | wrk.WOW64_64);
+      // Was the service at some point installed, but is now uninstalled?
+      attempted = wrk.readIntValue("Attempted");
+      wrk.close();
+    } catch(e) {
+      // Since this will throw if the registry key doesn't exist (e.g. the
+      // service has never been installed) don't report an error.
+    }
+
+    try {
+      let id = "UPDATE_SERVICE_MANUALLY_UNINSTALLED_" + aSuffix;
+      if (!aInstalled && attempted) {
+        // count type histogram
+        Services.telemetry.getHistogramById(id).add();
+      }
+    } catch(e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for a count type histogram when the expected value
+   * does not equal the boolean value of a pref or if the pref isn't present
+   * when the expected value does not equal default value. This lessens the
+   * amount of data submitted to telemetry.
+   *
+   * @param  aID
+   *         The histogram ID to report to.
+   * @param  aPref
+   *         The preference to check.
+   * @param  aDefault
+   *         The default value when the preference isn't present.
+   * @param  aExpected (optional)
+   *         If specified and the value is the same as the value that will be
+   *         added the value won't be added to telemetry.
+   */
+  pingBoolPref: function UT_pingBoolPref(aID, aPref, aDefault, aExpected) {
+    try {
+      let val = aDefault;
+      if (Services.prefs.getPrefType(aPref) != Ci.nsIPrefBranch.PREF_INVALID) {
+        val = Services.prefs.getBoolPref(aPref);
+      }
+      if (val != aExpected) {
+        // count type histogram
+        Services.telemetry.getHistogramById(aID).add();
+      }
+    } catch(e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for a histogram with the integer value of a
+   * preference when it is not the expected value or the default value when it
+   * is not the expected value. This lessens the amount of data submitted to
+   * telemetry.
+   *
+   * @param  aID
+   *         The histogram ID to report to.
+   * @param  aPref
+   *         The preference to check.
+   * @param  aDefault
+   *         The default value when the pref is not set.
+   * @param  aExpected (optional)
+   *         If specified and the value is the same as the value that will be
+   *         added the value won't be added to telemetry.
+   */
+  pingIntPref: function UT_pingIntPref(aID, aPref, aDefault, aExpected) {
+    try {
+      let val = aDefault;
+      if (Services.prefs.getPrefType(aPref) != Ci.nsIPrefBranch.PREF_INVALID) {
+        val = Services.prefs.getIntPref(aPref);
+      }
+      if (aExpected === undefined || val != aExpected) {
+        // enumerated or exponential type histogram
+        Services.telemetry.getHistogramById(aID).add(val);
+      }
+    } catch(e) {
+      Cu.reportError(e);
+    }
+  },
+
+  /**
+   * Submit a telemetry ping for all histogram types that take a single
+   * parameter to the telemetry add function and the count type histogram when
+   * the aExpected parameter is specified. If the aExpected parameter is
+   * specified and it equals the value specified by the aValue
+   * parameter the telemetry submission will be skipped.
+   * Note: the total for the following histogram IDs can be used to determine
+   *       the total number of telemetry timer and externally initiated
+   *       submissions:
+   *       UPDATE_CANNOT_APPLY_EXTERNAL
+   *       UPDATE_CANNOT_APPLY_NOTIFY
+   *
+   * @param  aID
+   *         The histogram ID to report to.
+   * @param  aValue
+   *         The value to add when aExpected is not defined or the value to
+   *         check if it is equal to when aExpected is defined.
+   * @param  aExpected (optional)
+   *         If specified and the value is the same as the value specified by
+   *         aValue parameter the submission will be skipped.
+   */
+  pingGeneric: function UT_pingGeneric(aID, aValue, aExpected) {
+    try {
+      if (aExpected === undefined) {
+        Services.telemetry.getHistogramById(aID).add(aValue);
+      } else if (aValue != aExpected) {
+        // count type histogram
+        Services.telemetry.getHistogramById(aID).add();
+      }
+    } catch(e) {
+      Cu.reportError(e);
+    }
+  }
+};
+Object.freeze(AUSTLMY);
--- a/toolkit/mozapps/update/common/errors.h
+++ b/toolkit/mozapps/update/common/errors.h
@@ -4,19 +4,22 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef Errors_h__
 #define Errors_h__
 
 #define OK 0
 
-// Old unused error codes:
-// #define MEM_ERROR 1  // Replaced with errors 10-16 (inclusive)
-// #define IO_ERROR 2  // Use READ_ERROR or WRITE_ERROR instead
+// Error codes that are no longer used should not be used again unless they
+// aren't used in client code (e.g. nsUpdateService.js, updates.js,
+// UpdatePrompt.js, etc.).
+
+#define MAR_ERROR_EMPTY_ACTION_LIST 1
+#define LOADSOURCE_ERROR_WRONG_SIZE 2
 
 // Error codes 3-16 are for general update problems.
 #define USAGE_ERROR 3
 #define CRC_ERROR 4
 #define PARSE_ERROR 5
 #define READ_ERROR 6
 #define WRITE_ERROR 7
 // #define UNEXPECTED_ERROR 8 // Replaced with errors 38-42
@@ -34,47 +37,58 @@
 #define CERT_LOAD_ERROR 17
 #define CERT_HANDLING_ERROR 18
 #define CERT_VERIFY_ERROR 19
 #define ARCHIVE_NOT_OPEN 20
 #define COULD_NOT_READ_PRODUCT_INFO_BLOCK_ERROR 21
 #define MAR_CHANNEL_MISMATCH_ERROR 22
 #define VERSION_DOWNGRADE_ERROR 23
 
-// Error codes 24-34 are related to the maintenance service
-// and so are Windows only
+// Error codes 24-33 and 49 are for the Windows maintenance service.
 #define SERVICE_UPDATER_COULD_NOT_BE_STARTED 24
 #define SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS 25
 #define SERVICE_UPDATER_SIGN_ERROR 26
 #define SERVICE_UPDATER_COMPARE_ERROR 27
 #define SERVICE_UPDATER_IDENTITY_ERROR 28
 #define SERVICE_STILL_APPLYING_ON_SUCCESS 29
 #define SERVICE_STILL_APPLYING_ON_FAILURE 30
 #define SERVICE_UPDATER_NOT_FIXED_DRIVE 31
 #define SERVICE_COULD_NOT_LOCK_UPDATER 32
 #define SERVICE_INSTALLDIR_ERROR 33
-#define SERVICE_COULD_NOT_COPY_UPDATER 49
 
 #define NO_INSTALLDIR_ERROR 34
 #define WRITE_ERROR_ACCESS_DENIED 35
 // #define WRITE_ERROR_SHARING_VIOLATION 36 // Replaced with errors 46-48
 #define WRITE_ERROR_CALLBACK_APP 37
-#define INVALID_UPDATER_STATUS_CODE 38
 #define UNEXPECTED_BZIP_ERROR 39
 #define UNEXPECTED_MAR_ERROR 40
 #define UNEXPECTED_BSPATCH_ERROR 41
 #define UNEXPECTED_FILE_OPERATION_ERROR 42
 #define FILESYSTEM_MOUNT_READWRITE_ERROR 43
-#define FOTA_GENERAL_ERROR 44
-#define FOTA_UNKNOWN_ERROR 45
-#define WRITE_ERROR_SHARING_VIOLATION_SIGNALED 46
-#define WRITE_ERROR_SHARING_VIOLATION_NOPROCESSFORPID 47
-#define WRITE_ERROR_SHARING_VIOLATION_NOPID 48
+#define DELETE_ERROR_EXPECTED_DIR 46
+#define DELETE_ERROR_EXPECTED_FILE 47
+#define RENAME_ERROR_EXPECTED_FILE 48
+
+// Error codes 24-33 and 49 are for the Windows maintenance service.
+#define SERVICE_COULD_NOT_COPY_UPDATER 49
+
+#define WRITE_ERROR_FILE_COPY 61
+#define WRITE_ERROR_DELETE_FILE 62
+#define WRITE_ERROR_OPEN_PATCH_FILE 63
+#define WRITE_ERROR_PATCH_FILE 64
+#define WRITE_ERROR_APPLY_DIR_PATH 65
+#define WRITE_ERROR_CALLBACK_PATH 66
+#define WRITE_ERROR_FILE_ACCESS_DENIED 67
+#define WRITE_ERROR_DIR_ACCESS_DENIED 68
+#define WRITE_ERROR_DELETE_BACKUP 69
+#define WRITE_ERROR_EXTRACT 70
+
+// Error codes 80 through 99 are reserved for nsUpdateService.js
 
 // The following error codes are only used by updater.exe
-// when a fallback key exists and XPCShell tests are being run.
+// when a fallback key exists for tests.
 #define FALLBACKKEY_UNKNOWN_ERROR 100
 #define FALLBACKKEY_REGPATH_ERROR 101
 #define FALLBACKKEY_NOKEY_ERROR 102
 #define FALLBACKKEY_SERVICE_NO_STOP_ERROR 103
 #define FALLBACKKEY_LAUNCH_ERROR 104
 
 #endif  // Errors_h__
--- a/toolkit/mozapps/update/content/updates.js
+++ b/toolkit/mozapps/update/content/updates.js
@@ -1,41 +1,41 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 'use strict';
 
-Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
-Components.utils.import("resource://gre/modules/AddonManager.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
 // Firefox's macBrowserOverlay.xul includes scripts that define Cc, Ci, and Cr
 // so we have to use different names.
-const CoC = Components.classes;
-const CoI = Components.interfaces;
-const CoR = Components.results;
+const {classes: CoC, interfaces: CoI, results: CoR, utils: CoU} = Components;
+
+CoU.import("resource://gre/modules/DownloadUtils.jsm", this);
+CoU.import("resource://gre/modules/AddonManager.jsm", this);
+CoU.import("resource://gre/modules/Services.jsm", this);
+CoU.import("resource://gre/modules/UpdateTelemetry.jsm", this);
 
 const XMLNS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 const PREF_APP_UPDATE_BACKGROUNDERRORS    = "app.update.backgroundErrors";
 const PREF_APP_UPDATE_BILLBOARD_TEST_URL  = "app.update.billboard.test_url";
 const PREF_APP_UPDATE_CERT_ERRORS         = "app.update.cert.errors";
 const PREF_APP_UPDATE_ENABLED             = "app.update.enabled";
 const PREF_APP_UPDATE_LOG                 = "app.update.log";
-const PREF_APP_UPDATE_MANUAL_URL          = "app.update.url.manual";
-const PREF_APP_UPDATE_NEVER_BRANCH        = "app.update.never.";
 const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED = "app.update.notifiedUnsupported";
 const PREF_APP_UPDATE_TEST_LOOP           = "app.update.test.loop";
-const PREF_PLUGINS_UPDATEURL              = "plugins.update.url";
+const PREF_APP_UPDATE_URL_MANUAL          = "app.update.url.manual";
+
+const PREFBRANCH_APP_UPDATE_NEVER         = "app.update.never.";
 
 const PREF_EM_HOTFIX_ID                   = "extensions.hotfix.id";
+const PREF_PLUGINS_UPDATE_URL             = "plugins.update.url";
 
-const UPDATE_TEST_LOOP_INTERVAL     = 2000;
+const UPDATE_TEST_LOOP_INTERVAL = 2000;
 
 const URI_UPDATES_PROPERTIES  = "chrome://mozapps/locale/update/updates.properties";
 
 const STATE_DOWNLOADING       = "downloading";
 const STATE_PENDING           = "pending";
 const STATE_PENDING_SVC       = "pending-service";
 const STATE_APPLYING          = "applying";
 const STATE_APPLIED           = "applied";
@@ -140,48 +140,22 @@ var gUpdates = {
 
   /**
    * Whether to run the unload handler. This will be set to false when the user
    * exits the wizard via onWizardCancel or onWizardFinish.
    */
   _runUnload: true,
 
   /**
-   * Submit the last page code when the wizard exited. The pageid is used to map
-   * to an integer instead of using the pageindex since pages can be added and
-   * removed which would change the page's pageindex.
-   * @param   pageID
+   * Submit on close telemtry values for the update wizard.
+   * @param  pageID
+   *         The page id for the last page displayed.
    */
-  _sendLastPageCodePing: function(pageID) {
-    var pageMap = { invalid: 0,
-                    dummy: 1,
-                    checking: 2,
-                    pluginupdatesfound: 3,
-                    noupdatesfound: 4,
-                    manualUpdate: 5,
-                    unsupported: 6,
-                    incompatibleCheck: 7,
-                    updatesfoundbasic: 8,
-                    updatesfoundbillboard: 9,
-                    license: 10,
-                    incompatibleList: 11,
-                    downloading: 12,
-                    errors: 13,
-                    errorextra: 14,
-                    errorpatching: 15,
-                    finished: 16,
-                    finishedBackground: 17,
-                    installed: 18 };
-    try {
-      Services.telemetry.getHistogramById("UPDATER_WIZ_LAST_PAGE_CODE").
-        add(pageMap[pageID] || pageMap.invalid);
-    }
-    catch (e) {
-      Components.utils.reportError(e);
-    }
+  _submitTelemetry: function(aPageID) {
+    AUSTLMY.pingWizLastPageCode(aPageID);
   },
 
   /**
    * Helper function for setButtons
    * Resets button to original label & accesskey if string is null.
    */
   _setButton: function(button, string) {
     if (string) {
@@ -264,17 +238,17 @@ var gUpdates = {
       return this.strings.getFormattedString(key, strings);
     return this.strings.getString(key);
   },
 
   never: function () {
     // If the user clicks "No Thanks", we should not prompt them to update to
     // this version again unless they manually select "Check for Updates..."
     // which will clear all of the "never" prefs.
-    var neverPrefName = PREF_APP_UPDATE_NEVER_BRANCH + this.update.appVersion;
+    var neverPrefName = PREFBRANCH_APP_UPDATE_NEVER + this.update.appVersion;
     Services.prefs.setBoolPref(neverPrefName, true);
   },
 
   /**
    * A hash of |pageid| attribute to page object. Can be used to dispatch
    * function calls to the appropriate page.
    */
   _pages: { },
@@ -283,29 +257,29 @@ var gUpdates = {
    * Called when the user presses the "Finish" button on the wizard, dispatches
    * the function call to the selected page.
    */
   onWizardFinish: function() {
     this._runUnload = false;
     var pageid = document.documentElement.currentPage.pageid;
     if ("onWizardFinish" in this._pages[pageid])
       this._pages[pageid].onWizardFinish();
-    this._sendLastPageCodePing(pageid);
+    this._submitTelemetry(pageid);
   },
 
   /**
    * Called when the user presses the "Cancel" button on the wizard, dispatches
    * the function call to the selected page.
    */
   onWizardCancel: function() {
     this._runUnload = false;
     var pageid = document.documentElement.currentPage.pageid;
     if ("onWizardCancel" in this._pages[pageid])
       this._pages[pageid].onWizardCancel();
-    this._sendLastPageCodePing(pageid);
+    this._submitTelemetry(pageid);
   },
 
   /**
    * Called when the user presses the "Next" button on the wizard, dispatches
    * the function call to the selected page.
    */
   onWizardNext: function() {
     var cp = document.documentElement.currentPage;
@@ -545,17 +519,17 @@ var gUpdates = {
       addons.forEach(function(addon) {
         // Protect against code that overrides the add-ons manager and doesn't
         // implement the isCompatibleWith or the findUpdates method.
         if (!("isCompatibleWith" in addon) || !("findUpdates" in addon)) {
           let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
                        "or the findUpdates method!";
           if (addon.id)
             errMsg += " Add-on ID: " + addon.id;
-          Components.utils.reportError(errMsg);
+          CoU.reportError(errMsg);
           return;
         }
 
         // If an add-on isn't appDisabled and isn't userDisabled then it is
         // either active now or the user expects it to be active after the
         // restart. If that is the case and the add-on is not installed by the
         // application and is not compatible with the new application version
         // then the user should be warned that the add-on will become
@@ -569,17 +543,17 @@ var gUpdates = {
               !addon.appDisabled && !addon.userDisabled &&
               addon.scope != AddonManager.SCOPE_APPLICATION &&
               addon.isCompatible &&
               !addon.isCompatibleWith(self.update.appVersion,
                                       self.update.platformVersion))
             self.addons.push(addon);
         }
         catch (e) {
-          Components.utils.reportError(e);
+          CoU.reportError(e);
         }
       });
 
       aCallback(self.addons.length != 0);
     });
   },
 
   /**
@@ -622,17 +596,17 @@ var gCheckingPage = {
   onPageShow: function() {
     gUpdates.setButtons(null, null, null, false, true);
     gUpdates.wiz.getButton("cancel").focus();
 
     // Clear all of the "never" prefs to handle the scenario where the user
     // clicked "never" for an update, selected "Check for Updates...", and
     // then canceled.  If we don't clear the "never" prefs future
     // notifications will never happen.
-    Services.prefs.deleteBranch(PREF_APP_UPDATE_NEVER_BRANCH);
+    Services.prefs.deleteBranch(PREFBRANCH_APP_UPDATE_NEVER);
 
     // The user will be notified if there is an error so clear the background
     // check error count.
     if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_BACKGROUNDERRORS))
       Services.prefs.clearUserPref(PREF_APP_UPDATE_BACKGROUNDERRORS);
 
     // The preference will be set back to true if the system is still
     // unsupported.
@@ -733,28 +707,28 @@ var gCheckingPage = {
 /**
  * The "You have outdated plugins" page
  */
 var gPluginsPage = {
   /**
    * URL of the plugin updates page
    */
   _url: null,
-  
+
   /**
    * Initialize
    */
   onPageShow: function() {
     var prefs = Services.prefs;
-    if (prefs.getPrefType(PREF_PLUGINS_UPDATEURL) == prefs.PREF_INVALID) {
+    if (prefs.getPrefType(PREF_PLUGINS_UPDATE_URL) == prefs.PREF_INVALID) {
       gUpdates.wiz.goTo("noupdatesfound");
       return;
     }
-    
-    this._url = Services.urlFormatter.formatURLPref(PREF_PLUGINS_UPDATEURL);
+
+    this._url = Services.urlFormatter.formatURLPref(PREF_PLUGINS_UPDATE_URL);
     var link = document.getElementById("pluginupdateslink");
     link.setAttribute("href", this._url);
 
 
     var phs = CoC["@mozilla.org/plugin/host;1"].
                  getService(CoI.nsIPluginHost);
     var plugins = phs.getPluginTags();
     var blocklist = CoC["@mozilla.org/extensions/blocklist;1"].
@@ -771,17 +745,17 @@ var gPluginsPage = {
     if (!hasOutdated) {
       gUpdates.wiz.goTo("noupdatesfound");
       return;
     }
 
     gUpdates.setButtons(null, null, "okButton", true);
     gUpdates.wiz.getButton("finish").focus();
   },
-  
+
   /**
    * Finish button clicked.
    */
   onWizardFinish: function() {
     openURL(this._url);
   }
 };
 
@@ -903,17 +877,17 @@ var gIncompatibleCheckPage = {
 };
 
 /**
  * The "Unable to Update" page. Provides the user information about why they
  * were unable to update and a manual download url.
  */
 var gManualUpdatePage = {
   onPageShow: function() {
-    var manualURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_MANUAL_URL);
+    var manualURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_URL_MANUAL);
     var manualUpdateLinkLabel = document.getElementById("manualUpdateLinkLabel");
     manualUpdateLinkLabel.value = manualURL;
     manualUpdateLinkLabel.setAttribute("url", manualURL);
 
     gUpdates.setButtons(null, null, "okButton", true);
     gUpdates.wiz.getButton("finish").focus();
   }
 };
@@ -1706,17 +1680,17 @@ var gErrorsPage = {
     gUpdates.setButtons(null, null, "okButton", true);
     gUpdates.wiz.getButton("finish").focus();
 
     var statusText = gUpdates.update.statusText;
     LOG("gErrorsPage" , "onPageShow - update.statusText: " + statusText);
 
     var errorReason = document.getElementById("errorReason");
     errorReason.value = statusText;
-    var manualURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_MANUAL_URL);
+    var manualURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_URL_MANUAL);
     var errorLinkLabel = document.getElementById("errorLinkLabel");
     errorLinkLabel.value = manualURL;
     errorLinkLabel.setAttribute("url", manualURL);
   }
 };
 
 /**
  * The page shown when there is a background check or a certificate attribute
@@ -1745,17 +1719,17 @@ var gErrorExtraPage = {
     }
     else {
       if (gUpdates.update.errorCode == CERT_ATTR_CHECK_FAILED_NO_UPDATE){
         document.getElementById("errorCertCheckNoUpdateLabel").hidden = false;
         secHistogram.add(CoI.nsISecurityUITelemetry.WARNING_NO_SECURE_UPDATE);
       }
       else
         document.getElementById("genericBackgroundErrorLabel").hidden = false;
-      var manualURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_MANUAL_URL);
+      var manualURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_URL_MANUAL);
       var errorLinkLabel = document.getElementById("errorExtraLinkLabel");
       errorLinkLabel.value = manualURL;
       errorLinkLabel.setAttribute("url", manualURL);
       errorLinkLabel.hidden = false;
     }
   }
 };
 
@@ -1768,17 +1742,17 @@ var gErrorPatchingPage = {
    */
   onPageShow: function() {
     gUpdates.setButtons(null, null, "okButton", true);
   },
 
   onWizardNext: function() {
     switch (gUpdates.update.selectedPatch.state) {
       case STATE_PENDING:
-      case STATE_PENDING_SVC: 
+      case STATE_PENDING_SVC:
         gUpdates.wiz.goTo("finished");
         break;
       case STATE_DOWNLOADING:
         gUpdates.wiz.goTo("downloading");
         break;
       case STATE_DOWNLOAD_FAILED:
         gUpdates.wiz.goTo("errors");
         break;
--- a/toolkit/mozapps/update/moz.build
+++ b/toolkit/mozapps/update/moz.build
@@ -41,9 +41,13 @@ if CONFIG['MOZ_UPDATER']:
         'nsUpdateService.manifest',
         'nsUpdateServiceStub.js',
     ]
 
     EXTRA_PP_COMPONENTS += [
         'nsUpdateService.js',
     ]
 
+    EXTRA_JS_MODULES += [
+        'UpdateTelemetry.jsm',
+    ]
+
 JAR_MANIFESTS += ['jar.mn']
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -2,47 +2,44 @@
 
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
 
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/FileUtils.jsm");
-Components.utils.import("resource://gre/modules/AddonManager.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
+const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+Cu.import("resource://gre/modules/FileUtils.jsm", this);
+Cu.import("resource://gre/modules/AddonManager.jsm", this);
+Cu.import("resource://gre/modules/Services.jsm", this);
+Cu.import("resource://gre/modules/ctypes.jsm", this);
+Cu.import("resource://gre/modules/UpdateTelemetry.jsm", this);
 
 const UPDATESERVICE_CID = Components.ID("{B3C290A6-3943-4B89-8BBE-C01EB7B3B311}");
 const UPDATESERVICE_CONTRACTID = "@mozilla.org/updates/update-service;1";
 
 const PREF_APP_UPDATE_ALTWINDOWTYPE       = "app.update.altwindowtype";
 const PREF_APP_UPDATE_AUTO                = "app.update.auto";
 const PREF_APP_UPDATE_BACKGROUND_INTERVAL = "app.update.download.backgroundInterval";
 const PREF_APP_UPDATE_BACKGROUNDERRORS    = "app.update.backgroundErrors";
 const PREF_APP_UPDATE_BACKGROUNDMAXERRORS = "app.update.backgroundMaxErrors";
+const PREF_APP_UPDATE_CANCELATIONS        = "app.update.cancelations";
 const PREF_APP_UPDATE_CERTS_BRANCH        = "app.update.certs.";
 const PREF_APP_UPDATE_CERT_CHECKATTRS     = "app.update.cert.checkAttributes";
 const PREF_APP_UPDATE_CERT_ERRORS         = "app.update.cert.errors";
 const PREF_APP_UPDATE_CERT_MAXERRORS      = "app.update.cert.maxErrors";
 const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
 const PREF_APP_UPDATE_CUSTOM              = "app.update.custom";
 const PREF_APP_UPDATE_ENABLED             = "app.update.enabled";
-const PREF_APP_UPDATE_METRO_ENABLED       = "app.update.metro.enabled";
 const PREF_APP_UPDATE_IDLETIME            = "app.update.idletime";
 const PREF_APP_UPDATE_INCOMPATIBLE_MODE   = "app.update.incompatible.mode";
 const PREF_APP_UPDATE_INTERVAL            = "app.update.interval";
-const PREF_APP_UPDATE_LASTUPDATETIME      = "app.update.lastUpdateTime.background-update-timer";
 const PREF_APP_UPDATE_LOG                 = "app.update.log";
 const PREF_APP_UPDATE_MODE                = "app.update.mode";
 const PREF_APP_UPDATE_NEVER_BRANCH        = "app.update.never.";
 const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED = "app.update.notifiedUnsupported";
 const PREF_APP_UPDATE_POSTUPDATE          = "app.update.postupdate";
 const PREF_APP_UPDATE_PROMPTWAITTIME      = "app.update.promptWaitTime";
 const PREF_APP_UPDATE_SHOW_INSTALLED_UI   = "app.update.showInstalledUI";
 const PREF_APP_UPDATE_SILENT              = "app.update.silent";
@@ -64,18 +61,16 @@ const PREF_APP_B2G_VERSION              
 const PREF_EM_HOTFIX_ID                   = "extensions.hotfix.id";
 
 const URI_UPDATE_PROMPT_DIALOG  = "chrome://mozapps/content/update/updates.xul";
 const URI_UPDATE_HISTORY_DIALOG = "chrome://mozapps/content/update/history.xul";
 const URI_BRAND_PROPERTIES      = "chrome://branding/locale/brand.properties";
 const URI_UPDATES_PROPERTIES    = "chrome://mozapps/locale/update/updates.properties";
 const URI_UPDATE_NS             = "http://www.mozilla.org/2005/app-update";
 
-const CATEGORY_UPDATE_TIMER               = "update-timer";
-
 const KEY_GRED            = "GreD";
 const KEY_UPDROOT         = "UpdRootD";
 const KEY_EXECUTABLE      = "XREExeF";
 
 #ifdef MOZ_WIDGET_GONK
 #define USE_UPDATE_ARCHIVE_DIR
 #endif
 
@@ -120,56 +115,88 @@ const STATE_PENDING_SVC     = "pending-s
 const STATE_APPLYING        = "applying";
 const STATE_APPLIED         = "applied";
 const STATE_APPLIED_OS      = "applied-os";
 const STATE_APPLIED_SVC     = "applied-service";
 const STATE_SUCCEEDED       = "succeeded";
 const STATE_DOWNLOAD_FAILED = "download-failed";
 const STATE_FAILED          = "failed";
 
-// From updater/errors.h:
-const WRITE_ERROR        = 7;
-// const UNEXPECTED_ERROR   = 8; // Replaced with errors 38-42
-const ELEVATION_CANCELED = 9;
-
-// Windows service specific errors
+// The values below used by this code are from common/errors.h
+const WRITE_ERROR                          = 7;
+const ELEVATION_CANCELED                   = 9;
 const SERVICE_UPDATER_COULD_NOT_BE_STARTED = 24;
 const SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS = 25;
 const SERVICE_UPDATER_SIGN_ERROR           = 26;
 const SERVICE_UPDATER_COMPARE_ERROR        = 27;
 const SERVICE_UPDATER_IDENTITY_ERROR       = 28;
 const SERVICE_STILL_APPLYING_ON_SUCCESS    = 29;
 const SERVICE_STILL_APPLYING_ON_FAILURE    = 30;
 const SERVICE_UPDATER_NOT_FIXED_DRIVE      = 31;
 const SERVICE_COULD_NOT_LOCK_UPDATER       = 32;
 const SERVICE_INSTALLDIR_ERROR             = 33;
+const WRITE_ERROR_ACCESS_DENIED            = 35;
+const WRITE_ERROR_CALLBACK_APP             = 37;
+const FILESYSTEM_MOUNT_READWRITE_ERROR     = 43;
 const SERVICE_COULD_NOT_COPY_UPDATER       = 49;
-
-const WRITE_ERROR_ACCESS_DENIED                     = 35;
-// const WRITE_ERROR_SHARING_VIOLATION                 = 36; // Replaced with errors 46-48
-const WRITE_ERROR_CALLBACK_APP                      = 37;
-const INVALID_UPDATER_STATUS_CODE                   = 38;
-const UNEXPECTED_BZIP_ERROR                         = 39;
-const UNEXPECTED_MAR_ERROR                          = 40;
-const UNEXPECTED_BSPATCH_ERROR                      = 41;
-const UNEXPECTED_FILE_OPERATION_ERROR               = 42;
-const FILESYSTEM_MOUNT_READWRITE_ERROR              = 43;
-const FOTA_GENERAL_ERROR                            = 44;
-const FOTA_UNKNOWN_ERROR                            = 45;
-const WRITE_ERROR_SHARING_VIOLATION_SIGNALED        = 46;
-const WRITE_ERROR_SHARING_VIOLATION_NOPROCESSFORPID = 47;
-const WRITE_ERROR_SHARING_VIOLATION_NOPID           = 48;
-const FOTA_FILE_OPERATION_ERROR                     = 49;
-const FOTA_RECOVERY_ERROR                           = 50;
-
+const WRITE_ERROR_FILE_COPY                = 61;
+const WRITE_ERROR_DELETE_FILE              = 62;
+const WRITE_ERROR_OPEN_PATCH_FILE          = 63;
+const WRITE_ERROR_PATCH_FILE               = 64;
+const WRITE_ERROR_APPLY_DIR_PATH           = 65;
+const WRITE_ERROR_CALLBACK_PATH            = 66;
+const WRITE_ERROR_FILE_ACCESS_DENIED       = 67;
+const WRITE_ERROR_DIR_ACCESS_DENIED        = 68;
+const WRITE_ERROR_DELETE_BACKUP            = 69;
+const WRITE_ERROR_EXTRACT                  = 70;
+
+// Array of write errors to simplify checks for write errors
+const WRITE_ERRORS = [WRITE_ERROR,
+                      WRITE_ERROR_ACCESS_DENIED,
+                      WRITE_ERROR_CALLBACK_APP,
+                      WRITE_ERROR_FILE_COPY,
+                      WRITE_ERROR_DELETE_FILE,
+                      WRITE_ERROR_OPEN_PATCH_FILE,
+                      WRITE_ERROR_PATCH_FILE,
+                      WRITE_ERROR_APPLY_DIR_PATH,
+                      WRITE_ERROR_CALLBACK_PATH,
+                      WRITE_ERROR_FILE_ACCESS_DENIED,
+                      WRITE_ERROR_DIR_ACCESS_DENIED,
+                      WRITE_ERROR_DELETE_BACKUP,
+                      WRITE_ERROR_EXTRACT];
+
+// Array of write errors to simplify checks for service errors
+const SERVICE_ERRORS = [SERVICE_UPDATER_COULD_NOT_BE_STARTED,
+                        SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS,
+                        SERVICE_UPDATER_SIGN_ERROR,
+                        SERVICE_UPDATER_COMPARE_ERROR,
+                        SERVICE_UPDATER_IDENTITY_ERROR,
+                        SERVICE_STILL_APPLYING_ON_SUCCESS,
+                        SERVICE_STILL_APPLYING_ON_FAILURE,
+                        SERVICE_UPDATER_NOT_FIXED_DRIVE,
+                        SERVICE_COULD_NOT_LOCK_UPDATER,
+                        SERVICE_INSTALLDIR_ERROR,
+                        SERVICE_COULD_NOT_COPY_UPDATER];
+
+// Error codes 80 through 99 are reserved for nsUpdateService.js and are not
+// defined in common/errors.h
+const FOTA_GENERAL_ERROR                   = 80;
+const FOTA_UNKNOWN_ERROR                   = 81;
+const FOTA_FILE_OPERATION_ERROR            = 82;
+const FOTA_RECOVERY_ERROR                  = 83;
+// Staging failed and changed the state to pending
+const STAGE_FAIL_FALLBACK                  = 97;
+const INVALID_UPDATER_STATE_CODE           = 98;
+const INVALID_UPDATER_STATUS_CODE          = 99;
+
+// Custom update error codes
 const CERT_ATTR_CHECK_FAILED_NO_UPDATE  = 100;
 const CERT_ATTR_CHECK_FAILED_HAS_UPDATE = 101;
 const BACKGROUNDCHECK_MULTIPLE_FAILURES = 110;
 const NETWORK_ERROR_OFFLINE             = 111;
-const FILE_ERROR_TOO_BIG                = 112;
 
 // Error codes should be < 1000. Errors above 1000 represent http status codes
 const HTTP_ERROR_OFFSET                 = 1000;
 
 const DOWNLOAD_CHUNK_SIZE           = 300000; // bytes
 const DOWNLOAD_BACKGROUND_INTERVAL  = 600;    // seconds
 const DOWNLOAD_FOREGROUND_INTERVAL  = 0;
 
@@ -181,88 +208,16 @@ const DEFAULT_SERVICE_MAX_ERRORS = 10;
 
 // The number of consecutive socket errors to allow before falling back to
 // downloading a different MAR file or failing if already downloading the full.
 const DEFAULT_SOCKET_MAX_ERRORS = 10;
 
 // The number of milliseconds to wait before retrying a connection error.
 const DEFAULT_UPDATE_RETRY_TIMEOUT = 2000;
 
-// A background download is in progress (no notification)
-const PING_BGUC_IS_DOWNLOADING               = 0;
-// An update is staged (no notification)
-const PING_BGUC_IS_STAGED                    = 1;
-// Invalid url for app.update.url default preference (no notification)
-const PING_BGUC_INVALID_DEFAULT_URL          = 2;
-// Invalid url for app.update.url user preference (no notification)
-const PING_BGUC_INVALID_CUSTOM_URL           = 3;
-// Invalid url for app.update.url.override user preference (no notification)
-const PING_BGUC_INVALID_OVERRIDE_URL         = 4;
-// Unable to check for updates per gCanCheckForUpdates and hasUpdateMutex()
-// (no notification)
-const PING_BGUC_UNABLE_TO_CHECK              = 5;
-// Already has an active update in progress (no notification)
-const PING_BGUC_HAS_ACTIVEUPDATE             = 6;
-// Background checks disabled by preference (no notification)
-const PING_BGUC_PREF_DISABLED                = 7;
-// Background checks disabled for the current session (no notification)
-const PING_BGUC_DISABLED_FOR_SESSION         = 8;
-// Background checks disabled in Metro (no notification)
-const PING_BGUC_METRO_DISABLED               = 9;
-// Unable to perform a background check while offline (no notification)
-const PING_BGUC_OFFLINE                      = 10;
-// No update found certificate check failed and threshold reached
-// (possible mitm attack notification)
-const PING_BGUC_CERT_ATTR_NO_UPDATE_NOTIFY   = 11;
-// No update found certificate check failed and threshold not reached
-// (no notification)
-const PING_BGUC_CERT_ATTR_NO_UPDATE_SILENT   = 12;
-// Update found certificate check failed and threshold reached
-// (possible mitm attack notification)
-const PING_BGUC_CERT_ATTR_WITH_UPDATE_NOTIFY = 13;
-// Update found certificate check failed and threshold not reached
-// (no notification)
-const PING_BGUC_CERT_ATTR_WITH_UPDATE_SILENT = 14;
-// General update check failure and threshold reached
-// (check failure notification)
-const PING_BGUC_GENERAL_ERROR_NOTIFY         = 15;
-// General update check failure and threshold not reached
-// (no notification)
-const PING_BGUC_GENERAL_ERROR_SILENT         = 16;
-// No update found (no notification)
-const PING_BGUC_NO_UPDATE_FOUND              = 17;
-// No compatible update found though there were updates (no notification)
-const PING_BGUC_NO_COMPAT_UPDATE_FOUND       = 18;
-// Update found for a previous version (no notification)
-const PING_BGUC_UPDATE_PREVIOUS_VERSION      = 19;
-// Update found for a version with the never preference set (no notification)
-const PING_BGUC_UPDATE_NEVER_PREF            = 20;
-// Update found without a type attribute (no notification)
-const PING_BGUC_UPDATE_INVALID_TYPE          = 21;
-// The system is no longer supported (system unsupported notification)
-const PING_BGUC_UNSUPPORTED                  = 22;
-// Unable to apply updates (manual install to update notification)
-const PING_BGUC_UNABLE_TO_APPLY              = 23;
-// Showing prompt due to the update.xml specifying showPrompt
-// (update notification)
-const PING_BGUC_SHOWPROMPT_SNIPPET           = 24;
-// Showing prompt due to preference (update notification)
-const PING_BGUC_SHOWPROMPT_PREF              = 25;
-// Incompatible add-on check disabled by preference (background download)
-const PING_BGUC_ADDON_PREF_DISABLED          = 26;
-// Incompatible add-on not checked not performed due to same update version and
-// app version (background download)
-const PING_BGUC_ADDON_SAME_APP_VER           = 27;
-// No incompatible add-ons found during incompatible check (background download)
-const PING_BGUC_CHECK_NO_INCOMPAT            = 28;
-// Incompatible add-ons found and all of them have updates (background download)
-const PING_BGUC_ADDON_UPDATES_FOR_INCOMPAT   = 29;
-// Incompatible add-ons found (update notification)
-const PING_BGUC_ADDON_HAVE_INCOMPAT          = 30;
-
 var gLocale = null;
 var gUpdateMutexHandle = null;
 
 #ifdef MOZ_WIDGET_GONK
 var gSDCardMountLock = null;
 
 XPCOMUtils.defineLazyGetter(this, "gExtStorage", function aus_gExtStorage() {
     return Services.env.get("EXTERNAL_STORAGE");
@@ -550,45 +505,33 @@ function getPerInstallationMutexName(aGl
   return (aGlobal ? "Global\\" : "") + "MozillaUpdateMutex-" + hasher.finish(true);
 }
 #endif // XP_WIN
 
 /**
  * Whether or not the current instance has the update mutex. The update mutex
  * gives protection against 2 applications from the same installation updating:
  * 1) Running multiple profiles from the same installation path
- * 2) Running a Metro and Desktop application at the same time from the same
- *    path
- * 3) 2 applications running in 2 different user sessions from the same path
+ * 2) Two applications running in 2 different user sessions from the same path
  *
  * @return true if this instance holds the update mutex
  */
 function hasUpdateMutex() {
 #ifdef XP_WIN
   if (!gUpdateMutexHandle) {
     gUpdateMutexHandle = createMutex(getPerInstallationMutexName(true), false);
   }
 
   return !!gUpdateMutexHandle;
 #else
   return true;
 #endif // XP_WIN
 }
 
 XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpdates() {
-  function submitHasPermissionsTelemetryPing(val) {
-    try {
-      let h = Services.telemetry.getHistogramById("UPDATER_HAS_PERMISSIONS");
-      h.add(+val);
-    } catch(e) {
-      // Don't allow any exception to be propagated.
-      Components.utils.reportError(e);
-    }
-  }
-
   let useService = false;
   if (shouldUseService() && isServiceInstalled()) {
     // No need to perform directory write checks, the maintenance service will
     // be able to write to all directories.
     LOG("gCanApplyUpdates - bypass the write checks because we'll use the service");
     useService = true;
   }
 
@@ -611,25 +554,25 @@ XPCOMUtils.defineLazyGetter(this, "gCanA
       var sysInfo = Cc["@mozilla.org/system-info;1"].
                     getService(Ci.nsIPropertyBag2);
 
       // Example windowsVersion:  Windows XP == 5.1
       var windowsVersion = sysInfo.getProperty("version");
       LOG("gCanApplyUpdates - windowsVersion = " + windowsVersion);
 
     /**
-  #    For Vista, updates can be performed to a location requiring admin
-  #    privileges by requesting elevation via the UAC prompt when launching
-  #    updater.exe if the appDir is under the Program Files directory
-  #    (e.g. C:\Program Files\) and UAC is turned on and  we can elevate
-  #    (e.g. user has a split token).
-  #
-  #    Note: this does note attempt to handle the case where UAC is turned on
-  #    and the installation directory is in a restricted location that
-  #    requires admin privileges to update other than Program Files.
+     * For Vista, updates can be performed to a location requiring admin
+     * privileges by requesting elevation via the UAC prompt when launching
+     * updater.exe if the appDir is under the Program Files directory
+     * (e.g. C:\Program Files\) and UAC is turned on and  we can elevate
+     * (e.g. user has a split token).
+     *
+     * Note: this does note attempt to handle the case where UAC is turned on
+     * and the installation directory is in a restricted location that
+     * requires admin privileges to update other than Program Files.
      */
       var userCanElevate = false;
 
       if (parseFloat(windowsVersion) >= 6) {
         try {
           var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
                             getService(Ci.nsIProperties);
           // KEY_UPDROOT will fail and throw an exception if
@@ -644,57 +587,55 @@ XPCOMUtils.defineLazyGetter(this, "gCanA
           // When the installation directory is not under Program Files,
           // fall through to checking if write access to the
           // installation directory is available.
           LOG("gCanApplyUpdates - on Vista, appDir is not under Program Files");
         }
       }
 
       /**
-#      On Windows, we no longer store the update under the app dir.
-#
-#      If we are on Windows (including Vista, if we can't elevate) we need to
-#      to check that we can create and remove files from the actual app
-#      directory (like C:\Program Files\Mozilla Firefox).  If we can't
-#      (because this user is not an adminstrator, for example) canUpdate()
-#      should return false.
-#
-#      For Vista, we perform this check to enable updating the  application
-#      when the user has write access to the installation directory under the
-#      following scenarios:
-#      1) the installation directory is not under Program Files
-#         (e.g. C:\Program Files)
-#      2) UAC is turned off
-#      3) UAC is turned on and the user is not an admin
-#         (e.g. the user does not have a split token)
-#      4) UAC is turned on and the user is already elevated, so they can't be
-#         elevated again
+       * On Windows, we no longer store the update under the app dir.
+       *
+       * If we are on Windows (including Vista, if we can't elevate) we need to
+       * to check that we can create and remove files from the actual app
+       * directory (like C:\Program Files\Mozilla Firefox).  If we can't
+       * (because this user is not an adminstrator, for example) canUpdate()
+       * should return false.
+       *
+       * For Vista, we perform this check to enable updating the  application
+       * when the user has write access to the installation directory under the
+       * following scenarios:
+       * 1) the installation directory is not under Program Files
+       *    (e.g. C:\Program Files)
+       * 2) UAC is turned off
+       * 3) UAC is turned on and the user is not an admin
+       *    (e.g. the user does not have a split token)
+       * 4) UAC is turned on and the user is already elevated, so they can't be
+       *    elevated again
        */
       if (!userCanElevate) {
         // if we're unable to create the test file this will throw an exception.
         var appDirTestFile = getAppBaseDir();
         appDirTestFile.append(FILE_PERMS_TEST);
         LOG("gCanApplyUpdates - testing write access " + appDirTestFile.path);
         if (appDirTestFile.exists())
           appDirTestFile.remove(false)
         appDirTestFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
         appDirTestFile.remove(false);
       }
 #endif //XP_WIN
     }
     catch (e) {
        LOG("gCanApplyUpdates - unable to apply updates. Exception: " + e);
       // No write privileges to install directory
-      submitHasPermissionsTelemetryPing(false);
       return false;
     }
   } // if (!useService)
 
   LOG("gCanApplyUpdates - able to apply updates");
-  submitHasPermissionsTelemetryPing(true);
   return true;
 });
 
 /**
  * Whether or not the application can stage an update.
  *
  * @return true if updates can be staged.
  */
@@ -757,48 +698,27 @@ function getCanStageUpdates() {
 
     LOG("canStageUpdatesSession - able to stage updates");
     return true;
   });
 
   return canStageUpdatesSession;
 }
 
-XPCOMUtils.defineLazyGetter(this, "gMetroUpdatesEnabled", function aus_gMetroUpdatesEnabled() {
-#ifdef XP_WIN
-#ifdef MOZ_METRO
-  if (Services.metro && Services.metro.immersive) {
-    let metroUpdate = getPref("getBoolPref", PREF_APP_UPDATE_METRO_ENABLED, true);
-    if (!metroUpdate) {
-      LOG("gMetroUpdatesEnabled - unable to automatically check for metro " +
-          "updates, disabled by pref");
-      return false;
-    }
-  }
-#endif
-#endif
-
-  return true;
-});
-
 XPCOMUtils.defineLazyGetter(this, "gCanCheckForUpdates", function aus_gCanCheckForUpdates() {
   // If the administrator has disabled app update and locked the preference so
   // users can't check for updates. This preference check is ok in this lazy
   // getter since locked prefs don't change until the application is restarted.
   var enabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
   if (!enabled && Services.prefs.prefIsLocked(PREF_APP_UPDATE_ENABLED)) {
     LOG("gCanCheckForUpdates - unable to automatically check for updates, " +
         "the preference is disabled and admistratively locked.");
     return false;
   }
 
-  if (!gMetroUpdatesEnabled) {
-    return false;
-  }
-
   // If we don't know the binary platform we're updating, we can't update.
   if (!gABI) {
     LOG("gCanCheckForUpdates - unable to check for updates, unknown ABI");
     return false;
   }
 
   // If we don't know the OS version we're updating, we can't update.
   if (!gOSVersion) {
@@ -1435,47 +1355,39 @@ function handleUpdateFailure(update, err
     Cc["@mozilla.org/updates/update-prompt;1"].
       createInstance(Ci.nsIUpdatePrompt).
       showUpdateError(update);
     writeStatusFile(getUpdatesDir(), STATE_FAILED + ": " + errorCode);
     cleanupActiveUpdate();
     return true;
   }
 
-  if (update.errorCode == WRITE_ERROR ||
-      update.errorCode == WRITE_ERROR_ACCESS_DENIED ||
-      update.errorCode == WRITE_ERROR_SHARING_VIOLATION_SIGNALED ||
-      update.errorCode == WRITE_ERROR_SHARING_VIOLATION_NOPROCESSFORPID ||
-      update.errorCode == WRITE_ERROR_SHARING_VIOLATION_NOPID ||
-      update.errorCode == WRITE_ERROR_CALLBACK_APP ||
+  // Replace with Array.prototype.includes when it has stabilized.
+  if (WRITE_ERRORS.indexOf(update.errorCode) != -1 ||
       update.errorCode == FILESYSTEM_MOUNT_READWRITE_ERROR) {
     Cc["@mozilla.org/updates/update-prompt;1"].
       createInstance(Ci.nsIUpdatePrompt).
       showUpdateError(update);
     writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
     return true;
   }
 
   if (update.errorCode == ELEVATION_CANCELED) {
     writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
+    let cancelations = getPref("getIntPref", PREF_APP_UPDATE_CANCELATIONS, 0);
+    cancelations++;
+    Services.prefs.setIntPref(PREF_APP_UPDATE_CANCELATIONS, cancelations);
     return true;
   }
-
-  if (update.errorCode == SERVICE_UPDATER_COULD_NOT_BE_STARTED ||
-      update.errorCode == SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS ||
-      update.errorCode == SERVICE_UPDATER_SIGN_ERROR ||
-      update.errorCode == SERVICE_UPDATER_COMPARE_ERROR ||
-      update.errorCode == SERVICE_UPDATER_IDENTITY_ERROR ||
-      update.errorCode == SERVICE_STILL_APPLYING_ON_SUCCESS ||
-      update.errorCode == SERVICE_STILL_APPLYING_ON_FAILURE ||
-      update.errorCode == SERVICE_UPDATER_NOT_FIXED_DRIVE ||
-      update.errorCode == SERVICE_COULD_NOT_LOCK_UPDATER ||
-      update.errorCode == SERVICE_COULD_NOT_COPY_UPDATER ||
-      update.errorCode == SERVICE_INSTALLDIR_ERROR) {
-
+  if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_SERVICE_ERRORS)) {
+    Services.prefs.clearUserPref(PREF_APP_UPDATE_SERVICE_ERRORS);
+  }
+
+  // Replace with Array.prototype.includes when it has stabilized.
+  if (SERVICE_ERRORS.indexOf(update.errorCode) != -1) {
     var failCount = getPref("getIntPref",
                             PREF_APP_UPDATE_SERVICE_ERRORS, 0);
     var maxFail = getPref("getIntPref",
                           PREF_APP_UPDATE_SERVICE_MAX_ERRORS,
                           DEFAULT_SERVICE_MAX_ERRORS);
 
     // As a safety, when the service reaches maximum failures, it will
     // disable itself and fallback to using the normal update mechanism
@@ -1485,32 +1397,18 @@ function handleUpdateFailure(update, err
       Services.prefs.clearUserPref(PREF_APP_UPDATE_SERVICE_ERRORS);
     } else {
       failCount++;
       Services.prefs.setIntPref(PREF_APP_UPDATE_SERVICE_ERRORS,
                                 failCount);
     }
 
     writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
-    try {
-      Services.telemetry.getHistogramById("UPDATER_SERVICE_ERROR_CODE").
-        add(update.errorCode);
-    }
-    catch (e) {
-      Cu.reportError(e);
-    }
     return true;
   }
-
-  try {
-    Services.telemetry.getHistogramById("UPDATER_SERVICE_ERROR_CODE").add(0);
-  }
-  catch (e) {
-    Cu.reportError(e);
-  }
   return false;
 }
 
 /**
  * Fall back to downloading a complete update in case an update has failed.
  *
  * @param update the update object that has failed to apply.
  * @param postStaging true if we have just attempted to stage an update.
@@ -1535,16 +1433,81 @@ function handleFallbackToCompleteUpdate(
   else {
     LOG("handleFallbackToCompleteUpdate - install of complete or " +
         "only one patch offered failed.");
   }
   update.QueryInterface(Ci.nsIWritablePropertyBag);
   update.setProperty("patchingFailed", oldType);
 }
 
+function pingStateAndStatusCodes(aUpdate, aStartup, aStatus) {
+  let patchType = AUSTLMY.PATCH_UNKNOWN;
+  if (aUpdate && aUpdate.selectedPatch && aUpdate.selectedPatch.type) {
+    if (aUpdate.selectedPatch.type == "complete") {
+      patchType = AUSTLMY.PATCH_COMPLETE;
+    } else if (aUpdate.selectedPatch.type == "partial") {
+      patchType = AUSTLMY.PATCH_PARTIAL;
+    }
+  }
+
+  let suffix = patchType + "_" + (aStartup ? AUSTLMY.STARTUP : AUSTLMY.STAGE);
+  let stateCode = 0;
+  let parts = aStatus.split(":");
+  if (parts.length > 0) {
+    switch (parts[0]) {
+      case STATE_NONE:
+        stateCode = 2;
+        break;
+      case STATE_DOWNLOADING:
+        stateCode = 3;
+        break;
+      case STATE_PENDING:
+        stateCode = 4;
+        parts[0] = STATE_FAILED;
+        parts.push(STAGE_FAIL_FALLBACK);
+        break;
+      case STATE_PENDING_SVC:
+        stateCode = 5;
+        break;
+      case STATE_APPLYING:
+        stateCode = 6;
+        break;
+      case STATE_APPLIED:
+        stateCode = 7;
+        break;
+      case STATE_APPLIED_OS:
+        stateCode = 8;
+        break;
+      case STATE_APPLIED_SVC:
+        stateCode = 9;
+        break;
+      case STATE_SUCCEEDED:
+        stateCode = 10;
+        break;
+      case STATE_DOWNLOAD_FAILED:
+        stateCode = 11;
+        break;
+      case STATE_FAILED:
+        stateCode = 12;
+        break;
+      default:
+        stateCode = 1;
+    }
+
+    if (parts.length > 1) {
+      let statusErrorCode = INVALID_UPDATER_STATE_CODE;
+      if (parts[0] == STATE_FAILED) {
+        statusErrorCode = parseInt(parts[1]) || INVALID_UPDATER_STATUS_CODE;
+      }
+      AUSTLMY.pingStatusErrorCode(suffix, statusErrorCode);
+    }
+  }
+  AUSTLMY.pingStateCode(suffix, stateCode);
+}
+
 /**
  * Update Patch
  * @param   patch
  *          A <patch> element to initialize this object with
  * @throws if patch has a size of 0
  * @constructor
  */
 function UpdatePatch(patch) {
@@ -2115,53 +2078,44 @@ UpdateService.prototype = {
 
   /**
    * Perform post-processing on updates lingering in the updates directory
    * from a previous application session - either report install failures (and
    * optionally attempt to fetch a different version if appropriate) or
    * notify the user of install success.
    */
   _postUpdateProcessing: function AUS__postUpdateProcessing() {
-    // canCheckForUpdates will return false when metro-only updates are disabled
-    // from within metro.  In that case we still want _postUpdateProcessing to
-    // run.  gMetroUpdatesEnabled returns true on non Windows 8 platforms.
-    // We want _postUpdateProcessing to run so that it will update the history
-    // XML. Without updating the history XML, the about flyout will continue to
-    // have the "Restart to Apply Update" button (history xml indicates update
-    // is applied).
-    // TODO: I think this whole if-block should be removed since updates can
-    // always be applied via the about dialog, we should be running post update
-    // in those cases.
-    if (!this.canCheckForUpdates && gMetroUpdatesEnabled) {
+    if (!this.canCheckForUpdates) {
       LOG("UpdateService:_postUpdateProcessing - unable to check for " +
           "updates... returning early");
       return;
     }
 
     if (!this.canApplyUpdates) {
       LOG("UpdateService:_postUpdateProcessing - unable to apply " +
           "updates... returning early");
       // If the update is present in the update directly somehow,
       // it would prevent us from notifying the user of futher updates.
       cleanupActiveUpdate();
       return;
     }
 
+    var um = Cc["@mozilla.org/updates/update-manager;1"].
+             getService(Ci.nsIUpdateManager);
+    var update = um.activeUpdate;
     var status = readStatusFile(getUpdatesDir());
-    // STATE_NONE status means that the update.status file is present but a
-    // background download error occurred.
+    pingStateAndStatusCodes(update, true, status);
+    // STATE_NONE status typically means that the update.status file is present
+    // but a background download error occurred.
     if (status == STATE_NONE) {
       LOG("UpdateService:_postUpdateProcessing - no status, no update");
       cleanupActiveUpdate();
       return;
     }
 
-    var um = Cc["@mozilla.org/updates/update-manager;1"].
-             getService(Ci.nsIUpdateManager);
-
 #ifdef MOZ_WIDGET_GONK
     // This code is called very early in the boot process, before we've even
     // had a chance to setup the UI so we can give feedback to the user.
     //
     // Since the download may be occuring over a link which has associated
     // cost, we want to require user-consent before resuming the download.
     // Also, applying an already downloaded update now is undesireable,
     // since the phone will look dead while the update is being applied.
@@ -2169,18 +2123,16 @@ UpdateService.prototype = {
     // the UI is initialized so it is possible to give feedback to and get
     // consent to update from the user.
     if (isInterruptedUpdate(status)) {
       LOG("UpdateService:_postUpdateProcessing - interrupted update detected - wait for user consent");
       return;
     }
 #endif
 
-    var update = um.activeUpdate;
-
     if (status == STATE_DOWNLOADING) {
       LOG("UpdateService:_postUpdateProcessing - patch found in downloading " +
           "state");
       if (update && update.state != STATE_SUCCEEDED) {
         // Resume download
         var status = this.downloadUpdate(update, true);
         if (status == STATE_NONE)
           cleanupActiveUpdate();
@@ -2254,17 +2206,16 @@ UpdateService.prototype = {
       }
       update = new Update(null);
     }
 
     var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
                    createInstance(Ci.nsIUpdatePrompt);
 
     update.state = status;
-    this._sendStatusCodeTelemetryPing(status);
 
     if (status == STATE_SUCCEEDED) {
       update.statusText = gUpdateBundle.GetStringFromName("installSuccess");
 
       // Update the patch's metadata.
       um.activeUpdate = update;
       Services.prefs.setBoolPref(PREF_APP_UPDATE_POSTUPDATE, true);
       prompter.showUpdateInstalled();
@@ -2296,177 +2247,16 @@ UpdateService.prototype = {
     }
 
     // Now trash the MozUpdater directory created when replacing an install with
     // a staged update.
     cleanUpMozUpdaterDirs();
   },
 
   /**
-   * Submit a telemetry ping with the boolean value of a pref for a histogram
-   *
-   * @param  pref
-   *         The preference to report
-   * @param  histogram
-   *         The histogram ID to report to
-   */
-  _sendBoolPrefTelemetryPing: function AUS__boolTelemetryPing(pref, histogram) {
-    try {
-      // The getPref is already wrapped in a try/catch but we never
-      // want telemetry pings breaking app update so we just put it
-      // inside the try to be safe.
-      let val = getPref("getBoolPref", pref, false);
-      Services.telemetry.getHistogramById(histogram).add(+val);
-    } catch(e) {
-      // Don't allow any exception to be propagated.
-      Cu.reportError(e);
-    }
-  },
-
-#ifdef XP_WIN
-  /**
-   * Submit a telemetry ping with a boolean value which indicates if the service
-   * is installed.
-   * Also submits a telemetry ping with a boolean value which indicates if the
-   * service was at some point installed, but is now uninstalled.
-   */
-  _sendServiceInstalledTelemetryPing: function AUS__svcInstallTelemetryPing() {
-    let installed = isServiceInstalled(); // Is the service installed?
-    let attempted = 0;
-    try {
-      let wrk = Cc["@mozilla.org/windows-registry-key;1"].
-                createInstance(Ci.nsIWindowsRegKey);
-      wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
-               "SOFTWARE\\Mozilla\\MaintenanceService",
-               wrk.ACCESS_READ | wrk.WOW64_64);
-      // Was the service at some point installed, but is now uninstalled?
-      attempted = wrk.readIntValue("Attempted");
-      wrk.close();
-    } catch(e) {
-    }
-    try {
-      let h = Services.telemetry.getHistogramById("UPDATER_SERVICE_INSTALLED");
-      h.add(Number(installed));
-    } catch(e) {
-      // Don't allow any exception to be propagated.
-      Cu.reportError(e);
-    }
-    try {
-      let h = Services.telemetry.getHistogramById("UPDATER_SERVICE_MANUALLY_UNINSTALLED");
-      h.add(!installed && attempted ? 1 : 0);
-    } catch(e) {
-      // Don't allow any exception to be propagated.
-      Cu.reportError(e);
-    }
-  },
-#endif
-
-  /**
-   * Submit a telemetry ping with the int value of a pref for a histogram
-   *
-   * @param  pref
-   *         The preference to report
-   * @param histogram
-   *         The histogram ID to report to
-   */
-  _sendIntPrefTelemetryPing: function AUS__intTelemetryPing(pref, histogram) {
-    try {
-      // The getPref is already wrapped in a try/catch but we never
-      // want telemetry pings breaking app update so we just put it
-      // inside the try to be safe.
-      let val = getPref("getIntPref", pref, 0);
-      Services.telemetry.getHistogramById(histogram).add(val);
-    } catch(e) {
-      // Don't allow any exception to be propagated.
-      Cu.reportError(e);
-    }
-  },
-
-
-  /**
-   * Submit the results of applying the update via telemetry.
-   *
-   * @param  status
-   *         The status of the update as read from the update.status file
-   */
-  _sendStatusCodeTelemetryPing: function AUS__statusTelemetryPing(status) {
-    try {
-      let parts = status.split(":");
-      if ((parts.length == 1 && status != STATE_SUCCEEDED) ||
-          (parts.length > 1  && parts[0] != STATE_FAILED)) {
-        // Should also report STATE_DOWNLOAD_FAILED
-        return;
-      }
-      let result = 0; // 0 means success
-      if (parts.length > 1) {
-        result = parseInt(parts[1]) || INVALID_UPDATER_STATUS_CODE;
-      }
-      Services.telemetry.getHistogramById("UPDATER_STATUS_CODES").add(result);
-    } catch(e) {
-      // Don't allow any exception to be propagated.
-      Cu.reportError(e);
-    }
-  },
-
-  /**
-   * Submit the interval in days since the last notification for this background
-   * update check.
-   */
-  _sendLastNotifyIntervalPing: function AUS__notifyIntervalPing() {
-    if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_LASTUPDATETIME)) {
-      let idSuffix = this._isNotify ? "NOTIFY" : "EXTERNAL";
-      let lastUpdateTimeSeconds = getPref("getIntPref",
-                                          PREF_APP_UPDATE_LASTUPDATETIME, 0);
-      if (lastUpdateTimeSeconds) {
-        let currentTimeSeconds = Math.round(Date.now() / 1000);
-        if (lastUpdateTimeSeconds > currentTimeSeconds) {
-          try {
-            Services.telemetry.
-              getHistogramById("UPDATER_INVALID_LASTUPDATETIME_" + idSuffix).
-              add(1);
-          } catch(e) {
-            Cu.reportError(e);
-          }
-        }
-        else {
-          let intervalDays = (currentTimeSeconds - lastUpdateTimeSeconds) /
-                             (60 * 60 * 24);
-          try {
-            Services.telemetry.
-              getHistogramById("UPDATER_INVALID_LASTUPDATETIME_" + idSuffix).
-              add(0);
-            Services.telemetry.
-              getHistogramById("UPDATER_LAST_NOTIFY_INTERVAL_DAYS_" + idSuffix).
-              add(intervalDays);
-          } catch(e) {
-            Cu.reportError(e);
-          }
-        }
-      }
-    }
-  },
-
-  /**
-   * Submit the result for the background update check.
-   *
-   * @param  code
-   *         An integer value as defined by the PING_BGUC_* constants.
-   */
-  _backgroundUpdateCheckCodePing: function AUS__backgroundUpdateCheckCodePing(code) {
-    try {
-      let idSuffix = this._isNotify ? "NOTIFY" : "EXTERNAL";
-      Services.telemetry.
-        getHistogramById("UPDATER_BACKGROUND_CHECK_CODE_" + idSuffix).add(code);
-    }
-    catch (e) {
-      Cu.reportError(e);
-    }
-  },
-
-  /**
    * Register an observer when the network comes online, so we can short-circuit
    * the app.update.interval when there isn't connectivity
    */
   _registerOnlineObserver: function AUS__registerOnlineObserver() {
     if (this._registeredOnlineObserver) {
       LOG("UpdateService:_registerOnlineObserver - observer already registered");
       return;
     }
@@ -2504,66 +2294,68 @@ UpdateService.prototype = {
     LOG("UpdateService:onError - error during background update. error code: " +
         update.errorCode + ", status text: " + update.statusText);
 
     var maxErrors;
     var errCount;
     if (update.errorCode == NETWORK_ERROR_OFFLINE) {
       // Register an online observer to try again
       this._registerOnlineObserver();
-      this._backgroundUpdateCheckCodePing(PING_BGUC_OFFLINE);
+      if (this._pingSuffix) {
+        AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_OFFLINE);
+      }
       return;
     }
 
     if (update.errorCode == CERT_ATTR_CHECK_FAILED_NO_UPDATE ||
         update.errorCode == CERT_ATTR_CHECK_FAILED_HAS_UPDATE) {
       errCount = getPref("getIntPref", PREF_APP_UPDATE_CERT_ERRORS, 0);
       errCount++;
       Services.prefs.setIntPref(PREF_APP_UPDATE_CERT_ERRORS, errCount);
       maxErrors = getPref("getIntPref", PREF_APP_UPDATE_CERT_MAXERRORS, 5);
-    }
-    else {
+    } else {
       update.errorCode = BACKGROUNDCHECK_MULTIPLE_FAILURES;
       errCount = getPref("getIntPref", PREF_APP_UPDATE_BACKGROUNDERRORS, 0);
       errCount++;
       Services.prefs.setIntPref(PREF_APP_UPDATE_BACKGROUNDERRORS, errCount);
       maxErrors = getPref("getIntPref", PREF_APP_UPDATE_BACKGROUNDMAXERRORS,
                           10);
     }
 
-    var pingCode;
+    let checkCode;
     if (errCount >= maxErrors) {
       var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
                      createInstance(Ci.nsIUpdatePrompt);
       prompter.showUpdateError(update);
 
       switch (update.errorCode) {
         case CERT_ATTR_CHECK_FAILED_NO_UPDATE:
-          pingCode = PING_BGUC_CERT_ATTR_NO_UPDATE_NOTIFY;
+          checkCode = AUSTLMY.CHK_CERT_ATTR_NO_UPDATE_PROMPT;
           break;
         case CERT_ATTR_CHECK_FAILED_HAS_UPDATE:
-          pingCode = PING_BGUC_CERT_ATTR_WITH_UPDATE_NOTIFY;
+          checkCode = AUSTLMY.CHK_CERT_ATTR_WITH_UPDATE_PROMPT;
           break;
         default:
-          pingCode = PING_BGUC_GENERAL_ERROR_NOTIFY;
+          checkCode = AUSTLMY.CHK_GENERAL_ERROR_PROMPT;
+          AUSTLMY.pingCheckExError(this._pingSuffix, update.errorCode);
+      }
+    } else {
+      switch (update.errorCode) {
+        case CERT_ATTR_CHECK_FAILED_NO_UPDATE:
+          checkCode = AUSTLMY.CHK_CERT_ATTR_NO_UPDATE_SILENT;
+          break;
+        case CERT_ATTR_CHECK_FAILED_HAS_UPDATE:
+          checkCode = AUSTLMY.CHK_CERT_ATTR_WITH_UPDATE_SILENT;
+          break;
+        default:
+          checkCode = AUSTLMY.CHK_GENERAL_ERROR_SILENT;
+          AUSTLMY.pingCheckExError(this._pingSuffix, update.errorCode);
       }
     }
-    else {
-      switch (update.errorCode) {
-        case CERT_ATTR_CHECK_FAILED_NO_UPDATE:
-          pingCode = PING_BGUC_CERT_ATTR_NO_UPDATE_SILENT;
-          break;
-        case CERT_ATTR_CHECK_FAILED_HAS_UPDATE:
-          pingCode = PING_BGUC_CERT_ATTR_WITH_UPDATE_SILENT;
-          break;
-        default:
-          pingCode = PING_BGUC_GENERAL_ERROR_SILENT;
-      }
-    }
-    this._backgroundUpdateCheckCodePing(pingCode);
+    AUSTLMY.pingCheckCode(this._pingSuffix, checkCode);
   },
 
   /**
    * Called when a connection should be resumed
    */
   _attemptResume: function AUS_attemptResume() {
     LOG("UpdateService:_attemptResume")
     // If a download is in progress, then resume it.
@@ -2587,152 +2379,207 @@ UpdateService.prototype = {
   },
 
   /**
    * Notified when a timer fires
    * @param   timer
    *          The timer that fired
    */
   notify: function AUS_notify(timer) {
-    // The telemetry below is specific to background notification.
-    this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_ENABLED,
-                                    "UPDATER_UPDATES_ENABLED");
-    this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_METRO_ENABLED,
-                                    "UPDATER_UPDATES_METRO_ENABLED");
-    this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_AUTO,
-                                    "UPDATER_UPDATES_AUTOMATIC");
-    this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGING_ENABLED,
-                                    "UPDATER_STAGE_ENABLED");
-
-#ifdef XP_WIN
-    this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ENABLED,
-                                    "UPDATER_SERVICE_ENABLED");
-    this._sendIntPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ERRORS,
-                                   "UPDATER_SERVICE_ERRORS");
-    this._sendServiceInstalledTelemetryPing();
-#endif
-
     this._checkForBackgroundUpdates(true);
   },
 
   /**
    * See nsIUpdateService.idl
    */
   checkForBackgroundUpdates: function AUS_checkForBackgroundUpdates() {
     this._checkForBackgroundUpdates(false);
   },
 
+  // The suffix used for background update check telemetry histogram ID's.
+  get _pingSuffix() {
+    return this._isNotify ? AUSTLMY.NOTIFY : AUSTLMY.EXTERNAL;
+  },
+
   /**
    * Checks for updates in the background.
    * @param   isNotify
    *          Whether or not a background update check was initiated by the
    *          application update timer notification.
    */
   _checkForBackgroundUpdates: function AUS__checkForBackgroundUpdates(isNotify) {
     this._isNotify = isNotify;
-    // From this point on, the telemetry reported differentiates between a call
-    // to notify and a call to checkForBackgroundUpdates so they are reported
-    // separately.
-    this._sendLastNotifyIntervalPing();
+
+    // Histogram IDs:
+    // UPDATE_CANNOT_APPLY_EXTERNAL
+    // UPDATE_CANNOT_APPLY_NOTIFY
+    AUSTLMY.pingGeneric("UPDATE_CANNOT_APPLY_" + this._pingSuffix,
+                        gCanApplyUpdates);
+    // Histogram IDs:
+    // UPDATE_CANNOT_STAGE_EXTERNAL
+    // UPDATE_CANNOT_STAGE_NOTIFY
+    AUSTLMY.pingGeneric("UPDATE_CANNOT_STAGE_" + this._pingSuffix,
+                        getCanStageUpdates(), true);
+    // Histogram IDs:
+    // UPDATE_INVALID_LASTUPDATETIME_EXTERNAL
+    // UPDATE_INVALID_LASTUPDATETIME_NOTIFY
+    // UPDATE_LAST_NOTIFY_INTERVAL_DAYS_EXTERNAL
+    // UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY
+    AUSTLMY.pingLastUpdateTime(this._pingSuffix);
+    // Histogram IDs:
+    // UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL
+    // UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY
+    AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_ENABLED_" + this._pingSuffix,
+                         PREF_APP_UPDATE_ENABLED, true, true);
+    // Histogram IDs:
+    // UPDATE_NOT_PREF_UPDATE_AUTO_EXTERNAL
+    // UPDATE_NOT_PREF_UPDATE_AUTO_NOTIFY
+    AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_AUTO_" + this._pingSuffix,
+                         PREF_APP_UPDATE_AUTO, true, true);
+    // Histogram IDs:
+    // UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_EXTERNAL
+    // UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_NOTIFY
+    AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_" +
+                         this._pingSuffix,
+                         PREF_APP_UPDATE_STAGING_ENABLED, true, true);
+#ifdef XP_WIN
+    // Histogram IDs:
+    // UPDATE_PREF_UPDATE_CANCELATIONS_EXTERNAL
+    // UPDATE_PREF_UPDATE_CANCELATIONS_NOTIFY
+    AUSTLMY.pingIntPref("UPDATE_PREF_UPDATE_CANCELATIONS_" + this._pingSuffix,
+                        PREF_APP_UPDATE_CANCELATIONS, 0, 0);
+#ifdef MOZ_MAINTENANCE_SERVICE
+    // Histogram IDs:
+    // UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_EXTERNAL
+    // UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_NOTIFY
+    AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_" +
+                         this._pingSuffix,
+                         PREF_APP_UPDATE_SERVICE_ENABLED, true);
+    // Histogram IDs:
+    // UPDATE_PREF_SERVICE_ERRORS_EXTERNAL
+    // UPDATE_PREF_SERVICE_ERRORS_NOTIFY
+    AUSTLMY.pingIntPref("UPDATE_PREF_SERVICE_ERRORS_" + this._pingSuffix,
+                        PREF_APP_UPDATE_SERVICE_ERRORS, 0, 0);
+    // Histogram IDs:
+    // UPDATE_SERVICE_INSTALLED_EXTERNAL
+    // UPDATE_SERVICE_INSTALLED_NOTIFY
+    // UPDATE_SERVICE_MANUALLY_UNINSTALLED_EXTERNAL
+    // UPDATE_SERVICE_MANUALLY_UNINSTALLED_NOTIFY
+    AUSTLMY.pingServiceInstallStatus(this._pingSuffix, isServiceInstalled());
+#endif // MOZ_MAINTENANCE_SERVICE
+#endif // XP_WIN
+    let prefType = Services.prefs.getPrefType(PREF_APP_UPDATE_URL_OVERRIDE);
+    let overridePrefHasValue = prefType != Ci.nsIPrefBranch.PREF_INVALID;
+    // Histogram IDs:
+    // UPDATE_HAS_PREF_URL_OVERRIDE_EXTERNAL
+    // UPDATE_HAS_PREF_URL_OVERRIDE_NOTIFY
+    AUSTLMY.pingGeneric("UPDATE_HAS_PREF_URL_OVERRIDE_" + this._pingSuffix,
+                        overridePrefHasValue, false);
 
     // If a download is in progress or the patch has been staged do nothing.
     if (this.isDownloading) {
-      this._backgroundUpdateCheckCodePing(PING_BGUC_IS_DOWNLOADING);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_IS_DOWNLOADING);
       return;
     }
 
     if (this._downloader && this._downloader.patchIsStaged) {
-      this._backgroundUpdateCheckCodePing(PING_BGUC_IS_STAGED);
+      let readState = readStatusFile(getUpdatesDir());
+      if (readState == STATE_PENDING || readState == STATE_PENDING_SVC) {
+        AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_IS_DOWNLOADED);
+      } else {
+        AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_IS_STAGED);
+      }
       return;
     }
 
-    // The following checks will return early without notification in the call
-    // to checkForUpdates below. To simplify the background update check ping
-    // their values are checked here.
+    let validUpdateURL = true;
     try {
-      if (!this.backgroundChecker.getUpdateURL(false)) {
-        let prefs = Services.prefs;
-        if (!prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
-          if (!prefs.prefHasUserValue(PREF_APP_UPDATE_URL)) {
-            this._backgroundUpdateCheckCodePing(PING_BGUC_INVALID_DEFAULT_URL);
-          }
-          else {
-            this._backgroundUpdateCheckCodePing(PING_BGUC_INVALID_CUSTOM_URL);
-          }
-        }
-        else {
-          this._backgroundUpdateCheckCodePing(PING_BGUC_INVALID_OVERRIDE_URL);
+      this.backgroundChecker.getUpdateURL(false);
+    } catch (e) {
+      validUpdateURL = false;
+    }
+    // The following checks are done here so they can be differentiated from
+    // foreground checks.
+    if (!gOSVersion) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_OS_VERSION);
+    } else if (!gABI) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_OS_ABI);
+    } else if (!validUpdateURL) {
+      if (overridePrefHasValue) {
+        if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
+          AUSTLMY.pingCheckCode(this._pingSuffix,
+                                AUSTLMY.CHK_INVALID_USER_OVERRIDE_URL);
+        } else {
+          AUSTLMY.pingCheckCode(this._pingSuffix,
+                                AUSTLMY.CHK_INVALID_DEFAULT_OVERRIDE_URL);
         }
-      }
-      else if (!gMetroUpdatesEnabled) {
-        this._backgroundUpdateCheckCodePing(PING_BGUC_METRO_DISABLED);
-      }
-      else if (!getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true)) {
-        this._backgroundUpdateCheckCodePing(PING_BGUC_PREF_DISABLED);
+      } else {
+        AUSTLMY.pingCheckCode(this._pingSuffix,
+                              AUSTLMY.CHK_INVALID_DEFAULT_URL);
       }
-      else if (!(gCanCheckForUpdates && hasUpdateMutex())) {
-        this._backgroundUpdateCheckCodePing(PING_BGUC_UNABLE_TO_CHECK);
-      }
-      else if (!this.backgroundChecker._enabled) {
-        this._backgroundUpdateCheckCodePing(PING_BGUC_DISABLED_FOR_SESSION);
-      }
-    }
-    catch (e) {
-      Cu.reportError(e);
+    } else if (!getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true)) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_PREF_DISABLED);
+    } else if (!hasUpdateMutex()) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_MUTEX);
+    } else if (!gCanCheckForUpdates) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_UNABLE_TO_CHECK);
+    } else if (!this.backgroundChecker._enabled) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_DISABLED_FOR_SESSION);
     }
 
     this.backgroundChecker.checkForUpdates(this, false);
   },
 
   /**
    * Determine the update from the specified updates that should be offered.
    * If both valid major and minor updates are available the minor update will
    * be offered.
    * @param   updates
    *          An array of available nsIUpdate items
    * @return  The nsIUpdate to offer.
    */
   selectUpdate: function AUS_selectUpdate(updates) {
     if (updates.length == 0) {
-      this._backgroundUpdateCheckCodePing(PING_BGUC_NO_UPDATE_FOUND);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_UPDATE_FOUND);
       return null;
     }
 
     // The ping for unsupported is sent after the call to showPrompt.
-    if (updates.length == 1 && updates[0].unsupported)
+    if (updates.length == 1 && updates[0].unsupported) {
       return updates[0];
+    }
 
     // Choose the newest of the available minor and major updates.
     var majorUpdate = null;
     var minorUpdate = null;
     var vc = Services.vc;
-    var lastPingCode = PING_BGUC_NO_COMPAT_UPDATE_FOUND;
+    let lastCheckCode = AUSTLMY.CHK_NO_COMPAT_UPDATE_FOUND;
 
     updates.forEach(function(aUpdate) {
       // Ignore updates for older versions of the application and updates for
       // the same version of the application with the same build ID.
       if (vc.compare(aUpdate.appVersion, Services.appinfo.version) < 0 ||
           vc.compare(aUpdate.appVersion, Services.appinfo.version) == 0 &&
           aUpdate.buildID == Services.appinfo.appBuildID) {
         LOG("UpdateService:selectUpdate - skipping update because the " +
             "update's application version is less than the current " +
             "application version");
-        lastPingCode = PING_BGUC_UPDATE_PREVIOUS_VERSION;
+        lastCheckCode = AUSTLMY.CHK_UPDATE_PREVIOUS_VERSION;
         return;
       }
 
       // Skip the update if the user responded with "never" to this update's
       // application version and the update specifies showNeverForVersion
       // (see bug 350636).
       let neverPrefName = PREF_APP_UPDATE_NEVER_BRANCH + aUpdate.appVersion;
       if (aUpdate.showNeverForVersion &&
           getPref("getBoolPref", neverPrefName, false)) {
         LOG("UpdateService:selectUpdate - skipping update because the " +
             "preference " + neverPrefName + " is true");
-        lastPingCode = PING_BGUC_UPDATE_NEVER_PREF;
+        lastCheckCode = AUSTLMY.CHK_UPDATE_NEVER_PREF;
         return;
       }
 
       switch (aUpdate.type) {
         case "major":
           if (!majorUpdate)
             majorUpdate = aUpdate;
           else if (vc.compare(majorUpdate.appVersion, aUpdate.appVersion) <= 0)
@@ -2742,24 +2589,25 @@ UpdateService.prototype = {
           if (!minorUpdate)
             minorUpdate = aUpdate;
           else if (vc.compare(minorUpdate.appVersion, aUpdate.appVersion) <= 0)
             minorUpdate = aUpdate;
           break;
         default:
           LOG("UpdateService:selectUpdate - skipping unknown update type: " +
               aUpdate.type);
-          lastPingCode = PING_BGUC_UPDATE_INVALID_TYPE;
+          lastCheckCode = AUSTLMY.CHK_UPDATE_INVALID_TYPE;
           break;
       }
     });
 
     var update = minorUpdate || majorUpdate;
-    if (!update)
-      this._backgroundUpdateCheckCodePing(lastPingCode);
+    if (!update) {
+      AUSTLMY.pingCheckCode(this._pingSuffix, lastCheckCode);
+    }
 
     return update;
   },
 
   /**
    * Reference to the currently selected update for when add-on compatibility
    * is checked.
    */
@@ -2777,55 +2625,50 @@ UpdateService.prototype = {
     var um = Cc["@mozilla.org/updates/update-manager;1"].
              getService(Ci.nsIUpdateManager);
     if (um.activeUpdate) {
 #ifdef MOZ_WIDGET_GONK
       // For gonk, the user isn't necessarily aware of the update, so we need
       // to show the prompt to make sure.
       this._showPrompt(um.activeUpdate);
 #endif
-      this._backgroundUpdateCheckCodePing(PING_BGUC_HAS_ACTIVEUPDATE);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_HAS_ACTIVEUPDATE);
       return;
     }
 
     var updateEnabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
     if (!updateEnabled) {
-      this._backgroundUpdateCheckCodePing(PING_BGUC_PREF_DISABLED);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_PREF_DISABLED);
       LOG("UpdateService:_selectAndInstallUpdate - not prompting because " +
           "update is disabled");
       return;
     }
 
-    if (!gMetroUpdatesEnabled) {
-      this._backgroundUpdateCheckCodePing(PING_BGUC_METRO_DISABLED);
-      return;
-    }
-
     var update = this.selectUpdate(updates, updates.length);
     if (!update) {
       return;
     }
 
     if (update.unsupported) {
       LOG("UpdateService:_selectAndInstallUpdate - update not supported for " +
           "this system");
       if (!getPref("getBoolPref", PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED, false)) {
         LOG("UpdateService:_selectAndInstallUpdate - notifying that the " +
             "update is not supported for this system");
         this._showPrompt(update);
       }
-      this._backgroundUpdateCheckCodePing(PING_BGUC_UNSUPPORTED);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_UNSUPPORTED);
       return;
     }
 
-    if (!(gCanApplyUpdates && hasUpdateMutex())) {
+    if (!gCanApplyUpdates) {
       LOG("UpdateService:_selectAndInstallUpdate - the user is unable to " +
           "apply updates... prompting");
       this._showPrompt(update);
-      this._backgroundUpdateCheckCodePing(PING_BGUC_UNABLE_TO_APPLY);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_UNABLE_TO_APPLY);
       return;
     }
 
     /**
 #      From this point on there are two possible outcomes:
 #      1. download and install the update automatically
 #      2. notify the user about the availability of an update
 #
@@ -2848,58 +2691,54 @@ UpdateService.prototype = {
 #      Major         all    N/A                    Notify
 #      Minor         0      N/A                    Auto Install
 #      Minor         1      Yes                    Notify
 #      Minor         1      No                     Auto Install
      */
     if (update.showPrompt) {
       LOG("UpdateService:_selectAndInstallUpdate - prompting because the " +
           "update snippet specified showPrompt");
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_SHOWPROMPT_SNIPPET);
       this._showPrompt(update);
-      if (!Services.metro || !Services.metro.immersive) {
-        this._backgroundUpdateCheckCodePing(PING_BGUC_SHOWPROMPT_SNIPPET);
-        return;
-      }
+      return;
     }
 
     if (!getPref("getBoolPref", PREF_APP_UPDATE_AUTO, true)) {
       LOG("UpdateService:_selectAndInstallUpdate - prompting because silent " +
           "install is disabled");
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_SHOWPROMPT_PREF);
       this._showPrompt(update);
-      if (!Services.metro || !Services.metro.immersive) {
-        this._backgroundUpdateCheckCodePing(PING_BGUC_SHOWPROMPT_PREF);
-        return;
-      }
     }
 
     if (getPref("getIntPref", PREF_APP_UPDATE_MODE, 1) == 0) {
       // Do not prompt regardless of add-on incompatibilities
       LOG("UpdateService:_selectAndInstallUpdate - add-on compatibility " +
           "check disabled by preference, just download the update");
       var status = this.downloadUpdate(update, true);
       if (status == STATE_NONE)
         cleanupActiveUpdate();
-      this._backgroundUpdateCheckCodePing(PING_BGUC_ADDON_PREF_DISABLED);
+      AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_ADDON_PREF_DISABLED);
       return;
     }
 
     // Only check add-on compatibility when the version changes.
     if (update.appVersion &&
         Services.vc.compare(update.appVersion, Services.appinfo.version) != 0) {
       this._update = update;
       this._checkAddonCompatibility();
     }
     else {
       LOG("UpdateService:_selectAndInstallUpdate - add-on compatibility " +
           "check not performed due to the update version being the same as " +
           "the current application version, just download the update");
-      var status = this.downloadUpdate(update, true);
-      if (status == STATE_NONE)
+      let status = this.downloadUpdate(update, true);
+      if (status == STATE_NONE) {
         cleanupActiveUpdate();
-      this._backgroundUpdateCheckCodePing(PING_BGUC_ADDON_SAME_APP_VER);
+      }
+      AUSTLMY.pingCheckCode(this._pingSuffix,AUSTLMY.CHK_ADDON_SAME_APP_VER);
     }
   },
 
   _showPrompt: function AUS__showPrompt(update) {
     var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
                    createInstance(Ci.nsIUpdatePrompt);
     prompter.showUpdateAvailable(update);
   },
@@ -2915,18 +2754,19 @@ UpdateService.prototype = {
     AddonManager.getAllAddons(function(addons) {
       self._incompatibleAddons = [];
       addons.forEach(function(addon) {
         // Protect against code that overrides the add-ons manager and doesn't
         // implement the isCompatibleWith or the findUpdates method.
         if (!("isCompatibleWith" in addon) || !("findUpdates" in addon)) {
           let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
                        "or the findUpdates method!";
-          if (addon.id)
+          if (addon.id) {
             errMsg += " Add-on ID: " + addon.id;
+          }
           Cu.reportError(errMsg);
           return;
         }
 
         // If an add-on isn't appDisabled and isn't userDisabled then it is
         // either active now or the user expects it to be active after the
         // restart. If that is the case and the add-on is not installed by the
         // application and is not compatible with the new application version
@@ -2937,20 +2777,20 @@ UpdateService.prototype = {
         // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
         // block the user from upgrading.
         try {
           if (addon.type != "plugin" && addon.id != hotfixID &&
               !addon.appDisabled && !addon.userDisabled &&
               addon.scope != AddonManager.SCOPE_APPLICATION &&
               addon.isCompatible &&
               !addon.isCompatibleWith(self._update.appVersion,
-                                      self._update.platformVersion))
+                                      self._update.platformVersion)) {
             self._incompatibleAddons.push(addon);
-        }
-        catch (e) {
+          }
+        } catch (e) {
           Cu.reportError(e);
         }
       });
 
       if (self._incompatibleAddons.length > 0) {
       /**
 #        PREF_APP_UPDATE_INCOMPATIBLE_MODE
 #        Controls the mode in which we check for updates as follows.
@@ -2982,17 +2822,17 @@ UpdateService.prototype = {
       }
       else {
         LOG("UpdateService:_checkAddonCompatibility - no incompatible " +
             "add-ons found, just download the update");
         var status = self.downloadUpdate(self._update, true);
         if (status == STATE_NONE)
           cleanupActiveUpdate();
         self._update = null;
-        self._backgroundUpdateCheckCodePing(PING_BGUC_CHECK_NO_INCOMPAT);
+        AUSTLMY.pingCheckCode(self._pingSuffix, AUSTLMY.CHK_ADDON_NO_INCOMPAT);
       }
     });
   },
 
   // AddonUpdateListener
   onCompatibilityUpdateAvailable: function(addon) {
     // Remove the add-on from the list of add-ons that will become incompatible
     // with the new version of the application.
@@ -3022,30 +2862,35 @@ UpdateService.prototype = {
     // Compatibility or new version updates mean the same thing here.
     this.onCompatibilityUpdateAvailable(addon);
   },
 
   onUpdateFinished: function(addon) {
     if (--this._updateCheckCount > 0)
       return;
 
-    if (this._incompatibleAddons.length > 0 ||
-        !(gCanApplyUpdates && hasUpdateMutex())) {
+    if (this._incompatibleAddons.length > 0 || !gCanApplyUpdates) {
       LOG("UpdateService:onUpdateEnded - prompting because there are " +
           "incompatible add-ons");
+      if (this._incompatibleAddons.length > 0) {
+        AUSTLMY.pingCheckCode(this._pingSuffix,
+                              AUSTLMY.CHK_ADDON_HAVE_INCOMPAT);
+      } else {
+        AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_UNABLE_TO_APPLY);
+      }
       this._showPrompt(this._update);
-      this._backgroundUpdateCheckCodePing(PING_BGUC_ADDON_HAVE_INCOMPAT);
     }
     else {
       LOG("UpdateService:_selectAndInstallUpdate - updates for all " +
           "incompatible add-ons found, just download the update");
       var status = this.downloadUpdate(this._update, true);
       if (status == STATE_NONE)
         cleanupActiveUpdate();
-      this._backgroundUpdateCheckCodePing(PING_BGUC_ADDON_UPDATES_FOR_INCOMPAT);
+      AUSTLMY.pingCheckCode(this._pingSuffix,
+                            AUSTLMY.CHK_ADDON_UPDATES_FOR_INCOMPAT);
     }
     this._update = null;
   },
 
   /**
    * The Checker used for background update checks.
    */
   _backgroundChecker: null,
@@ -3203,39 +3048,45 @@ UpdateService.prototype = {
     }
 
     aUpdate.QueryInterface(Ci.nsIWritablePropertyBag);
     let osApplyToDir = aUpdate.getProperty("osApplyToDir");
 
     if (!osApplyToDir) {
       LOG("UpdateService:applyOsUpdate - Error: osApplyToDir is not defined" +
           "in the nsIUpdate!");
+      pingStateAndStatusCodes(aUpdate, false,
+                              STATE_FAILED + ": " + FOTA_FILE_OPERATION_ERROR);
       handleUpdateFailure(aUpdate, FOTA_FILE_OPERATION_ERROR);
       return;
     }
 
     let updateFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
     updateFile.initWithPath(osApplyToDir + "/update.zip");
     if (!updateFile.exists()) {
       LOG("UpdateService:applyOsUpdate - Error: OS update is not found at " +
           updateFile.path);
+      pingStateAndStatusCodes(aUpdate, false,
+                              STATE_FAILED + ": " + FOTA_FILE_OPERATION_ERROR);
       handleUpdateFailure(aUpdate, FOTA_FILE_OPERATION_ERROR);
       return;
     }
 
     writeStatusFile(getUpdatesDir(), aUpdate.state = STATE_APPLIED_OS);
     LOG("UpdateService:applyOsUpdate - Rebooting into recovery to apply " +
         "FOTA update: " + updateFile.path);
     try {
       let recoveryService = Cc["@mozilla.org/recovery-service;1"]
                             .getService(Ci.nsIRecoveryService);
       recoveryService.installFotaUpdate(updateFile.path);
     } catch (e) {
       LOG("UpdateService:applyOsUpdate - Error: Couldn't reboot into recovery" +
           " to apply FOTA update " + updateFile.path);
+      pingStateAndStatusCodes(aUpdate, false,
+                              STATE_FAILED + ": " + FOTA_RECOVERY_ERROR);
       writeStatusFile(getUpdatesDir(), aUpdate.state = STATE_APPLIED);
       handleUpdateFailure(aUpdate, FOTA_RECOVERY_ERROR);
     }
   },
 
   classID: UPDATESERVICE_CID,
   classInfo: XPCOMUtils.generateCI({classID: UPDATESERVICE_CID,
                                     contractID: UPDATESERVICE_CONTRACTID,
@@ -3521,21 +3372,23 @@ UpdateManager.prototype = {
    */
   refreshUpdateStatus: function UM_refreshUpdateStatus() {
     var update = this._activeUpdate;
     if (!update) {
       return;
     }
     var updateSucceeded = true;
     var status = readStatusFile(getUpdatesDir());
-    var ary = status.split(":");
-    update.state = ary[0];
-    if (update.state == STATE_FAILED && ary[1]) {
+    pingStateAndStatusCodes(update, false, status);
+    var parts = status.split(":");
+    update.state = parts[0];
+
+    if (update.state == STATE_FAILED && parts[1]) {
       updateSucceeded = false;
-      if (!handleUpdateFailure(update, ary[1])) {
+      if (!handleUpdateFailure(update, parts[1])) {
         handleFallbackToCompleteUpdate(update, true);
       }
     }
     if (update.state == STATE_APPLIED && shouldUseService()) {
       writeStatusFile(getUpdatesDir(), update.state = STATE_APPLIED_SVC);
     }
     var um = Cc["@mozilla.org/updates/update-manager;1"].
              getService(Ci.nsIUpdateManager);
@@ -3854,20 +3707,16 @@ Checker.prototype = {
     this._request = null;
   },
 
   /**
    * Whether or not we are allowed to do update checking.
    */
   _enabled: true,
   get enabled() {
-    if (!gMetroUpdatesEnabled) {
-      return false;
-    }
-
     return getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true) &&
            gCanCheckForUpdates && hasUpdateMutex() && this._enabled;
   },
 
   /**
    * See nsIUpdateService.idl
    */
   stopChecking: function UC_stopChecking(duration) {
@@ -3957,24 +3806,28 @@ Downloader.prototype = {
 
   /**
    * Verify the downloaded file.  We assume that the download is complete at
    * this point.
    */
   _verifyDownload: function Downloader__verifyDownload() {
     LOG("Downloader:_verifyDownload called");
     if (!this._request) {
+      AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                               AUSTLMY.DWNLD_ERR_VERIFY_NO_REQUEST);
       return false;
     }
 
     let destination = this._request.destination;
 
     // Ensure that the file size matches the expected file size.
     if (destination.fileSize != this._patch.size) {
       LOG("Downloader:_verifyDownload downloaded size != expected size.");
+      AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                               AUSTLMY.DWNLD_ERR_VERIFY_PATCH_SIZE_NOT_EQUAL);
       return false;
     }
 
     LOG("Downloader:_verifyDownload downloaded size == expected size.");
     let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].
                      createInstance(Ci.nsIFileInputStream);
     fileStream.init(destination, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
 
@@ -4002,16 +3855,18 @@ Downloader.prototype = {
     fileStream.close();
 
     if (digest == this._patch.hashValue.toLowerCase()) {
       LOG("Downloader:_verifyDownload hashes match.");
       return true;
     }
 
     LOG("Downloader:_verifyDownload hashes do not match. ");
+    AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                             AUSTLMY.DWNLD_ERR_VERIFY_NO_HASH_MATCH);
     return false;
   },
 
   /**
    * Select the patch to use given the current state of updateDir and the given
    * set of update patches.
    * @param   update
    *          A nsIUpdate object to select a patch from
@@ -4145,28 +4000,31 @@ Downloader.prototype = {
 
   /**
    * Download and stage the given update.
    * @param   update
    *          A nsIUpdate object to download a patch for. Cannot be null.
    */
   downloadUpdate: function Downloader_downloadUpdate(update) {
     LOG("UpdateService:_downloadUpdate");
-    if (!update)
+    if (!update) {
+      AUSTLMY.pingDownloadCode(undefined, AUSTLMY.DWNLD_ERR_NO_UPDATE);
       throw Cr.NS_ERROR_NULL_POINTER;
+    }
 
     var updateDir = getUpdatesDir();
 
     this._update = update;
 
     // This function may return null, which indicates that there are no patches
     // to download.
     this._patch = this._selectPatch(update, updateDir);
     if (!this._patch) {
       LOG("Downloader:downloadUpdate - no patch to download");
+      AUSTLMY.pingDownloadCode(undefined, AUSTLMY.DWNLD_ERR_NO_UPDATE_PATCH);
       return readStatusFile(updateDir);
     }
     this.isCompleteUpdate = this._patch.type == "complete";
 
     var patchFile = null;
 
 #ifdef MOZ_WIDGET_GONK
     let status = readStatusFile(updateDir);
@@ -4222,16 +4080,18 @@ Downloader.prototype = {
       }
     }
 #endif
     if (!patchFile) {
       // Find a place to put the patchfile that we're going to download.
       patchFile = this._getUpdateArchiveFile();
     }
     if (!patchFile) {
+      AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                               AUSTLMY.DWNLD_ERR_NO_PATCH_FILE);
       return STATE_NONE;
     }
 
 #ifdef MOZ_WIDGET_GONK
     if (patchFile.path.indexOf(updateDir.path) != 0) {
       // The patchFile is in a directory which is different from the
       // updateDir, create a link file.
       writeLinkFile(updateDir, patchFile);
@@ -4339,26 +4199,30 @@ Downloader.prototype = {
     LOG("Downloader:onProgress - progress: " + progress + "/" + maxProgress);
 
     if (progress > this._patch.size) {
       LOG("Downloader:onProgress - progress: " + progress +
           " is higher than patch size: " + this._patch.size);
       // It's important that we use a different code than
       // NS_ERROR_CORRUPTED_CONTENT so that tests can verify the difference
       // between a hash error and a wrong download error.
+      AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                               AUSTLMY.DWNLD_ERR_PATCH_SIZE_LARGER);
       this.cancel(Cr.NS_ERROR_UNEXPECTED);
       return;
     }
 
     if (maxProgress != this._patch.size) {
       LOG("Downloader:onProgress - maxProgress: " + maxProgress +
           " is not equal to expectd patch size: " + this._patch.size);
       // It's important that we use a different code than
       // NS_ERROR_CORRUPTED_CONTENT so that tests can verify the difference
       // between a hash error and a wrong download error.
+      AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                               AUSTLMY.DWNLD_ERR_PATCH_SIZE_NOT_EQUAL);
       this.cancel(Cr.NS_ERROR_UNEXPECTED);
       return;
     }
 
     var listeners = this._listeners.concat();
     var listenerCount = listeners.length;
     for (var i = 0; i < listenerCount; ++i) {
       var listener = listeners[i];
@@ -4421,16 +4285,17 @@ Downloader.prototype = {
         "current fail: " + this.updateService._consecutiveSocketErrors + ", " +
         "max fail: " + maxFail + ", " + "retryTimeout: " + retryTimeout);
     if (Components.isSuccessCode(status)) {
       if (this._verifyDownload()) {
         state = shouldUseService() ? STATE_PENDING_SVC : STATE_PENDING;
         if (this.background) {
           shouldShowPrompt = !getCanStageUpdates();
         }
+        AUSTLMY.pingDownloadCode(this.isCompleteUpdate, AUSTLMY.DWNLD_SUCCESS);
 
         // Tell the updater.exe we're ready to apply.
         writeStatusFile(getUpdatesDir(), state);
         writeVersionFile(getUpdatesDir(), this._update.appVersion);
         this._update.installDate = (new Date()).getTime();
         this._update.statusText = gUpdateBundle.GetStringFromName("installPending");
       }
       else {
@@ -4451,33 +4316,50 @@ Downloader.prototype = {
       }
     } else {
       if (status == Cr.NS_ERROR_OFFLINE) {
         // Register an online observer to try again.
         // The online observer will continue the incremental download by
         // calling downloadUpdate on the active update which continues
         // downloading the file from where it was.
         LOG("Downloader:onStopRequest - offline, register online observer: true");
+        AUSTLMY.pingDownloadCode(this.isCompleteUpdate,
+                                 AUSTLMY.DWNLD_RETRY_OFFLINE);
         shouldRegisterOnlineObserver = true;
         deleteActiveUpdate = false;
       // Each of NS_ERROR_NET_TIMEOUT, ERROR_CONNECTION_REFUSED, and
       // NS_ERROR_NET_RESET can be returned when disconnecting the internet while
       // a download of a MAR is in progress.  There may be others but I have not
       // encountered them during testing.
       } else if ((status == Cr.NS_ERROR_NET_TIMEOUT ||
                   status == Cr.NS_ERROR_CONNECTION_REFUSED ||
                   status == Cr.NS_ERROR_NET_RESET) &&
                  this.updateService._consecutiveSocketErrors < maxFail) {
         LOG("Downloader:onStopRequest - socket error, shouldRetrySoon: true");
+        let dwnldCode = AUSTLMY.DWNLD_RETRY_CONNECTION_REFUSED;
+        if (status == Cr.NS_ERROR_NET_TIMEOUT) {
+          dwnldCode = AUSTLMY.DWNLD_RETRY_NET_TIMEOUT;
+        } else if (status == Cr.NS_ERROR_NET_RESET) {
+          dwnldCode = AUSTLMY.DWNLD_RETRY_NET_RESET;
+        }
+        AUSTLMY.pingDownloadCode(this.isCompleteUpdate, dwnldCode);
         shouldRetrySoon = true;
         deleteActiveUpdate = false;
       } else if (status != Cr.NS_BINDING_ABORTED &&
                  status != Cr.NS_ERROR_ABORT &&
                  status != Cr.NS_ERROR_DOCUMENT_NOT_CACHED) {
         LOG("Downloader:onStopRequest - non-verification failure");
+        let dwnldCode = AUSTLMY.DWNLD_ERR_DOCUMENT_NOT_CACHED;
+        if (status == Cr.NS_BINDING_ABORTED) {
+          dwnldCode = AUSTLMY.DWNLD_ERR_BINDING_ABORTED;
+        } else if (status == Cr.NS_ERROR_ABORT) {
+          dwnldCode = AUSTLMY.DWNLD_ERR_ABORT;
+        }
+        AUSTLMY.pingDownloadCode(this.isCompleteUpdate, dwnldCode);
+
         // Some sort of other failure, log this in the |statusText| property
         state = STATE_DOWNLOAD_FAILED;
 
         // XXXben - if |request| (The Incremental Download) provided a means
         // for accessing the http channel we could do more here.
 
         this._update.statusText = getStatusTextFromCode(status,
                                                         Cr.NS_BINDING_FAILED);
@@ -4499,18 +4381,19 @@ Downloader.prototype = {
     this._patch.state = state;
     var um = Cc["@mozilla.org/updates/update-manager;1"].
              getService(Ci.nsIUpdateManager);
     if (deleteActiveUpdate) {
       this._update.installDate = (new Date()).getTime();
       um.activeUpdate = null;
     }
     else {
-      if (um.activeUpdate)
+      if (um.activeUpdate) {
         um.activeUpdate.state = state;
+      }
     }
     um.saveUpdates();
 
     // Only notify listeners about the stopped state if we
     // aren't handling an internal retry.
     if (!shouldRetrySoon && !shouldRegisterOnlineObserver) {
       var listeners = this._listeners.concat();
       var listenerCount = listeners.length;
@@ -4729,24 +4612,20 @@ UpdatePrompt.prototype = {
   /**
    * See nsIUpdateService.idl
    */
   showUpdateError: function UP_showUpdateError(update) {
     if (getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false) ||
         this._getAltUpdateWindow())
       return;
 
-    // In some cases, we want to just show a simple alert dialog:
+    // In some cases, we want to just show a simple alert dialog.
+    // Replace with Array.prototype.includes when it has stabilized.
     if (update.state == STATE_FAILED &&
-        (update.errorCode == WRITE_ERROR ||
-         update.errorCode == WRITE_ERROR_ACCESS_DENIED ||
-         update.errorCode == WRITE_ERROR_SHARING_VIOLATION_SIGNALED ||
-         update.errorCode == WRITE_ERROR_SHARING_VIOLATION_NOPROCESSFORPID ||
-         update.errorCode == WRITE_ERROR_SHARING_VIOLATION_NOPID ||
-         update.errorCode == WRITE_ERROR_CALLBACK_APP ||
+        (WRITE_ERRORS.indexOf(update.errorCode) != -1 ||
          update.errorCode == FILESYSTEM_MOUNT_READWRITE_ERROR ||
          update.errorCode == FOTA_GENERAL_ERROR ||
          update.errorCode == FOTA_FILE_OPERATION_ERROR ||
          update.errorCode == FOTA_RECOVERY_ERROR ||
          update.errorCode == FOTA_UNKNOWN_ERROR)) {
       var title = gUpdateBundle.GetStringFromName("updaterIOErrorTitle");
       var text = gUpdateBundle.formatStringFromName("updaterIOErrorMsg",
                                                     [Services.appinfo.name,
--- a/toolkit/mozapps/update/nsUpdateServiceStub.js
+++ b/toolkit/mozapps/update/nsUpdateServiceStub.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+Cu.import("resource://gre/modules/FileUtils.jsm", this);
 
 const DIR_UPDATES         = "updates";
 const FILE_UPDATE_STATUS  = "update.status";
 
 const KEY_UPDROOT         = "UpdRootD";
 
 /**
  * Gets the specified directory at the specified hierarchy under the update root
--- a/toolkit/mozapps/update/nsUpdateTimerManager.js
+++ b/toolkit/mozapps/update/nsUpdateTimerManager.js
@@ -1,14 +1,14 @@
 /* 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/. */
 
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm", this);
+Components.utils.import("resource://gre/modules/Services.jsm", this);
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 const PREF_APP_UPDATE_LASTUPDATETIME_FMT  = "app.update.lastUpdateTime.%ID%";
 const PREF_APP_UPDATE_TIMERMINIMUMDELAY   = "app.update.timerMinimumDelay";
 const PREF_APP_UPDATE_TIMERFIRSTINTERVAL  = "app.update.timerFirstInterval";
 const PREF_APP_UPDATE_LOG                 = "app.update.log";
--- a/toolkit/mozapps/update/tests/chrome/chrome.ini
+++ b/toolkit/mozapps/update/tests/chrome/chrome.ini
@@ -62,16 +62,18 @@ reason = Bug 918029 - timeout caused by 
 [test_0097_restartNotification_stagedServiceBackground.xul]
 [test_0101_background_restartNotification.xul]
 [test_0102_background_restartNotification_staging.xul]
 skip-if = os == 'linux'
 reason = Bug 918029 - timeout caused by copying too many files.
 [test_0103_background_restartNotification_stagingService.xul]
 skip-if = os != 'win'
 reason = only Windows has the maintenance service.
+[test_0104_background_restartNotification_NoIncompatAddons.xul]
+[test_0105_background_restartNotification_VersionCompatAddons.xul]
 [test_0111_neverButton_basic.xul]
 [test_0112_neverButton_billboard.xul]
 [test_0113_showNeverForVersionRemovedWithPref.xul]
 [test_0121_check_requireBuiltinCert.xul]
 [test_0122_check_allowNonBuiltinCert_validCertAttrs.xul]
 [test_0123_check_allowNonBuiltinCert_noCertAttrsCheck.xul]
 [test_0131_check_invalidCertAttrs_noUpdate.xul]
 [test_0132_check_invalidCertAttrs_hasUpdate.xul]
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/tests/chrome/test_0104_background_restartNotification_NoIncompatAddons.xul
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Update Wizard pages: background finish with a background download"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_FINISHED_BKGRD,
+  buttonClick: "extra1"
+} ];
+
+gDisableNoUpdateAddon = true;
+gDisableUpdateCompatibilityAddon = true;
+gDisableUpdateVersionAddon = true;
+
+function runTest() {
+  debugDump("entering");
+
+  Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
+
+  let url = URL_HTTP_UPDATE_XML + "?showDetails=1" +
+            getVersionParams(getNewerAppVersion(), getNewerPlatformVersion());
+  setUpdateURLOverride(url);
+
+  gAUS.notify(null);
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/tests/chrome/test_0105_background_restartNotification_VersionCompatAddons.xul
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Update Wizard pages: background finish with a background download"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_FINISHED_BKGRD,
+  buttonClick: "extra1"
+} ];
+
+gDisableNoUpdateAddon = true;
+gDisableUpdateCompatibilityAddon = true;
+
+function runTest() {
+  debugDump("entering");
+
+  Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
+
+  let url = URL_HTTP_UPDATE_XML + "?showDetails=1" +
+            getVersionParams(getNewerAppVersion(), getNewerPlatformVersion());
+  setUpdateURLOverride(url);
+
+  gAUS.notify(null);
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
--- a/toolkit/mozapps/update/tests/chrome/utils.js
+++ b/toolkit/mozapps/update/tests/chrome/utils.js
@@ -97,35 +97,41 @@
  *   the add-on is compatible with the current toolkit version and does not have
  *   an update to make it compatible with the update's toolkit version. Tests
  *   that need to have all add-ons compatible for the application update can
  *   disable this add-on by setting the gDisableNoUpdateAddon variable to true.
  *
  * updatecompatibility
  *   the add-on is compatible with the current toolkit version and has a
  *   compatibility update to make it compatible with the update's toolkit
- *   version.
+ *   version. Tests that need to have add-ons compatible for the application
+ *   update without updating the add-on's compatibility information can disable
+ *   this add-on by setting the gDisableUpdateCompatibilityAddon variable to
+ *   true.
  *
  * updateversion
  *   the add-on is compatible with the current toolkit version and has a version
- *   update to make it compatible with the update's toolkit version.
+ *   update to make it compatible with the update's toolkit version. Tests that
+ *   need to have add-ons compatible for the application update without updating
+ *   the add-on's to a new version that is compatible can disable this add-on by
+ *   setting the gDisableUpdateVersionAddon variable to true.
  *
  * userdisabled
  *   disabled by the user and compatible with the current toolkit version but
  *   not the update's toolkit version. This add-on will be disabled after its
  *   install completes.
  */
 
 'use strict';
 
 const { classes: Cc, interfaces: Ci, manager: Cm, results: Cr,
         utils: Cu } = Components;
 
-Cu.import("resource://gre/modules/AddonManager.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/AddonManager.jsm", this);
+Cu.import("resource://gre/modules/Services.jsm", this);
 
 const IS_MACOSX = ("nsILocalFileMac" in Ci);
 
 // The tests have to use the pageid instead of the pageIndex due to the
 // app update wizard's access method being random.
 const PAGEID_DUMMY            = "dummy";                 // Done
 const PAGEID_CHECKING         = "checking";              // Done
 const PAGEID_PLUGIN_UPDATES   = "pluginupdatesfound";
@@ -146,16 +152,18 @@ const PAGEID_FINISHED_BKGRD   = "finishe
 const PAGEID_INSTALLED        = "installed";             // Done
 
 const UPDATE_WINDOW_NAME = "Update:Wizard";
 
 const URL_HOST = "http://example.com";
 const URL_PATH_UPDATE_XML = "/chrome/toolkit/mozapps/update/tests/chrome/update.sjs";
 const REL_PATH_DATA = "chrome/toolkit/mozapps/update/tests/data";
 
+// These two URLs must not contain parameters since tests add their own
+// test specific parameters.
 const URL_HTTP_UPDATE_XML = URL_HOST + URL_PATH_UPDATE_XML;
 const URL_HTTPS_UPDATE_XML = "https://example.com" + URL_PATH_UPDATE_XML;
 
 const URI_UPDATE_PROMPT_DIALOG  = "chrome://mozapps/content/update/updates.xul";
 
 const ADDON_ID_SUFFIX = "@appupdatetest.mozilla.org";
 const ADDON_PREP_DIR = "appupdateprep";
 
@@ -197,16 +205,18 @@ var gAppUpdateURLDefault;         // app
 var gAppUpdateURL;                // app.update.url.override
 var gExtUpdateURL;                // extensions.update.url
 
 var gTestCounter = -1;
 var gWin;
 var gDocElem;
 var gPrefToCheck;
 var gDisableNoUpdateAddon = false;
+var gDisableUpdateCompatibilityAddon = false;
+var gDisableUpdateVersionAddon = false;
 
 // Set to true to log additional information for debugging. To log additional
 // information for an individual test set DEBUG_AUS_TEST to true in the test's
 // onload function.
 var DEBUG_AUS_TEST = false;
 
 const DATA_URI_SPEC = "chrome://mochitests/content/chrome/toolkit/mozapps/update/tests/data/";
 Services.scriptloader.loadSubScript(DATA_URI_SPEC + "shared.js", this);
@@ -1120,31 +1130,37 @@ function setupAddons(aCallback) {
   debugDump("entering");
 
   // Sets the appropriate userDisabled value for the noupdate test add-ons based
   // on the value of gDisableNoUpdateAddon and calls the callback specified in
   // setupAddons aCallback parameter.
   function setNoUpdateAddonsDisabledState() {
     AddonManager.getAllAddons(function(aAddons) {
       aAddons.forEach(function(aAddon) {
-        if (aAddon.name.indexOf("appdisabled") == 0) {
+        if (aAddon.name.startsWith("appdisabled")) {
           if (!aAddon.userDisabled) {
             aAddon.userDisabled = true;
           }
         }
 
-        if (aAddon.name.indexOf("noupdate") == 0) {
-          if (gDisableNoUpdateAddon) {
-            if (!aAddon.userDisabled) {
-              aAddon.userDisabled = true;
-            }
-          } else {
-            if (aAddon.userDisabled) {
-              aAddon.userDisabled = false;
-            }
+        if (aAddon.name.startsWith("noupdate")) {
+          if (aAddon.userDisabled != gDisableNoUpdateAddon) {
+            aAddon.userDisabled = gDisableNoUpdateAddon;
+          }
+        }
+
+        if (aAddon.name.startsWith("updatecompatibility")) {
+          if (aAddon.userDisabled != gDisableUpdateCompatibilityAddon) {
+            aAddon.userDisabled = gDisableUpdateCompatibilityAddon;
+          }
+        }
+
+        if (aAddon.name.startsWith("updateversion")) {
+          if (aAddon.userDisabled != gDisableUpdateVersionAddon) {
+            aAddon.userDisabled = gDisableUpdateVersionAddon;
           }
         }
       });
       // Start the timout timer before the update window is displayed so it can
       // clean up tests that don't successfully display the update window.
       setupTimer(gTestTimeout);
       aCallback();
     });
--- a/toolkit/mozapps/update/tests/data/partial_log_failure
+++ b/toolkit/mozapps/update/tests/data/partial_log_failure
@@ -177,10 +177,10 @@ backup_restore: backup file doesn't exis
 FINISH REMOVEFILE 4/4text1
 backup_restore: backup file doesn't exist: 4/4text1.moz-backup
 FINISH REMOVEFILE 4/4text0
 backup_restore: backup file doesn't exist: 4/4text0.moz-backup
 FINISH REMOVEFILE 3/3text1
 backup_restore: backup file doesn't exist: 3/3text1.moz-backup
 FINISH REMOVEFILE 3/3text0
 backup_restore: backup file doesn't exist: 3/3text0.moz-backup
-failed: 42
+failed: 2
 calling QuitProgressUI
--- a/toolkit/mozapps/update/tests/data/partial_log_failure_mac
+++ b/toolkit/mozapps/update/tests/data/partial_log_failure_mac
@@ -177,10 +177,10 @@ backup_restore: backup file doesn't exis
 FINISH REMOVEFILE Contents/Resources/4/4text1
 backup_restore: backup file doesn't exist: Contents/Resources/4/4text1.moz-backup
 FINISH REMOVEFILE Contents/Resources/4/4text0
 backup_restore: backup file doesn't exist: Contents/Resources/4/4text0.moz-backup
 FINISH REMOVEFILE Contents/Resources/3/3text1
 backup_restore: backup file doesn't exist: Contents/Resources/3/3text1.moz-backup
 FINISH REMOVEFILE Contents/Resources/3/3text0
 backup_restore: backup file doesn't exist: Contents/Resources/3/3text0.moz-backup
-failed: 42
+failed: 2
 calling QuitProgressUI
--- a/toolkit/mozapps/update/tests/data/sharedUpdateXML.js
+++ b/toolkit/mozapps/update/tests/data/sharedUpdateXML.js
@@ -30,21 +30,22 @@ const STATE_PENDING         = "pending";
 const STATE_PENDING_SVC     = "pending-service";
 const STATE_APPLYING        = "applying";
 const STATE_APPLIED         = "applied";
 const STATE_APPLIED_SVC     = "applied-service";
 const STATE_SUCCEEDED       = "succeeded";
 const STATE_DOWNLOAD_FAILED = "download-failed";
 const STATE_FAILED          = "failed";
 
-const STATE_FAILED_READ_ERROR                      = STATE_FAILED + ": 6";
-const STATE_FAILED_WRITE_ERROR                     = STATE_FAILED + ": 7";
-const STATE_FAILED_CHANNEL_MISMATCH_ERROR          = STATE_FAILED + ": 22";
-const STATE_FAILED_VERSION_DOWNGRADE_ERROR         = STATE_FAILED + ": 23";
-const STATE_FAILED_UNEXPECTED_FILE_OPERATION_ERROR = STATE_FAILED + ": 42";
+const STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE = STATE_FAILED + ": 2";
+const STATE_FAILED_READ_ERROR                  = STATE_FAILED + ": 6";
+const STATE_FAILED_WRITE_ERROR                 = STATE_FAILED + ": 7";
+const STATE_FAILED_CHANNEL_MISMATCH_ERROR      = STATE_FAILED + ": 22";
+const STATE_FAILED_VERSION_DOWNGRADE_ERROR     = STATE_FAILED + ": 23";
+const STATE_FAILED_WRITE_ERROR_FILE_COPY       = STATE_FAILED + ": 61";
 
 /**
  * Constructs a string representing a remote update xml file.
  *
  * @param  aUpdates
  *         The string representing the update elements.
  * @return The string representing a remote update xml file.
  */
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -4,17 +4,18 @@
 
 'use strict';
 
 const { classes: Cc, interfaces: Ci, manager: Cm, results: Cr,
         utils: Cu } = Components;
 
 load("../data/xpcshellConstantsPP.js");
 
-Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Services.jsm", this);
+Cu.import("resource://gre/modules/ctypes.jsm", this);
 
 const DIR_MACOS = IS_MACOSX ? "Contents/MacOS/" : "";
 const DIR_RESOURCES = IS_MACOSX ? "Contents/Resources/" : "";
 const TEST_FILE_SUFFIX =  IS_MACOSX ? "_mac" : "";
 const FILE_COMPLETE_MAR = "complete" + TEST_FILE_SUFFIX + ".mar";
 const FILE_PARTIAL_MAR = "partial" + TEST_FILE_SUFFIX + ".mar";
 const LOG_COMPLETE_SUCCESS = "complete_log_success" + TEST_FILE_SUFFIX;
 const LOG_PARTIAL_SUCCESS  = "partial_log_success" + TEST_FILE_SUFFIX;
@@ -1191,17 +1192,16 @@ function getTestDirFile(aRelPath) {
   return do_get_file(relpath, false);
 }
 
 function getSpecialFolderDir(aCSIDL) {
   if (!IS_WIN) {
     do_throw("Windows only function called by a different platform!");
   }
 
-  Cu.import("resource://gre/modules/ctypes.jsm");
   let lib = ctypes.open("shell32");
   let SHGetSpecialFolderPath = lib.declare("SHGetSpecialFolderPathW",
                                            ctypes.winapi_abi,
                                            ctypes.bool, /* bool(return) */
                                            ctypes.int32_t, /* HWND hwndOwner */
                                            ctypes.char16_t.ptr, /* LPTSTR lpszPath */
                                            ctypes.int32_t, /* int csidl */
                                            ctypes.bool /* BOOL fCreate */);
@@ -1526,18 +1526,23 @@ function runUpdate(aExpectedExitValue, a
                   process.exitValue + ", Expected: " +  aExpectedExitValue);
     }
     if (status != aExpectedStatus) {
       logTestInfo("update status is not the expected status! Got: " + status +
                   ", Expected: " +  aExpectedStatus);
     }
     let updateLog = getUpdatesPatchDir();
     updateLog.append(FILE_UPDATE_LOG);
-    logTestInfo("contents of " + updateLog.path + ":\n" +
-                readFileBytes(updateLog).replace(/\r\n/g, "\n"));
+    // xpcshell tests won't display the entire contents so log each line.
+    let contents = readFileBytes(updateLog).replace(/\r\n/g, "\n");
+    let aryLogContents = contents.split("\n");
+    logTestInfo("contents of " + updateLog.path + ":");
+    aryLogContents.forEach(function RU_LC_FE(aLine) {
+      logTestInfo(aLine);
+    });
   }
   debugDump("testing updater binary process exitValue against expected " +
             "exit value");
   do_check_eq(process.exitValue, aExpectedExitValue);
   debugDump("testing update status against expected status");
   do_check_eq(status, aExpectedStatus);
 
   if (aCallback !== null) {
@@ -2070,17 +2075,17 @@ function runUpdateUsingService(aInitialS
   // We will rely on watching the update.status file and waiting for the service
   // to stop to know the service command is done.
   process.run(true, args, args.length);
 
   resetEnvironment();
 
   function timerCallback(aTimer) {
     // Wait for the expected status
-    let status = readStatusState();
+    let status = readStatusFile();
     // status will probably always be equal to STATE_APPLYING but there is a
     // race condition where it would be possible on slower machines where status
     // could be equal to STATE_PENDING_SVC.
     if (status == STATE_APPLYING ||
         status == STATE_PENDING_SVC) {
       debugDump("still waiting to see the " + aExpectedStatus +
                 " status, got " + status + " for now...");
       return;
@@ -2093,18 +2098,23 @@ function runUpdateUsingService(aInitialS
     aTimer = null;
 
     if (status != aExpectedStatus) {
       logTestInfo("update status is not the expected status! Got: " + status +
                   ", Expected: " +  aExpectedStatus);
       logTestInfo("update.status contents: " + readStatusFile());
       let updateLog = getUpdatesPatchDir();
       updateLog.append(FILE_UPDATE_LOG);
-      logTestInfo("contents of " + updateLog.path + ":\n" +
-                  readFileBytes(updateLog).replace(/\r\n/g, "\n"));
+      // xpcshell tests won't display the entire contents so log each line.
+      let contents = readFileBytes(updateLog).replace(/\r\n/g, "\n");
+      let aryLogContents = contents.split("\n");
+      logTestInfo("contents of " + updateLog.path + ":");
+      aryLogContents.forEach(function RUUS_TC_LC_FE(aLine) {
+        logTestInfo(aLine);
+      });
     }
     debugDump("testing update status against expected status");
     do_check_eq(status, aExpectedStatus);
 
     if (aCheckSvcLog) {
       checkServiceLogs(svcOriginalLog);
     }
 
@@ -2465,17 +2475,32 @@ function checkUpdateLogContents(aCompare
 
   // Don't write the contents of the file to the log to reduce log spam
   // unless there is a failure.
   if (compareLogContents == updateLogContents) {
     debugDump("log contents are correct");
     do_check_true(true);
   } else {
     logTestInfo("log contents are not correct");
-    do_check_eq(compareLogContents, updateLogContents);
+    let aryLog = updateLogContents.split("\n");
+    let aryCompare = compareLogContents.split("\n");
+    // Pushing an empty string to both arrays makes it so either array's length
+    // can be used in the for loop below without going out of bounds.
+    aryLog.push("");
+    aryCompare.push("");
+    // xpcshell tests won't display the entire contents so log the incorrect
+    // line.
+    for (let i = 0; i < aryLog.length; ++i) {
+      if (aryCompare[i] != aryLog[i]) {
+        logTestInfo("the first incorrect line in the log is: " + aryLog[i]);
+        do_check_eq(aryCompare[i], aryLog[i]);
+      }
+    }
+    // This should never happen!
+    do_throw("Unable to find incorrect log contents!");
   }
 }
 
 /**
  * Helper function to check if the update log contains a string.
  *
  * @param   aCheckString
  *          The string to check if the update log contains.
@@ -2484,17 +2509,16 @@ function checkUpdateLogContains(aCheckSt
   let updateLog = getUpdatesPatchDir();
   updateLog.append(FILE_UPDATE_LOG);
   let updateLogContents = readFileBytes(updateLog);
   if (updateLogContents.indexOf(aCheckString) != -1) {
     debugDump("log file does contain: " + aCheckString);
     do_check_true(true);
   } else {
     logTestInfo("log file does not contain: " + aCheckString);
-    logTestInfo("log file contents:\n" + updateLogContents);
     do_check_true(false);
   }
 }
 
 /**
  * Helper function for updater binary tests for verifying the state of files and
  * directories after a successful update.
  *
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
@@ -84,10 +84,11 @@ function finishTest() {
   if (IS_WIN || IS_MACOSX) {
     // Check that the post update process was not launched.
     do_check_false(getPostUpdateFile(".running").exists());
   }
 
   do_check_eq(readStatusState(), STATE_PENDING);
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   unlockDirectory(getAppBaseDir());
+  standardInit();
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseFallbackStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseFallbackStageFailureComplete_win.js
@@ -35,10 +35,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
@@ -36,10 +36,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
@@ -108,16 +108,17 @@ function finishCheckUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   if (IS_UNIX) {
     checkSymlink();
   }
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  standardInit();
   checkCallbackAppLog();
 }
 
 function runHelperProcess(args) {
   let helperBin = getTestDirFile(FILE_HELPER_BIN);
   let process = Cc["@mozilla.org/process/util;1"].
                 createInstance(Ci.nsIProcess);
   process.init(helperBin);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js
@@ -48,10 +48,11 @@ function checkUpdate() {
     let now = Date.now();
     let applyToDir = getApplyDirFile();
     let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
     do_check_true(timeDiff < MAC_MAX_TIME_DIFFERENCE);
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
@@ -18,10 +18,11 @@ function run_test() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(0, STATE_SUCCEEDED);
 }
 
 function checkUpdateApplied() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
@@ -18,10 +18,11 @@ function run_test() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(0, STATE_SUCCEEDED);
 }
 
 function checkUpdateApplied() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js
@@ -12,10 +12,11 @@ function run_test() {
 
   gCallbackBinFile = "exe0.exe";
 
   runUpdate(0, STATE_SUCCEEDED);
 }
 
 function checkUpdateApplied() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js
@@ -12,10 +12,11 @@ function run_test() {
 
   gCallbackBinFile = "exe0.exe";
 
   runUpdate(0, STATE_SUCCEEDED);
 }
 
 function checkUpdateApplied() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js
@@ -21,17 +21,17 @@ function run_test() {
   if (IS_MACOSX) {
     let now = Date.now();
     let yesterday = now - (1000 * 60 * 60 * 24);
     let applyToDir = getApplyDirFile();
     applyToDir.lastModifiedTime = yesterday;
   }
 
   // Note that on platforms where we use execv, we cannot trust the return code.
-  runUpdate((USE_EXECV ? 0 : 1), STATE_FAILED_UNEXPECTED_FILE_OPERATION_ERROR);
+  runUpdate((USE_EXECV ? 0 : 1), STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE);
 }
 
 /**
  * Checks if the update has finished and if it has finished performs checks for
  * the test.
  */
 function checkUpdateApplied() {
   if (IS_WIN || IS_MACOSX) {
@@ -45,10 +45,11 @@ function checkUpdateApplied() {
     let now = Date.now();
     let applyToDir = getApplyDirFile();
     let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
     do_check_true(timeDiff < MAC_MAX_TIME_DIFFERENCE);
   }
 
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_PARTIAL_FAILURE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseFallbackStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseFallbackStageFailureComplete_win.js
@@ -36,10 +36,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseFallbackStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseFallbackStageFailurePartial_win.js
@@ -36,10 +36,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
@@ -37,10 +37,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
@@ -37,10 +37,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js
@@ -1,18 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use complete MAR file patch apply success test */
 
 function run_test() {
-  // Set to true due to bug 1123503
-  DEBUG_AUS_TEST = true;
-
   setupTestCommon();
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setupUpdaterTest(FILE_COMPLETE_MAR);
 
   // Launch an existing file so it is in use during the update.
   let fileInUseBin = getApplyDirFile(gTestFiles[13].relPathDir +
                                      gTestFiles[13].fileName);
@@ -32,10 +29,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js
@@ -29,10 +29,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js
@@ -39,10 +39,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js
@@ -39,10 +39,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_UNABLE_OPEN_DEST);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFallbackStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFallbackStageFailureComplete_win.js
@@ -30,25 +30,26 @@ function run_test() {
                         createInstance(Ci.nsIProcess);
   lockFileProcess.init(helperBin);
   lockFileProcess.run(false, args, args.length);
 
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdate(1, STATE_FAILED_WRITE_ERROR, null);
+  runUpdate(1, STATE_FAILED_WRITE_ERROR_FILE_COPY, null);
 
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(1, STATE_PENDING);
 }
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFallbackStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFallbackStageFailurePartial_win.js
@@ -30,25 +30,26 @@ function run_test() {
                         createInstance(Ci.nsIProcess);
   lockFileProcess.init(helperBin);
   lockFileProcess.run(false, args, args.length);
 
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdate(1, STATE_FAILED_WRITE_ERROR, null);
+  runUpdate(1, STATE_FAILED_WRITE_ERROR_FILE_COPY, null);
 
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(1, STATE_PENDING);
 }
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
@@ -30,26 +30,27 @@ function run_test() {
                         createInstance(Ci.nsIProcess);
   lockFileProcess.init(helperBin);
   lockFileProcess.run(false, args, args.length);
 
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdate(1, STATE_FAILED_WRITE_ERROR, null);
+  runUpdate(1, STATE_FAILED_WRITE_ERROR_FILE_COPY, null);
 
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   gDisableReplaceFallback = true;
   runUpdate(1, STATE_FAILED_WRITE_ERROR);
 }
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
@@ -30,26 +30,27 @@ function run_test() {
                         createInstance(Ci.nsIProcess);
   lockFileProcess.init(helperBin);
   lockFileProcess.run(false, args, args.length);
 
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdate(1, STATE_FAILED_WRITE_ERROR, null);
+  runUpdate(1, STATE_FAILED_WRITE_ERROR_FILE_COPY, null);
 
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   gDisableReplaceFallback = true;
   runUpdate(1, STATE_FAILED_WRITE_ERROR);
 }
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseFallbackStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseFallbackStageFailureComplete_win.js
@@ -47,10 +47,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseFallbackStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseFallbackStageFailurePartial_win.js
@@ -45,10 +45,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
@@ -48,10 +48,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
@@ -46,10 +46,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js
@@ -39,10 +39,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js
@@ -37,10 +37,11 @@ function doUpdate() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
@@ -21,25 +21,26 @@ function run_test() {
   // the precomplete file in the root of the bundle is renamed, etc. (bug 600098).
   if (IS_MACOSX) {
     let now = Date.now();
     let yesterday = now - (1000 * 60 * 60 * 24);
     let applyToDir = getApplyDirFile();
     applyToDir.lastModifiedTime = yesterday;
   }
 
-  runUpdate(1, STATE_FAILED_UNEXPECTED_FILE_OPERATION_ERROR);
+  runUpdate(1, STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE);
 }
 
 /**
  * Checks if the update has finished and if it has finished performs checks for
  * the test.
  */
 function checkUpdateApplied() {
   if (IS_WIN || IS_MACOSX) {
     // Check that the post update process was not launched.
     do_check_false(getPostUpdateFile(".running").exists());
   }
 
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContents(LOG_PARTIAL_FAILURE);
+  standardInit();
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js
@@ -113,16 +113,17 @@ function finishCheckUpdateApplied() {
     checkUpdateLogContains("removing old distribution directory");
   }
 
   if (IS_UNIX && !IS_MACOSX) {
     checkSymlink();
   }
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  standardInit();
   checkCallbackAppLog();
 }
 
 function runHelperProcess(args) {
   let helperBin = getTestDirFile(FILE_HELPER_BIN);
   let process = Cc["@mozilla.org/process/util;1"].
                 createInstance(Ci.nsIProcess);
   process.init(helperBin);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
@@ -106,10 +106,11 @@ function finishCheckUpdateApplied() {
     debugDump("testing that files aren't added with an add-if instruction " +
               "when the file's destination directory doesn't exist");
     debugDump("testing " + distributionDir.path + " shouldn't exist");
     do_check_false(distributionDir.exists());
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js
@@ -86,10 +86,11 @@ function finishCheckUpdateApplied() {
     debugDump("testing that files aren't added with an add-if instruction " +
               "when the file's destination directory doesn't exist");
     debugDump("testing " + distributionDir.path + " shouldn't exist");
     do_check_false(distributionDir.exists());
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js
@@ -76,10 +76,11 @@ function finishCheckUpdateApplied() {
     debugDump("testing " + distributionDir.path + " shouldn't exist");
     do_check_false(distributionDir.exists());
 
     checkUpdateLogContains("removing old distribution directory");
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js
@@ -32,10 +32,11 @@ function run_test() {
  */
 function checkUpdateApplied() {
   if (IS_WIN || IS_MACOSX) {
     // Check that the post update process was not launched.
     do_check_false(getPostUpdateFile(".running").exists());
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   doTestFinish();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js
@@ -32,10 +32,11 @@ function run_test() {
  */
 function checkUpdateApplied() {
   if (IS_WIN || IS_MACOSX) {
     // Check that the post update process was not launched.
     do_check_false(getPostUpdateFile(".running").exists());
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   doTestFinish();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
@@ -90,10 +90,11 @@ function finishTest() {
     debugDump("checking that the post update process running file doesn't " +
               "exist. Path: " + running.path);
     do_check_false(running.exists());
   }
 
   do_check_eq(readStatusState(), STATE_PENDING);
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   unlockDirectory(getAppBaseDir());
+  standardInit();
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseFallbackStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseFallbackStageFailureCompleteSvc_win.js
@@ -45,10 +45,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
@@ -46,10 +46,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js
@@ -56,10 +56,11 @@ function checkUpdate() {
     let now = Date.now();
     let applyToDir = getApplyDirFile();
     let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
     do_check_true(timeDiff < MAC_MAX_TIME_DIFFERENCE);
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
@@ -1,18 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Replace app binary complete MAR file staged patch apply success test */
 
 function run_test() {
-  // Set to true due to bug 1037599
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
@@ -31,10 +28,11 @@ function checkUpdateFinished() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(0, STATE_SUCCEEDED);
 }
 
 function checkUpdateApplied() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
@@ -28,10 +28,11 @@ function checkUpdateFinished() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(0, STATE_SUCCEEDED);
 }
 
 function checkUpdateApplied() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js
@@ -20,10 +20,11 @@ function run_test() {
 }
 
 function setupAppFilesFinished() {
   runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED);
 }
 
 function checkUpdateFinished() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js
@@ -20,10 +20,11 @@ function run_test() {
 }
 
 function setupAppFilesFinished() {
   runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED);
 }
 
 function checkUpdateFinished() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js
@@ -28,17 +28,18 @@ function run_test() {
     let applyToDir = getApplyDirFile();
     applyToDir.lastModifiedTime = yesterday;
   }
 
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC,
+                        STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE);
 }
 
 /**
  * Checks if the update has finished and if it has finished performs checks for
  * the test.
  */
 function checkUpdateFinished() {
   if (IS_MACOSX) {
@@ -54,10 +55,11 @@ function checkUpdateFinished() {
     let running = getPostUpdateFile(".running");
     debugDump("checking that the post update process running file doesn't " +
               "exist. Path: " + running.path);
     do_check_false(running.exists());
   }
 
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_PARTIAL_FAILURE);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseFallbackStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseFallbackStageFailureCompleteSvc_win.js
@@ -46,10 +46,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseFallbackStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseFallbackStageFailurePartialSvc_win.js
@@ -46,10 +46,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
@@ -47,10 +47,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
@@ -47,10 +47,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js
@@ -37,10 +37,11 @@ function doUpdate() {
 
 function checkUpdateFinished() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js
@@ -37,10 +37,11 @@ function doUpdate() {
 
 function checkUpdateFinished() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js
@@ -37,20 +37,21 @@ function run_test() {
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR);
 }
 
 function checkUpdateFinished() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js
@@ -37,20 +37,21 @@ function run_test() {
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_READ_ERROR);
 }
 
 function checkUpdateFinished() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_UNABLE_OPEN_DEST);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFallbackStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFallbackStageFailureCompleteSvc_win.js
@@ -38,27 +38,28 @@ function run_test() {
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR_FILE_COPY);
 }
 
 function checkUpdateFinished() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(1, STATE_PENDING);
 }
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFallbackStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFallbackStageFailurePartialSvc_win.js
@@ -38,27 +38,28 @@ function run_test() {
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR_FILE_COPY);
 }
 
 function checkUpdateFinished() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   runUpdate(1, STATE_PENDING);
 }
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
@@ -38,17 +38,17 @@ function run_test() {
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR_FILE_COPY);
 }
 
 function checkUpdateFinished() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   gDisableReplaceFallback = true;
   runUpdate(1, STATE_FAILED_WRITE_ERROR);
@@ -56,10 +56,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
@@ -38,17 +38,17 @@ function run_test() {
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
   do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep);
 }
 
 function doUpdate() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR_FILE_COPY);
 }
 
 function checkUpdateFinished() {
   // Switch the application to the staged application that was updated.
   gStageUpdate = false;
   gSwitchApp = true;
   gDisableReplaceFallback = true;
   runUpdate(1, STATE_FAILED_WRITE_ERROR);
@@ -56,10 +56,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseFallbackStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseFallbackStageFailureCompleteSvc_win.js
@@ -1,19 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir complete MAR file staged patch apply failure
    fallback test */
 
 function run_test() {
-  // Set to true due to bug 1123503
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
@@ -60,10 +57,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseFallbackStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseFallbackStageFailurePartialSvc_win.js
@@ -1,19 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir partial MAR file staged patch apply failure
    fallback test */
 
 function run_test() {
-  // Set to true due to bug 1112284
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
@@ -58,10 +55,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, false, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
@@ -1,19 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir complete MAR file staged patch apply failure
    test */
 
 function run_test() {
-  // Set to true due to bug 1123503
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
@@ -61,10 +58,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
@@ -1,19 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir partial MAR file staged patch apply failure
    test */
 
 function run_test() {
-  // Set to true due to bug 1112284
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
@@ -59,10 +56,11 @@ function checkUpdateFinished() {
 
 function checkUpdateApplied() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContains(ERR_RENAME_FILE);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js
@@ -47,10 +47,11 @@ function doUpdate() {
 
 function checkUpdateFinished() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js
@@ -45,10 +45,11 @@ function doUpdate() {
 
 function checkUpdateFinished() {
   setupHelperFinish();
 }
 
 function checkUpdate() {
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
@@ -1,19 +1,16 @@
 /* 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/.
  */
 
 /* General Partial MAR File Staged Patch Apply Failure Test */
 
 function run_test() {
-  // Set to true due to bug 1109219
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesPartialSuccess;
   gTestFiles[11].originalFile = "partial.png";
@@ -32,27 +29,29 @@ function run_test() {
     let applyToDir = getApplyDirFile();
     applyToDir.lastModifiedTime = yesterday;
   }
 
   setupAppFilesAsync();
 }
 
 function setupAppFilesFinished() {
-  runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED);
+  runUpdateUsingService(STATE_PENDING_SVC,
+                        STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE);
 }
 
 /**
  * Checks if the update has finished and if it has finished performs checks for
  * the test.
  */
 function checkUpdateFinished() {
   if (IS_WIN || IS_MACOSX) {
     let running = getPostUpdateFile(".running");
     debugDump("checking that the post update process running file doesn't " +
               "exist. Path: " + running.path);
     do_check_false(running.exists());
   }
 
   checkFilesAfterUpdateFailure(getApplyDirFile, true, false);
   checkUpdateLogContents(LOG_PARTIAL_FAILURE);
+  standardInit();
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js
@@ -111,16 +111,17 @@ function finishCheckUpdateApplied() {
     do_check_true(running.exists());
   }
 
   if (IS_UNIX && !IS_MACOSX) {
     checkSymlink();
   }
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  standardInit();
   checkCallbackAppLog();
 }
 
 function runHelperProcess(args) {
   let helperBin = getTestDirFile(FILE_HELPER_BIN);
   let process = Cc["@mozilla.org/process/util;1"].
                 createInstance(Ci.nsIProcess);
   process.init(helperBin);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
@@ -1,19 +1,16 @@
 /* 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/.
  */
 
 /* General Partial MAR File Staged Patch Apply Test */
 
 function run_test() {
-  // Set to true due to bug 1083653
-  DEBUG_AUS_TEST = true;
-
   if (!shouldRunServiceTest()) {
     return;
   }
 
   gStageUpdate = true;
   setupTestCommon();
   gTestFiles = gTestFilesPartialSuccess;
   gTestFiles[gTestFiles.length - 2].originalContents = null;
@@ -91,10 +88,11 @@ function finishCheckUpdateApplied() {
     let running = getPostUpdateFile(".running");
     debugDump("checking that the post update process running file exists. " +
               "Path: " + running.path);
     do_check_true(running.exists());
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
+  standardInit();
   checkCallbackAppLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js
@@ -58,10 +58,11 @@ function finishCheckUpdateFinished() {
     let now = Date.now();
     let applyToDir = getApplyDirFile();
     let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
     do_check_true(timeDiff < MAC_MAX_TIME_DIFFERENCE);
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js
@@ -64,10 +64,11 @@ function finishCheckUpdateFinished() {
     let now = Date.now();
     let applyToDir = getApplyDirFile();
     let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
     do_check_true(timeDiff < MAC_MAX_TIME_DIFFERENCE);
   }
 
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
+  standardInit();
   checkCallbackServiceLog();
 }
--- a/toolkit/mozapps/update/updater/archivereader.cpp
+++ b/toolkit/mozapps/update/updater/archivereader.cpp
@@ -303,17 +303,17 @@ ArchiveReader::ExtractItemToStream(const
     if (ret != BZ_OK && ret != BZ_STREAM_END) {
       ret = UNEXPECTED_BZIP_ERROR;
       break;
     }
 
     outlen = outbuf_size - strm.avail_out;
     if (outlen) {
       if (fwrite(outbuf, outlen, 1, fp) != 1) {
-        ret = WRITE_ERROR;
+        ret = WRITE_ERROR_EXTRACT;
         break;
       }
     }
 
     if (ret == BZ_STREAM_END) {
       ret = OK;
       break;
     }
--- a/toolkit/mozapps/update/updater/bspatch.cpp
+++ b/toolkit/mozapps/update/updater/bspatch.cpp
@@ -144,30 +144,30 @@ MBS_ApplyPatch(const MBSPatchHeader *hea
           diffsrc + ctrlsrc->x > diffend) {
         rv = UNEXPECTED_BSPATCH_ERROR;
         goto end;
       }
       for (uint32_t i = 0; i < ctrlsrc->x; ++i) {
         diffsrc[i] += fbuffer[i];
       }
       if ((uint32_t) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x) {
-        rv = WRITE_ERROR;
+        rv = WRITE_ERROR_PATCH_FILE;
         goto end;
       }
       fbuffer += ctrlsrc->x;
       diffsrc += ctrlsrc->x;
 
       /* Copy y bytes from the extra block */
 
       if (extrasrc + ctrlsrc->y > extraend) {
         rv = UNEXPECTED_BSPATCH_ERROR;
         goto end;
       }
       if ((uint32_t) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y) {
-        rv = WRITE_ERROR;
+        rv = WRITE_ERROR_PATCH_FILE;
         goto end;
       }
       extrasrc += ctrlsrc->y;
 
       /* "seek" forwards in oldfile by z bytes */
 
       if (fbuffer + ctrlsrc->z > fbufend) {
         rv = UNEXPECTED_BSPATCH_ERROR;
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -635,19 +635,19 @@ create_hard_link(const NS_tchar *srcFile
 static int ensure_copy(const NS_tchar *path, const NS_tchar *dest)
 {
 #ifdef XP_WIN
   // Fast path for Windows
   bool result = CopyFileW(path, dest, false);
   if (!result) {
     LOG(("ensure_copy: failed to copy the file " LOG_S " over to " LOG_S ", lasterr: %x",
          path, dest, GetLastError()));
-    return WRITE_ERROR;
+    return WRITE_ERROR_FILE_COPY;
   }
-  return 0;
+  return OK;
 #else
   struct NS_tstat_t ss;
   int rv = NS_tlstat(path, &ss);
   if (rv) {
     LOG(("ensure_copy: failed to read file status info: " LOG_S ", err: %d",
          path, errno));
     return READ_ERROR;
   }
@@ -701,17 +701,17 @@ static int ensure_copy(const NS_tchar *p
     size_t written = 0;
 
     while (written < read) {
       size_t chunkWritten = fwrite(buffer, 1, read - written, outfile);
       if (chunkWritten <= 0) {
         LOG(("ensure_copy: failed to write the file: " LOG_S ", err: %d",
              dest, errno));
         free(buffer);
-        return WRITE_ERROR;
+        return WRITE_ERROR_FILE_COPY;
       }
 
       written += chunkWritten;
     }
   }
 
   rv = NS_tchmod(dest, ss.st_mode);
 
@@ -817,27 +817,27 @@ static int rename_file(const NS_tchar *s
          "err: %d", spath, errno));
     return READ_ERROR;
   }
 
   if (!S_ISREG(spathInfo.st_mode)) {
     if (allowDirs && !S_ISDIR(spathInfo.st_mode)) {
       LOG(("rename_file: path present, but not a file: " LOG_S ", err: %d",
            spath, errno));
-      return UNEXPECTED_FILE_OPERATION_ERROR;
+      return RENAME_ERROR_EXPECTED_FILE;
     } else {
       LOG(("rename_file: proceeding to rename the directory"));
     }
   }
 
   if (!NS_taccess(dpath, F_OK)) {
     if (ensure_remove(dpath)) {
       LOG(("rename_file: destination file exists and could not be " \
            "removed: " LOG_S, dpath));
-      return WRITE_ERROR;
+      return WRITE_ERROR_DELETE_FILE;
     }
   }
 
   if (NS_trename(spath, dpath) != 0) {
     LOG(("rename_file: failed to rename file - src: " LOG_S ", " \
          "dst:" LOG_S ", err: %d", spath, dpath, errno));
     return WRITE_ERROR;
   }
@@ -889,34 +889,34 @@ static int backup_discard(const NS_tchar
 #if defined(XP_WIN)
   if (rv && !sStagedUpdate && !sReplaceRequest) {
     LOG(("backup_discard: unable to remove: " LOG_S, backup));
     NS_tchar path[MAXPATHLEN];
     GetTempFileNameW(DELETE_DIR, L"moz", 0, path);
     if (rename_file(backup, path)) {
       LOG(("backup_discard: failed to rename file:" LOG_S ", dst:" LOG_S,
            backup, path));
-      return WRITE_ERROR;
+      return WRITE_ERROR_DELETE_BACKUP;
     }
     // The MoveFileEx call to remove the file on OS reboot will fail if the
     // process doesn't have write access to the HKEY_LOCAL_MACHINE registry key
     // but this is ok since the installer / uninstaller will delete the
     // directory containing the file along with its contents after an update is
     // applied, on reinstall, and on uninstall.
     if (MoveFileEx(path, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
       LOG(("backup_discard: file renamed and will be removed on OS " \
            "reboot: " LOG_S, path));
     } else {
       LOG(("backup_discard: failed to schedule OS reboot removal of " \
            "file: " LOG_S, path));
     }
   }
 #else
   if (rv)
-    return WRITE_ERROR;
+    return WRITE_ERROR_DELETE_BACKUP;
 #endif
 
   return OK;
 }
 
 // Helper function for post-processing a temporary backup.
 static void backup_finish(const NS_tchar *path, int status)
 {
@@ -1004,31 +1004,31 @@ RemoveFile::Prepare()
   if (rv) {
     LOG(("failed to read file status info: " LOG_S ", err: %d", mFile,
          errno));
     return READ_ERROR;
   }
 
   if (!S_ISREG(fileInfo.st_mode)) {
     LOG(("path present, but not a file: " LOG_S, mFile));
-    return UNEXPECTED_FILE_OPERATION_ERROR;
+    return DELETE_ERROR_EXPECTED_FILE;
   }
 
   NS_tchar *slash = (NS_tchar *) NS_tstrrchr(mFile, NS_T('/'));
   if (slash) {
     *slash = NS_T('\0');
     rv = NS_taccess(mFile, W_OK);
     *slash = NS_T('/');
   } else {
     rv = NS_taccess(NS_T("."), W_OK);
   }
 
   if (rv) {
     LOG(("access failed: %d", errno));
-    return WRITE_ERROR;
+    return WRITE_ERROR_FILE_ACCESS_DENIED;
   }
 
   return OK;
 }
 
 int
 RemoveFile::Execute()
 {
@@ -1113,23 +1113,23 @@ RemoveDir::Prepare()
   if (rv) {
     LOG(("failed to read directory status info: " LOG_S ", err: %d", mDir,
          errno));
     return READ_ERROR;
   }
 
   if (!S_ISDIR(dirInfo.st_mode)) {
     LOG(("path present, but not a directory: " LOG_S, mDir));
-    return UNEXPECTED_FILE_OPERATION_ERROR;
+    return DELETE_ERROR_EXPECTED_DIR;
   }
 
   rv = NS_taccess(mDir, W_OK);
   if (rv) {
     LOG(("access failed: %d, %d", rv, errno));
-    return WRITE_ERROR;
+    return WRITE_ERROR_DIR_ACCESS_DENIED;
   }
 
   return OK;
 }
 
 int
 RemoveDir::Execute()
 {
@@ -1305,17 +1305,17 @@ PatchFile::LoadSourceFile(FILE* ofile)
     LOG(("LoadSourceFile: unable to stat destination file: " LOG_S ", " \
          "err: %d", mFile, errno));
     return READ_ERROR;
   }
 
   if (uint32_t(os.st_size) != header.slen) {
     LOG(("LoadSourceFile: destination file size %d does not match expected size %d",
          uint32_t(os.st_size), header.slen));
-    return UNEXPECTED_FILE_OPERATION_ERROR;
+    return LOADSOURCE_ERROR_WRONG_SIZE;
   }
 
   buf = (unsigned char *) malloc(header.slen);
   if (!buf)
     return UPDATER_MEM_ERROR;
 
   size_t r = header.slen;
   unsigned char *rb = buf;
@@ -1456,17 +1456,17 @@ PatchFile::Execute()
 #if defined(HAVE_POSIX_FALLOCATE)
   AutoFile ofile(ensure_open(mFile, NS_T("wb+"), ss.st_mode));
   posix_fallocate(fileno((FILE *)ofile), 0, header.dlen);
 #elif defined(XP_WIN)
   bool shouldTruncate = true;
   // Creating the file, setting the size, and then closing the file handle
   // lessens fragmentation more than any other method tested. Other methods that
   // have been tested are:
-  // 1. _chsize / _chsize_s reduced fragmentation but though not completely.
+  // 1. _chsize / _chsize_s reduced fragmentation though not completely.
   // 2. _get_osfhandle and then setting the size reduced fragmentation though
   //    not completely. There are also reports of _get_osfhandle failing on
   //    mingw.
   HANDLE hfile = CreateFileW(mFile,
                              GENERIC_WRITE,
                              0,
                              nullptr,
                              CREATE_ALWAYS,
@@ -1477,17 +1477,18 @@ PatchFile::Execute()
     if (SetFilePointer(hfile, header.dlen,
                        nullptr, FILE_BEGIN) != INVALID_SET_FILE_POINTER &&
         SetEndOfFile(hfile) != 0) {
       shouldTruncate = false;
     }
     CloseHandle(hfile);
   }
 
-  AutoFile ofile(ensure_open(mFile, shouldTruncate ? NS_T("wb+") : NS_T("rb+"), ss.st_mode));
+  AutoFile ofile(ensure_open(mFile, shouldTruncate ? NS_T("wb+") : NS_T("rb+"),
+                             ss.st_mode));
 #elif defined(XP_MACOSX)
   AutoFile ofile(ensure_open(mFile, NS_T("wb+"), ss.st_mode));
   // Modified code from FileUtils.cpp
   fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, header.dlen};
   // Try to get a continous chunk of disk space
   rv = fcntl(fileno((FILE *)ofile), F_PREALLOCATE, &store);
   if (rv == -1) {
     // OK, perhaps we are too fragmented, allocate non-continuous
@@ -1499,17 +1500,17 @@ PatchFile::Execute()
     ftruncate(fileno((FILE *)ofile), header.dlen);
   }
 #else
   AutoFile ofile(ensure_open(mFile, NS_T("wb+"), ss.st_mode));
 #endif
 
   if (ofile == nullptr) {
     LOG(("unable to create new file: " LOG_S ", err: %d", mFile, errno));
-    return WRITE_ERROR;
+    return WRITE_ERROR_OPEN_PATCH_FILE;
   }
 
 #ifdef XP_WIN
   if (!shouldTruncate) {
     fseek(ofile, 0, SEEK_SET);
   }
 #endif
 
@@ -1937,17 +1938,18 @@ ProcessReplaceRequest()
   NS_tsnprintf(destDir, sizeof(destDir)/sizeof(destDir[0]),
                NS_T("%s/Contents"), gInstallDirPath);
 #elif XP_WIN
   // Windows preserves the case of the file/directory names.  We use the
   // GetLongPathName API in order to get the correct case for the directory
   // name, so that if the user has used a different case when launching the
   // application, the installation directory's name does not change.
   NS_tchar destDir[MAXPATHLEN];
-  if (!GetLongPathNameW(gInstallDirPath, destDir, sizeof(destDir)/sizeof(destDir[0]))) {
+  if (!GetLongPathNameW(gInstallDirPath, destDir,
+                        sizeof(destDir)/sizeof(destDir[0]))) {
     return NO_INSTALLDIR_ERROR;
   }
 #else
   NS_tchar* destDir = gInstallDirPath;
 #endif
 
   NS_tchar tmpDir[MAXPATHLEN];
   NS_tsnprintf(tmpDir, sizeof(tmpDir)/sizeof(tmpDir[0]),
@@ -1985,16 +1987,18 @@ ProcessReplaceRequest()
          destDir, GetLastError(), rv));
 
     Sleep(100);
 
     rv = rename_file(destDir, tmpDir, true);
   }
 #endif
   if (rv) {
+    // The status file will have 'pending' written to it so there is no value in
+    // returning an error specific for this failure.
     LOG(("Moving destDir to tmpDir failed, err: %d", rv));
     return rv;
   }
 
   LOG(("Begin moving newDir (" LOG_S ") to destDir (" LOG_S ")",
        newDir, destDir));
   rv = rename_file(newDir, destDir, true);
 #ifdef XP_MACOSX
@@ -2008,16 +2012,18 @@ ProcessReplaceRequest()
   if (rv) {
     LOG(("Moving newDir to destDir failed, err: %d", rv));
     LOG(("Now, try to move tmpDir back to destDir"));
     ensure_remove_recursive(destDir);
     int rv2 = rename_file(tmpDir, destDir, true);
     if (rv2) {
       LOG(("Moving tmpDir back to destDir failed, err: %d", rv2));
     }
+    // The status file will be have 'pending' written to it so there is no value
+    // in returning an error specific for this failure.
     return rv;
   }
 
   LOG(("Now, remove the tmpDir"));
   rv = ensure_remove_recursive(tmpDir);
   if (rv) {
     LOG(("Removing tmpDir failed, err: %d", rv));
 #ifdef XP_WIN
@@ -2079,17 +2085,18 @@ ReadMARChannelIDs(const NS_tchar *path, 
 
   return result;
 }
 #endif
 
 static int
 GetUpdateFileName(NS_tchar *fileName, int maxChars)
 {
-#if defined(MOZ_WIDGET_GONK)  // If an update.link file exists, then it will contain the name
+#if defined(MOZ_WIDGET_GONK)
+  // If an update.link file exists, then it will contain the name
   // of the update file (terminated by a newline).
 
   NS_tchar linkFileName[MAXPATHLEN];
   NS_tsnprintf(linkFileName, sizeof(linkFileName)/sizeof(linkFileName[0]),
                NS_T("%s/update.link"), gPatchDirPath);
   AutoFile linkFile(NS_tfopen(linkFileName, NS_T("rb")));
   if (linkFile == nullptr) {
     NS_tsnprintf(fileName, maxChars,
@@ -2221,17 +2228,18 @@ UpdateThreadFunc(void *param)
     // updater application again in order to apply the update without
     // staging.
     // The MOZ_NO_REPLACE_FALLBACK environment variable is used to
     // bypass this fallback, and is used in the updater tests.
     // The only special thing which we should do here is to remove the
     // staged directory as it won't be useful any more.
     ensure_remove_recursive(gWorkingDirPath);
     WriteStatusFile(sUsingService ? "pending-service" : "pending");
-    putenv(const_cast<char*>("MOZ_PROCESS_UPDATES=")); // We need to use --process-updates again in the tests
+    // We need to use --process-updates again in the tests
+    putenv(const_cast<char*>("MOZ_PROCESS_UPDATES="));
     reportRealResults = false; // pretend success
   }
 
   if (reportRealResults) {
     if (rv) {
       LOG(("failed: %d", rv));
     }
     else {
@@ -2434,17 +2442,18 @@ int NS_main(int argc, NS_tchar **argv)
         LOG(("ioprio_set(%d,%d) failed: errno = %d",
              ioprioClass, ioprioLevel, errno));
       }
       FILE *fs = fopen("/proc/self/oom_score_adj", "w");
       if (fs) {
         fprintf(fs, "%d", oomScoreAdj);
         fclose(fs);
       } else {
-        LOG(("Unable to open /proc/self/oom_score_adj for writing, errno = %d", errno));
+        LOG(("Unable to open /proc/self/oom_score_adj for writing, errno = %d",
+             errno));
       }
     }
   }
 #endif
 
 #ifdef XP_WIN
   if (pid > 0) {
     HANDLE parent = OpenProcess(SYNCHRONIZE, false, (DWORD) pid);
@@ -2618,17 +2627,18 @@ int NS_main(int argc, NS_tchar **argv)
           useService = !unpromptedElevation;
         }
       }
 
       // Make sure the service registry entries for the instsallation path
       // are available.  If not don't use the service.
       if (useService) {
         WCHAR maintenanceServiceKey[MAX_PATH + 1];
-        if (CalculateRegistryPathFromFilePath(gInstallDirPath, maintenanceServiceKey)) {
+        if (CalculateRegistryPathFromFilePath(gInstallDirPath,
+                                              maintenanceServiceKey)) {
           HKEY baseKey = nullptr;
           if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                             maintenanceServiceKey, 0,
                             KEY_READ | KEY_WOW64_64KEY,
                             &baseKey) == ERROR_SUCCESS) {
             RegCloseKey(baseKey);
           } else {
             useService = testOnlyFallbackKeyExists;
@@ -2707,17 +2717,18 @@ int NS_main(int argc, NS_tchar **argv)
       // current user's session of this unelevated updater.exe the
       // current process is running as.
       // Note that we don't need to do this if we're just staging the update,
       // as the PostUpdate step runs when performing the replacing in that case.
       if (useService && !sStagedUpdate) {
         bool updateStatusSucceeded = false;
         if (IsUpdateStatusSucceeded(updateStatusSucceeded) &&
             updateStatusSucceeded) {
-          if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath, false, nullptr)) {
+          if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath, false,
+                                    nullptr)) {
             fprintf(stderr, "The post update process which runs as the user"
                     " for service update could not be launched.");
           }
         }
       }
 
       // If we didn't want to use the service at all, or if an update was
       // already happening, or launching the service command failed, then
@@ -2850,17 +2861,17 @@ int NS_main(int argc, NS_tchar **argv)
     gDestPath = destpath;
   }
 
   NS_tchar applyDirLongPath[MAXPATHLEN];
   if (!GetLongPathNameW(gWorkingDirPath, applyDirLongPath,
                         sizeof(applyDirLongPath)/sizeof(applyDirLongPath[0]))) {
     LOG(("NS_main: unable to find apply to dir: " LOG_S, gWorkingDirPath));
     LogFinish();
-    WriteStatusFile(WRITE_ERROR);
+    WriteStatusFile(WRITE_ERROR_APPLY_DIR_PATH);
     EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
     if (argc > callbackIndex) {
       LaunchCallbackApp(argv[5], argc - callbackIndex,
                         argv + callbackIndex, sUsingService);
     }
     return 1;
   }
 
@@ -2895,24 +2906,25 @@ int NS_main(int argc, NS_tchar **argv)
       ++p;
       bufferLeft--;
       *p = NS_T('\0');
       NS_tchar installDir[MAXPATHLEN];
       NS_tstrcpy(installDir, gInstallDirPath);
       size_t callbackPrefixLength = PathCommonPrefixW(argv[callbackIndex],
                                                       installDir,
                                                       nullptr);
-      NS_tstrncpy(p, argv[callbackIndex] + std::max(callbackPrefixLength, commonPrefixLength), bufferLeft);
+      NS_tstrncpy(p, argv[callbackIndex] + std::max(callbackPrefixLength,
+                  commonPrefixLength), bufferLeft);
       targetPath = buffer;
     }
     if (!GetLongPathNameW(targetPath, callbackLongPath,
                           sizeof(callbackLongPath)/sizeof(callbackLongPath[0]))) {
       LOG(("NS_main: unable to find callback file: " LOG_S, targetPath));
       LogFinish();
-      WriteStatusFile(WRITE_ERROR);
+      WriteStatusFile(WRITE_ERROR_CALLBACK_PATH);
       EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
       if (argc > callbackIndex) {
         LaunchCallbackApp(argv[5],
                           argc - callbackIndex,
                           argv + callbackIndex,
                           sUsingService);
       }
       return 1;
@@ -3182,17 +3194,17 @@ ActionList::Append(Action *action)
 int
 ActionList::Prepare()
 {
   // If the action list is empty then we should fail in order to signal that
   // something has gone wrong. Otherwise we report success when nothing is
   // actually done. See bug 327140.
   if (mCount == 0) {
     LOG(("empty action list"));
-    return UNEXPECTED_MAR_ERROR;
+    return MAR_ERROR_EMPTY_ACTION_LIST;
   }
 
   Action *a = mFirst;
   int i = 0;
   while (a) {
     int rv = a->Prepare();
     if (rv)
       return rv;
@@ -3292,17 +3304,18 @@ int add_dir_entries(const NS_tchar *dirp
         // Add the file to be removed to the ActionList.
         NS_tchar *quotedpath = get_quoted_path(foundpath);
         if (!quotedpath)
           return PARSE_ERROR;
 
         Action *action = new RemoveFile();
         rv = action->Parse(quotedpath);
         if (rv) {
-          LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d", quotedpath, rv));
+          LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d",
+               quotedpath, rv));
           return rv;
         }
 
         list->Append(action);
       }
     } while (FindNextFileW(hFindFile, &finddata) != 0);
 
     FindClose(hFindFile);
@@ -3310,17 +3323,18 @@ int add_dir_entries(const NS_tchar *dirp
       // Add the directory to be removed to the ActionList.
       NS_tchar *quotedpath = get_quoted_path(dirpath);
       if (!quotedpath)
         return PARSE_ERROR;
 
       Action *action = new RemoveDir();
       rv = action->Parse(quotedpath);
       if (rv)
-        LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d", quotedpath, rv));
+        LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d",
+             quotedpath, rv));
       else
         list->Append(action);
     }
   }
 
   return rv;
 }