Bug 872206 - Part 2 -Use CrashMonitor to identify crashes in Metro for sending a SHUTDOWN_OK telemetry probe. r=mbrubeck
authorMarina Samuel <msamuel@mozilla.com>
Wed, 12 Feb 2014 12:59:16 -0500
changeset 168434 77e7f75b502d7f0dc21377d7d358d8002096e5e0
parent 168433 c0ea0b4d69f7750002c5bed54219f7296f2536ac
child 168435 ce6caf543408184d1ccdeac576ab3278a3d3648a
push id26204
push userkwierso@gmail.com
push dateThu, 13 Feb 2014 00:26:33 +0000
treeherdermozilla-central@7920df861c8a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs872206
milestone30.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 872206 - Part 2 -Use CrashMonitor to identify crashes in Metro for sending a SHUTDOWN_OK telemetry probe. r=mbrubeck
browser/metro/components/SessionStore.js
--- a/browser/metro/components/SessionStore.js
+++ b/browser/metro/components/SessionStore.js
@@ -11,16 +11,19 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/WindowsPrefSync.jsm");
 
 #ifdef MOZ_CRASHREPORTER
 XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
   "@mozilla.org/xre/app-info;1", "nsICrashReporter");
 #endif
 
+XPCOMUtils.defineLazyModuleGetter(this, "CrashMonitor",
+  "resource://gre/modules/CrashMonitor.jsm");
+
 XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
   "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
 
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
@@ -71,16 +74,35 @@ SessionStore.prototype = {
 
     try {
       UITelemetry.addSimpleMeasureFunction("metro-tabs",
                                           this._getTabStats.bind(this));
     } catch (ex) {
       // swallow exception that occurs if metro-tabs measure is already set up
     }
 
+    CrashMonitor.previousCheckpoints.then(checkpoints => {
+      let previousSessionCrashed = false;
+
+      if (checkpoints) {
+        // If the previous session finished writing the final state, we'll
+        // assume there was no crash.
+        previousSessionCrashed = !checkpoints["sessionstore-final-state-write-complete"];
+      } else {
+        // If no checkpoints are saved, this is the first run with CrashMonitor or the
+        // metroSessionCheckpoints file was corrupted/deleted, so fallback to defining
+        // a crash as init-ing with an unexpected previousExecutionState
+        // 1 == RUNNING, 2 == SUSPENDED
+        previousSessionCrashed = Services.metro.previousExecutionState == 1 ||
+          Services.metro.previousExecutionState == 2;
+      }
+
+      Services.telemetry.getHistogramById("SHUTDOWN_OK").add(!previousSessionCrashed);
+    });
+
     try {
       let shutdownWasUnclean = false;
 
       if (this._sessionFileBackup.exists()) {
         this._sessionFileBackup.remove(false);
         shutdownWasUnclean = true;
       }
 
@@ -286,18 +308,18 @@ SessionStore.prototype = {
         observerService.removeObserver(this, "quit-application-granted");
         observerService.removeObserver(this, "quit-application");
         observerService.removeObserver(this, "reset-telemetry-vars");
 
         // If a save has been queued, kill the timer and save state now
         if (this._saveTimer) {
           this._saveTimer.cancel();
           this._saveTimer = null;
-          this.saveState();
         }
+        this.saveState();
         break;
       case "browser:purge-session-history": // catch sanitization
         this._clearDisk();
 
         // If the browser is shutting down, simply return after clearing the
         // session data on disk as this notification fires after the
         // quit-application notification so the browser is about to exit.
         if (this._loadState == STATE_QUITTING)
@@ -639,16 +661,19 @@ SessionStore.prototype = {
     // Obtain a converter to convert our data to a UTF-8 encoded input stream.
     let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
     converter.charset = "UTF-8";
 
     // Asynchronously copy the data to the file.
     let istream = converter.convertToInputStream(aData);
     NetUtil.asyncCopy(istream, ostream, function(rc) {
       if (Components.isSuccessCode(rc)) {
+        if (Services.startup.shuttingDown) {
+          Services.obs.notifyObservers(null, "sessionstore-final-state-write-complete", "");
+        }
         Services.obs.notifyObservers(null, "sessionstore-state-write-complete", "");
       }
     });
   },
 
   _updateCrashReportURL: function ss_updateCrashReportURL(aWindow) {
 #ifdef MOZ_CRASHREPORTER
     try {