Bug 853694 - Cannot send crash reports for click-to-play plugins. r=jaws
☠☠ backed out by 2d46b79963e8 ☠ ☠
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Sat, 19 Oct 2013 17:15:18 +0200
changeset 165255 14789271ad201a947a2f6b2dbebe1415f7eb85ff
parent 165254 77f70432fdcd1c525d57c6ef8f558cc155869e1b
child 165256 5e8f8322f8fd6564accfeb61c960e3ed7fbb2a10
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs853694
milestone27.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 853694 - Cannot send crash reports for click-to-play plugins. r=jaws
browser/base/content/browser-plugins.js
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_CTP_crashreporting.js
browser/base/content/test/general/plugin_big.html
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -799,16 +799,20 @@ var gPluginHandler = {
     let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
 
     for (let plugin of plugins) {
       plugin.QueryInterface(Ci.nsIObjectLoadingContent);
       // canActivatePlugin will return false if this isn't a known plugin type,
       // so the pluginHost.getPermissionStringForType call is protected
       if (gPluginHandler.canActivatePlugin(plugin) &&
           aPluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
+        let overlay = this.getPluginUI(plugin, "main");
+        if (overlay) {
+          overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
+        }
         plugin.playPlugin();
       }
     }
   },
 
   _showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPrimaryPlugin) {
     let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
 
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -42,16 +42,17 @@ support-files =
   head.js
   healthreport_testRemoteCommands.html
   moz.png
   offlineQuotaNotification.cacheManifest
   offlineQuotaNotification.html
   page_style_sample.html
   plugin_add_dynamically.html
   plugin_alternate_content.html
+  plugin_big.html
   plugin_both.html
   plugin_both2.html
   plugin_bug744745.html
   plugin_bug749455.html
   plugin_bug752516.html
   plugin_bug787619.html
   plugin_bug797677.html
   plugin_bug820497.html
@@ -73,16 +74,17 @@ support-files =
   test_bug462673.html
   test_bug628179.html
   test_bug839103.html
   test_wyciwyg_copying.html
   title_test.svg
   video.ogg
   zoom_test.html
 
+[browser_CTP_crashreporting.js]
 [browser_CTP_data_urls.js]
 [browser_CTP_drag_drop.js]
 [browser_CTP_iframe.js]
 [browser_CTP_nonplugins.js]
 [browser_CTP_resize.js]
 [browser_URLBarSetURI.js]
 [browser_aboutHealthReport.js]
 [browser_aboutHome.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_CTP_crashreporting.js
@@ -0,0 +1,132 @@
+/* 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/. */
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
+const gTestRoot = getRootDirectory(gTestPath);
+var gTestBrowser = null;
+
+// Test that plugin crash submissions still work properly after
+// click-to-play activation.
+
+function test() {
+  waitForExplicitFinish();
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+
+  // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
+  // crash reports.  This test needs them enabled.  The test also needs a mock
+  // report server, and fortunately one is already set up by toolkit/
+  // crashreporter/test/Makefile.in.  Assign its URL to MOZ_CRASHREPORTER_URL,
+  // which CrashSubmit.jsm uses as a server override.
+  let env = Cc["@mozilla.org/process/environment;1"].
+            getService(Components.interfaces.nsIEnvironment);
+  let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
+  let serverURL = env.get("MOZ_CRASHREPORTER_URL");
+  env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
+  env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
+
+  let tab = gBrowser.loadOneTab("about:blank", { inBackground: false });
+  gTestBrowser = gBrowser.getBrowserForTab(tab);
+  gTestBrowser.addEventListener("PluginCrashed", onCrash, false);
+  gTestBrowser.addEventListener("load", onPageLoad, true);
+  Services.obs.addObserver(onSubmitStatus, "crash-report-status", false);
+
+  registerCleanupFunction(function cleanUp() {
+    env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
+    env.set("MOZ_CRASHREPORTER_URL", serverURL);
+    gTestBrowser.removeEventListener("PluginCrashed", onCrash, false);
+    gTestBrowser.removeEventListener("load", onPageLoad, true);
+    Services.obs.removeObserver(onSubmitStatus, "crash-report-status");
+    gBrowser.removeCurrentTab();
+  });
+
+  gTestBrowser.contentWindow.location = gTestRoot + "plugin_big.html";
+}
+function onPageLoad() {
+  // Force the plugins binding to attach as layout is async.
+  let plugin = gTestBrowser.contentDocument.getElementById("test");
+  plugin.clientTop;
+  executeSoon(afterBindingAttached);
+}
+
+function afterBindingAttached() {
+  let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(popupNotification, "Should have a click-to-play notification");
+
+  let plugin = gTestBrowser.contentDocument.getElementById("test");
+  let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Plugin should not be activated");
+
+  // Simulate clicking the "Allow Always" button.
+  popupNotification.reshow();
+  PopupNotifications.panel.firstChild._primaryButton.click();
+
+  let condition = function() objLoadingContent.activated;
+  waitForCondition(condition, pluginActivated, "Waited too long for plugin to activate");
+}
+
+function pluginActivated() {
+  let plugin = gTestBrowser.contentDocument.getElementById("test");
+  try {
+    plugin.crash();
+  } catch (e) {
+    // The plugin crashed in the above call, an exception is expected.
+  }
+}
+
+function onCrash() {
+  try {
+    let plugin = gBrowser.contentDocument.getElementById("test");
+    let elt = gPluginHandler.getPluginUI.bind(gPluginHandler, plugin);
+    let style =
+      gBrowser.contentWindow.getComputedStyle(elt("pleaseSubmit"));
+    is(style.display, "block", "Submission UI visibility should be correct");
+
+    elt("submitComment").value = "a test comment";
+    is(elt("submitURLOptIn").checked, true, "URL opt-in should default to true");
+    EventUtils.synthesizeMouseAtCenter(elt("submitURLOptIn"), {}, gTestBrowser.contentWindow);
+    EventUtils.synthesizeMouseAtCenter(elt("submitButton"), {}, gTestBrowser.contentWindow);
+    // And now wait for the submission status notification.
+  }
+  catch (err) {
+    failWithException(err);
+  }
+}
+
+function onSubmitStatus(subj, topic, data) {
+  try {
+    // Wait for success or failed, doesn't matter which.
+    if (data != "success" && data != "failed")
+      return;
+
+    let extra = getPropertyBagValue(subj.QueryInterface(Ci.nsIPropertyBag),
+                                    "extra");
+    ok(extra instanceof Ci.nsIPropertyBag, "Extra data should be property bag");
+
+    let val = getPropertyBagValue(extra, "PluginUserComment");
+    is(val, "a test comment",
+       "Comment in extra data should match comment in textbox");
+
+    val = getPropertyBagValue(extra, "PluginContentURL");
+    ok(val === undefined,
+       "URL should be absent from extra data when opt-in not checked");
+  }
+  catch (err) {
+    failWithException(err);
+  }
+  finish();
+}
+
+function getPropertyBagValue(bag, key) {
+  try {
+    var val = bag.getProperty(key);
+  }
+  catch (e if e.result == Cr.NS_ERROR_FAILURE) {}
+  return val;
+}
+
+function failWithException(err) {
+  ok(false, "Uncaught exception: " + err + "\n" + err.stack);
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/plugin_big.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+<embed id="test" style="width: 500px; height: 500px" type="application/x-test">
+</body>
+</html>