Bug 688083 - Plugin Crash: Sync Submit Report Checkbox With Pref Between Instances. r=dolske
authorFelix Fung <ffung@mozilla.com>
Mon, 03 Oct 2011 13:26:08 -0700
changeset 79276 fc2cf14697f84ca2d3fe3683dc3178ed18f71337
parent 79275 5df0d42376702f49f6912d8a019f626a2241eee7
child 79277 e60d3779a3b83c67a748244fd925a0269a13d612
push id21383
push usermleibovic@mozilla.com
push dateThu, 27 Oct 2011 18:30:56 +0000
treeherdermozilla-central@322354df233d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske
bugs688083
milestone10.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 688083 - Plugin Crash: Sync Submit Report Checkbox With Pref Between Instances. r=dolske
browser/base/content/browser.js
toolkit/crashreporter/nsExceptionHandler.cpp
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7056,18 +7056,17 @@ var gPluginHandler = {
   // Crashed-plugin event listener. Called for every instance of a
   // plugin in content.
   pluginInstanceCrashed: function (plugin, aEvent) {
     // Ensure the plugin and event are of the right type.
     if (!(aEvent instanceof Ci.nsIDOMDataContainerEvent))
       return;
 
     let submittedReport = aEvent.getData("submittedCrashReport");
-    let doPrompt        = true; // XXX followup for .getData("doPrompt");
-    let submitReports   = true; // XXX followup for .getData("submitReports");
+    let doPrompt        = true; // XXX followup to get via gCrashReporter
     let pluginName      = aEvent.getData("pluginName");
     let pluginFilename  = aEvent.getData("pluginFilename");
     let pluginDumpID    = aEvent.getData("pluginDumpID");
     let browserDumpID   = aEvent.getData("browserDumpID");
 
     // Remap the plugin name to a more user-presentable form.
     pluginName = this.makeNicePluginName(pluginName, pluginFilename);
 
@@ -7075,75 +7074,99 @@ var gPluginHandler = {
 
     //
     // Configure the crashed-plugin placeholder.
     //
     let doc = plugin.ownerDocument;
     let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
     let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
 #ifdef MOZ_CRASHREPORTER
+    let submitReports = gCrashReporter.submitReports;
     let status;
 
     // Determine which message to show regarding crash reports.
     if (submittedReport) { // submitReports && !doPrompt, handled in observer
       status = "submitted";
     }
     else if (!submitReports && !doPrompt) {
       status = "noSubmit";
     }
     else { // doPrompt
+      // link submit checkbox to gCrashReporter submitReports preference
       let submitChk = doc.getAnonymousElementByAttribute(
                         plugin, "class", "pleaseSubmitCheckbox");
       submitChk.checked = submitReports;
+      submitChk.addEventListener("click", function() {
+        gCrashReporter.submitReports = this.checked;
+      }, false);
+
       status = "please";
     }
 
     // If we don't have a minidumpID, we can't (or didn't) submit anything.
     // This can happen if the plugin is killed from the task manager.
     if (!pluginDumpID) {
       status = "noReport";
     }
 
     statusDiv.setAttribute("status", status);
 
     let bottomLinks = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgBottomLinks");
     bottomLinks.style.display = "block";
     let helpIcon = doc.getAnonymousElementByAttribute(plugin, "class", "helpIcon");
     this.addLinkClickCallback(helpIcon, "openHelpPage");
 
-    // If we're showing the link to manually trigger report submission, we'll
-    // want to be able to update all the instances of the UI for this crash to
-    // show an updated message when a report is submitted.
+    // If we're showing the checkbox to trigger report submission, we'll want
+    // to be able to update all the instances of the UI for this crash when
+    // one instance of the checkbox is modified or the status is updated.
     if (doPrompt) {
+      let submitReportsPrefObserver = {
+        QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+                                               Ci.nsISupportsWeakReference]),
+        observe : function(subject, topic, data) {
+          let submitChk = doc.getAnonymousElementByAttribute(
+                            plugin, "class", "pleaseSubmitCheckbox");
+          submitChk.checked = gCrashReporter.submitReports;
+        },
+        handleEvent : function(event) {
+            // Not expected to be called, just here for the closure.
+        }
+      };
+
       let observer = {
         QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                                Ci.nsISupportsWeakReference]),
         observe : function(subject, topic, data) {
           let propertyBag = subject;
           if (!(propertyBag instanceof Ci.nsIPropertyBag2))
             return;
           // Ignore notifications for other crashes.
           if (propertyBag.get("minidumpID") != pluginDumpID)
             return;
           statusDiv.setAttribute("status", data);
         },
 
         handleEvent : function(event) {
             // Not expected to be called, just here for the closure.
         }
-      }
+      };
 
       // Use a weak reference, so we don't have to remove it...
       Services.obs.addObserver(observer, "crash-report-status", true);
+      Services.obs.addObserver(
+        submitReportsPrefObserver, "submit-reports-pref-changed", true);
+
       // ...alas, now we need something to hold a strong reference to prevent
       // it from being GC. But I don't want to manually manage the reference's
       // lifetime (which should be no greater than the page).
       // Clever solution? Use a closure with an event listener on the document.
       // When the doc goes away, so do the listener references and the closure.
       doc.addEventListener("mozCleverClosureHack", observer, false);
+      doc.addEventListener(
+        "mozCleverClosureHack", submitReportsPrefObserver, false);
     }
 #endif
 
     let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgCrashed");
     crashText.textContent = messageString;
 
     let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
 
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+  /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -33,17 +33,18 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/dom/CrashReporterChild.h"
-
+#include "mozilla/Services.h"
+#include "nsIObserverService.h"
 #include "mozilla/Util.h"
 
 #include "nsXULAppAPI.h"
 
 #include "nsExceptionHandler.h"
 #include "nsThreadUtils.h"
 
 #if defined(XP_WIN32)
@@ -1546,17 +1547,31 @@ static nsresult PrefSubmitReports(bool* 
 
 nsresult GetSubmitReports(bool* aSubmitReports)
 {
     return PrefSubmitReports(aSubmitReports, false);
 }
 
 nsresult SetSubmitReports(bool aSubmitReports)
 {
-    return PrefSubmitReports(&aSubmitReports, true);
+    nsresult rv;
+
+    nsCOMPtr<nsIObserverService> obsServ =
+      mozilla::services::GetObserverService();
+    if (!obsServ) {
+      return NS_ERROR_FAILURE;
+    }
+
+    rv = PrefSubmitReports(&aSubmitReports, true);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    obsServ->NotifyObservers(nsnull, "submit-reports-pref-changed", nsnull);
+    return NS_OK;
 }
 
 // The "pending" dir is Crash Reports/pending, from which minidumps
 // can be submitted
 static bool
 GetPendingDir(nsILocalFile** dir)
 {
   nsCOMPtr<nsIProperties> dirSvc =