Bug 801809 - Add hooks for b2g crash reporter UI. r=fabrice
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Mon, 29 Oct 2012 11:18:50 -0700
changeset 111855 c0e42b3b43e322a0f8f3f9951aeaf455c30ec40a
parent 111854 70d9ba6b84f885bb2a8aadce246b75e8f650fdc3
child 111856 9057eef5920abebc005e088749b57240285266da
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersfabrice
bugs801809
milestone19.0a1
Bug 801809 - Add hooks for b2g crash reporter UI. r=fabrice
b2g/app/b2g.js
b2g/chrome/content/settings.js
b2g/chrome/content/shell.js
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -185,17 +185,19 @@ pref("dom.ipc.plugins.enabled", true);
 pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
 pref("app.releaseNotesURL", "http://www.mozilla.com/%LOCALE%/b2g/%VERSION%/releasenotes/");
 pref("app.support.baseURL", "http://support.mozilla.com/b2g");
 pref("app.feedbackURL", "http://input.mozilla.com/feedback/");
 pref("app.privacyURL", "http://www.mozilla.com/%LOCALE%/m/privacy.html");
 pref("app.creditsURL", "http://www.mozilla.org/credits/");
 pref("app.featuresURL", "http://www.mozilla.com/%LOCALE%/b2g/features/");
 pref("app.faqURL", "http://www.mozilla.com/%LOCALE%/b2g/faq/");
+pref("app.showCrashDialog", true);
 // Whether we want to report crashes (headless)
+//XXX Remove this pref when bug 801932 is fixed
 pref("app.reportCrashes", true);
 
 // Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
 pref("security.alternate_certificate_error_page", "certerror");
 
 pref("security.warn_viewing_mixed", false); // Warning is disabled.  See Bug 616712.
 
 // Override some named colors to avoid inverse OS themes
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -176,8 +176,20 @@ SettingsListener.observe('debug.log-anim
 SettingsListener.observe('debug.dev-mode', false, function(value) {
   Services.prefs.setBoolPref('dom.mozApps.dev_mode', value);
 });
 
 // =================== Privacy ====================
 SettingsListener.observe('privacy.donottrackheader.enabled', false, function(value) {
   Services.prefs.setBoolPref('privacy.donottrackheader.enabled', value);
 });
+
+// =================== Crash Reporting ====================
+SettingsListener.observe('app.reportCrashes', 'ask', function(value) {
+  if (value == 'always') {
+    Services.prefs.setBoolPref('app.reportCrashes', true);
+  } else if (value == 'never') {
+    Services.prefs.setBoolPref('app.reportCrashes', false);
+  } else {
+    Services.prefs.clearUserPref('app.reportCrashes');
+  }
+});
+
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -74,31 +74,53 @@ var shell = {
 
   reportCrash: function shell_reportCrash(aCrashID) {
     let crashID = aCrashID;
     try {
       if (crashID == undefined || crashID == "")
         crashID = Cc["@mozilla.org/xre/app-info;1"]
                     .getService(Ci.nsIXULRuntime).lastRunCrashID;
     } catch(e) { }
-    if (Services.prefs.getBoolPref('app.reportCrashes') &&
-        crashID) {
+
+    // Bail if there isn't a valid crashID.
+    if (!crashID) {
+      return;
+    }
 
-      Services.obs.addObserver(function observer(subject, topic, state) {
-          if (topic != "network:offline-status-changed")
-            return;
-          if (state == 'online') {
-            shell.CrashSubmit.submit(crashID);
-            Services.obs.removeObserver(observer, topic);
-          }
-        }
-        , "network:offline-status-changed", false);
+    try {
+      // Check to see if the user has set a pref to always/never send
+      // crash reports. This will throw if the pref hasn't been set.
+      if (Services.prefs.getBoolPref("app.reportCrashes")) {
+        this.submitCrash(crashID);
+      }
+      // Show a banner letting the user know there was a crash.
+      this.sendChromeEvent({ type: "crash-banner" });
+    } catch (e) {
+      // Show a dialog only the first time there's a crash to report.
+      if (Services.prefs.getBoolPref("app.showCrashDialog")) {
+        Services.prefs.setBoolPref("app.showCrashDialog", false);
+        this.sendChromeEvent({ type: "crash-dialog", crashID: crashID });
+      } else {
+        // If the user hasn't set a pref, but we've already shown
+        // a dialog, show a banner with a "Report" button.
+        this.sendChromeEvent({ type: "crash-banner", crashID: crashID });
+      }
     }
   },
 
+  // This function submits a crash when we're online.
+  submitCrash: function shell_submitCrash(aCrashID) {
+    Services.obs.addObserver(function observer(subject, topic, state) {
+      if (state == 'online') {
+        shell.CrashSubmit.submit(aCrashID);
+        Services.obs.removeObserver(observer, topic);
+      }
+    }, "network:offline-status-changed", false);
+  },
+
   get contentBrowser() {
     delete this.contentBrowser;
     return this.contentBrowser = document.getElementById('homescreen');
   },
 
   get homeURL() {
     try {
       let homeSrc = Services.env.get('B2G_HOMESCREEN');
@@ -766,26 +788,34 @@ window.addEventListener('ContentStart', 
         error: String(e)
       });
     }
   });
 });
 
 (function contentCrashTracker() {
   Services.obs.addObserver(function(aSubject, aTopic, aData) {
-      let cs = Cc["@mozilla.org/consoleservice;1"]
-                 .getService(Ci.nsIConsoleService);
       let props = aSubject.QueryInterface(Ci.nsIPropertyBag2);
       if (props.hasKey("abnormal") && props.hasKey("dumpID")) {
         shell.reportCrash(props.getProperty("dumpID"));
       }
     },
     "ipc:content-shutdown", false);
 })();
 
+// Listen for crashes submitted through the crash reporter UI.
+window.addEventListener('ContentStart', function cr_onContentStart() {
+  let content = shell.contentBrowser.contentWindow;
+  content.addEventListener("mozContentEvent", function cr_onMozContentEvent(e) {
+    if (e.detail.type == "submit-crash") {
+      shell.submitCrash(e.detail.crashID);
+    }
+  });
+});
+
 window.addEventListener('ContentStart', function update_onContentStart() {
   let updatePrompt = Cc["@mozilla.org/updates/update-prompt;1"]
                        .createInstance(Ci.nsIUpdatePrompt);
 
   let content = shell.contentBrowser.contentWindow;
   content.addEventListener("mozContentEvent", updatePrompt.wrappedJSObject);
 });