Bug 899347 - Make click-to-play work in e10s
GWAERRRR - there have been changes in browser-plugins since mbrubeck
worked on this stuff. The patch doesn't apply cleanly, and… well, I
don't want to just clobber everything.
So - I need to figure out what's changed since mbrubeck worked on this
stuff, and then see what in mbrubeck's patch I need to modify in order
for it all to keep working.
mbrubeck posted his patch around July 1st. Commits to browser-plugins around that time:
Birunthan Mohanathas - Bug 994708 - Part 2: Record submission event for plugin crashes. r=gps
This is pretty straight forward - it's just decorating the crash submission with the plugin process type.
Felipe Gomes - Bug 1009760 - Support displaying of crash notification for GMP plugins. r=gfritzsche
This one… is more complicated. GMP =
GeckoMediaPlugins
. These are 3rd party codecs, EME and CDMs.
So we've added a new type of plugin… and felipe added support for showing when they crash. Simple enough.
Let's take a closer look at the patch:
This reorganized a number of things in browser-plugins.js. Oooh! and it added a test. Good.
Georg Fritzsche - Bug 1043531 - Let frontend deal properly with PluginCrashed without a browser dump id. r=ttaubert
This seems pretty straight forward… not worried about this one.
Georg Fritzsche - Bug 1045500 - Skip processing the plugin name for
plugin crashes in the front-end for GMP plugins. r=ttaubert
Also pretty straight forward…
Birunthan Mohanathas - Bug 972237 - Fix missing plugin overlay with some zoom levels and add test. r=mikedeboer
This seems also straight forward - and changes how the plugin overlay works with zoom levels. And its got a test!!
So it's felipe's patch in bug 1009760 that I need to integrate. Now let's look and see what mbrubeck's patch did.
Adds an initialize function that adds message listeners to all sorts of plugin messages.
Adds an "_unremotePrincipal" function that will take some CPOW'd
principal or object with principal properties, and turn it into a real
nsIPrincipal in the chrome process.
The event handler is removed, and I'm guessing it gets moved into
content.js. (Well, kinda - it gets moved to PluginContent.jsm, which is
imported into content.js).
Handlers for click-to-play get removed, and again, I'm guessing it gets moved to content.js. (Same as above).
Ahhh, interesting - so mbrubeck copied
browser/base/content/browser-plugins to
browser/modules/PluginContent.jsm, and then did a ton of mods on it. I
guess that helps preserve history instead of a manual copy paste.
I wonder if maybe this would be a lot simpler if I updated my tree
back to when mbrubeck was working on this, applied the patch, and then
attempted to rebase it on tip?
Let's try that.
Hm… seems to have kinda worked. handleEvent seems to have diverged
quite a bit… I wonder if mbrubeck did some cleanup in here…
I… I kinda have stuff working kinda. For non-e10s, anyway. The crashinfobar test shows an info bar. That's good.
The notification bar isn't being detected in the test. Why? Because the
frame script hears the event, fires an async message, but after it
fires it, the event keeps bubbling up and the test expects the
notification to appear once it sees the event. When the event is done
bubbling, that's when the message is handled and the notification bar is
displayed.
So we've changed the order of events. Again. So I need a way of waiting
for the message to be handled before checking for the existence of the
notification.
Is there prior art for waiting for a notification? It's unfortunate
that it doesn't seem to emit events on showing… hm - I see several
instances of us using waitForCondition for this sort of thing. I used
it, and that seemed to fix that test.
I'm looking at
browser/base/content/test/plugins/browser_CTP_crashreporting.js now,
and it looks like this one is busted because it attempts to read
information about the content - like, it tests style attributes,
checkbox values, etc.
browser_CTP_crashreporting.js and browser_pluginCrashCommentAndURL.js
I'm actually finding only two instances of this occurring - one in
browser_CTP_crashreporting.js and browser_pluginCrashCommentAndURL.js.
Here are the two usages:
function onCrash() {
try {
let plugin = gBrowser.contentDocument.getElementById("plugin");
let elt = gPluginHandler.getPluginUI.bind(gPluginHandler, plugin);
let style =
gBrowser.contentWindow.getComputedStyle(elt("pleaseSubmit"));
is(style.display,
currentRun.shouldSubmissionUIBeVisible ? "block" : "none",
"Submission UI visibility should be correct");
if (!currentRun.shouldSubmissionUIBeVisible) {
// Done with this run.
doNextRun();
return;
}
elt("submitComment").value = currentRun.comment;
elt("submitURLOptIn").checked = currentRun.urlOptIn;
elt("submitButton").click();
// And now wait for the submission status notification.
}
catch (err) {
failWithException(err);
doNextRun();
}
}
try {
let plugin = gBrowser.contentDocument.getElementById("plugin");
let elt = gPluginHandler.getPluginUI.bind(gPluginHandler, plugin);
let style =
gBrowser.contentWindow.getComputedStyle(elt("pleaseSubmit"));
is(style.display,
currentRun.shouldSubmissionUIBeVisible ? "block" : "none",
"Submission UI visibility should be correct");
if (!currentRun.shouldSubmissionUIBeVisible) {
// Done with this run.
doNextRun();
return;
}
elt("submitComment").value = currentRun.comment;
elt("submitURLOptIn").checked = currentRun.urlOptIn;
elt("submitButton").click();
// And now wait for the submission status notification.
}
catch (err) {
failWithException(err);
doNextRun();
}
}
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);
}
}
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);
}
}
I think instead of this, the content should have a frame script
injected that detects onCrash, and then messages these values to the
parent. Instead of listening for onCrash in the parent, we listen for
the message, and then perform the test with what gets passed up to us.
Ok, so we have a plan there.
browser_CTP_data_urls.js
So it's test3a that's failing out, because apparently:
let condition = function() objLoadingContent.activated;
waitForCondition(condition, test3b, "Test 3a, Waited too long for plugin to activate");
waitForCondition(condition, test3b, "Test 3a, Waited too long for plugin to activate");
This condition never gets to true… hrm. So what's happening is that the plugin is actually _not_ activating.
Ah… I'm getting this in PluginContent.jsm in
updateNotificationUI:
let contentWindow = this.global.content;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
contentWindow is null.
Stack to call that function is:
PluginContent.prototype.updateNotificationUI@resource:///modules/PluginContent.jsm:749:115
PluginContent.prototype.receiveMessage/<@resource:///modules/PluginContent.jsm:57:26
PluginContent.prototype.receiveMessage/<@resource:///modules/PluginContent.jsm:57:26
setTimeout_timer@resource://gre/modules/Timer.jsm:30:5
and that setTimeout timer is set in receiveMessage as:
case "BrowserPlugins:NotificationShown":
setTimeout(() => this.updateNotificationUI(), 0);
break;
setTimeout(() => this.updateNotificationUI(), 0);
break;
So we've received a BrowserPlugins:NotificationShown, but content is null. How can that happen?
Where are
PluginContent's constructed? How can it be constructed with a global that has no content?
Created in
browser/base/content/content.js…
// TODO: Load this lazily so the JSM is run only if a relevant event/message fires.
let pluginContent = new PluginContent(global);
let pluginContent = new PluginContent(global);
Waaaaait - this contentWindow stuff might be a red herring.
"Allow Now" and "Allow and Remember" are the panel buttons in test3a
without my patch. But with my patch, it's "Block plugin" and "Continue
Allowing".
So we end up clicking "Block plugin", when we should be clicking "Allow
now". Ah hah. So behaviour has changed - something is clearly busted.
Where and when do we choose these two sets of options? urlbarBindings.xml seems to be where the panel is implemented.
The translation keys we want are pluginActivateNow.label
and pluginActivateAlways.label, but what we got
were pluginBlockNow.label and pluginContinue.label.
So my current patch makes us enter this block:
if (action.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
When we should be entering the else down below. Confirm? Yes, that's
exactly what's happening. For some reason, my patch makes it so that the
front-end thinks that the plugin instance in the content process is
already active.
Stack for entering _setupSingleState in bad case:
42 INFO _setupSingleState entered. _setupSingleState@chrome://browser/content/urlbarBindings.xml:1714:50
43 INFO _setState@chrome://browser/content/urlbarBindings.xml:1671:13
44 INFO click-to-play-plugins-notification_XBL_Constructor@chrome://browser/content/urlbarBindings.xml:1654:13
45 INFO PopupNotifications_refreshPanel/<@resource://gre/modules/PopupNotifications.jsm:597:7
46 INFO PopupNotifications_refreshPanel@resource://gre/modules/PopupNotifications.jsm:535:1
47 INFO PopupNotifications_showPanel@resource://gre/modules/PopupNotifications.jsm:617:5
48 INFO PopupNotifications_update@resource://gre/modules/PopupNotifications.jsm:699:7
49 INFO PopupNotifications_reshowNotifications@resource://gre/modules/PopupNotifications.jsm:812:5
50 INFO Notification.prototype.reshow@resource://gre/modules/PopupNotifications.jsm:93:5
51 INFO test3a@chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_data_urls.js:167:3
52 INFO testScope/test_executeSoon/<.run@chrome://mochikit/content/browser-test.js:805:9
43 INFO _setState@chrome://browser/content/urlbarBindings.xml:1671:13
44 INFO click-to-play-plugins-notification_XBL_Constructor@chrome://browser/content/urlbarBindings.xml:1654:13
45 INFO PopupNotifications_refreshPanel/<@resource://gre/modules/PopupNotifications.jsm:597:7
46 INFO PopupNotifications_refreshPanel@resource://gre/modules/PopupNotifications.jsm:535:1
47 INFO PopupNotifications_showPanel@resource://gre/modules/PopupNotifications.jsm:617:5
48 INFO PopupNotifications_update@resource://gre/modules/PopupNotifications.jsm:699:7
49 INFO PopupNotifications_reshowNotifications@resource://gre/modules/PopupNotifications.jsm:812:5
50 INFO Notification.prototype.reshow@resource://gre/modules/PopupNotifications.jsm:93:5
51 INFO test3a@chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_data_urls.js:167:3
52 INFO testScope/test_executeSoon/<.run@chrome://mochikit/content/browser-test.js:805:9
Ok,
showClickToPlayNotification seems to get the same bogus value for the Test plugin…
I think the content process is sending up the wrong data for the
fallback type for the plugin. showClickToPlayNotification gets its
information from the content process via
the PluginContent:ShowClickToPlayNotification message.
Ah, ok - so it looks like the instance of PluginContent for the window
holds on to pluginData, and that information doesn't get cleared. The
lifetime of that data needs to be thought through more. It looks like
pre-e10s ties the lifetime of this information to the lifetime of a
notification… and I think it dies once the notification closes. Let's
check.
Yep, that's the case. I've hooked up a listener for the notification
removed event which sends a message to the child, which clears the
cache. Test now passes.
browser_CTP_drag_drop.js
This is what we get when we run the test:
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:part1:32
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:handleEvent:27
chrome://mozapps/content/plugins/pluginProblem.xml:pluginProblem_XBL_Constructor:83
null:null:0
TEST-INFO | expected PASS
60 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Waited too long for click-to-play notification -
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:33
null:null:0
TEST-INFO | expected PASS
61 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Should have a click-to-play notification in the tab in the new window
-
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:part3:46
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/moveOn:48
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:34
null:null:0
TEST-INFO | expected PASS
62 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Waited too long for click-to-play notification -
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:33
null:null:0
TEST-INFO | expected PASS
63 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Should have a click-to-play notification in the initial tab again -
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:part4:56
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/moveOn:48
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:34
null:null:0
TEST-INFO | expected PASS
64 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Should have a click-to-play notification in the initial tab -
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:part5:65
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:handleEvent:27
chrome://mozapps/content/plugins/pluginProblem.xml:pluginProblem_XBL_Constructor:83
null:null:0
TEST-INFO | expected PASS
65 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Waited too long for click-to-play notification -
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:33
null:null:0
TEST-INFO | expected PASS
66 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| Should have a click-to-play notification in the tab in the new window
-
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:part7:77
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/moveOn:48
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:34
null:null:0
TEST-INFO | expected PASS
67 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js
| plugin should be activated now -
Stack trace:
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_drag_drop.js:part8:95
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/moveOn:48
chrome://mochitests/content/browser/browser/base/content/test/plugins/head.js:waitForCondition/interval<:44
null:null:0
TEST-INFO | expected PASS
What does this test even do?
Ok, so what we do is we create a tab with a plugin, and make sure we're
showing a click-to-play notification. Then, we tear that tab out into a
new window, and wait for a click-to-play notification. The notification
is not showing up, so there's legit bustage here.
Actually, we don't even get the click-to-play notification in the first
tab… what's going on there? No, wait that's showing just fine.
Nevermind.
So, when working, the stack for re-showing the notification when dragging into a new window is:
PH_showClickToPlayNotification@chrome://browser/content/browser.js:4611:40
PH_reshowClickToPlayNotification@chrome://browser/content/browser.js:4467:5
pageShowEventHandlers@chrome://browser/content/browser.js:10121:5
Let's see which of those we hit with our patch…
15:19
(mconley)
smaug: ping
15:19
(smaug)
mconley: pong
15:20
(mconley)
smaug: I was wondering if you knew whether or not the pageshow event
is supposed to be kind of flake-y in content scripts when moving a tab
into its own window
15:20
(mconley)
smaug: because I don't appear to get that event fired when tabbrowser's replaceTabWithWindow is called...
15:20
(mconley)
in content scripts, anyways
15:21
(mconley)
even if it's all in the same process
15:22
(mconley)
if the above is possibly true, do you know what the best way for me to
confirm it would be? Like... good places for breakpoints?
15:22
(smaug)
hmm
15:22
(smaug)
I think no one has tested this stuff
15:22
(mconley)
heh, ok
15:23
(mconley)
smaug: am I correct in thinking that it's the pageshow stuff in nsFrameLoader.cpp that I want to look at?
15:25
(smaug)
yes
15:26
(mconley)
smaug: hm... and if it looks like pageshow is only being dispatched to the chrome event handler...
15:26
(mconley)
would you know who I'd talk to about that?
15:26
(mconley)
:)
15:26
mconley
fires up blame
15:27
(smaug)
mconley: ourWindow->GetChromeEventHandler()
15:27
(smaug)
and that stuff
15:27
(smaug)
it takes effectively xul:browser
15:27
(smaug)
and the event is fired on that
15:28
(mconley)
does that somehow bypass my content script event handler then?
15:28
(smaug)
it could use ourWindow->GetParentTarget()
15:28
(mconley)
like
15:28
(smaug)
tabchildglobal is an EventTarget between top level content window and that window's chrome event handler
15:29
(mconley)
smaug: ok, so my content script *should* be receiving this event?
15:29
(smaug)
no
15:29
(mconley)
ah, heh
15:29
(smaug)
because we use chrome event handler
15:29
(smaug)
but
15:29
(smaug)
we should change the code
15:30
(smaug)
so that content script would get the event
15:30
(mconley)
ok
15:30
(mconley)
smaug: and we'd change that code by setting the dispatch target to ourWindow->GetParentTarget()?
15:30
(smaug)
and some for the other window too
15:30
(smaug)
same
15:30
(mconley)
smaug: ok, gotcha. Thanks!
TL;DR: Gecko isn't sending pageshow / pagehide events to content scripts! Filed
bug 1058164
to get this fixed.
17:25
(mconley)
smaug: hey - so, I've got a solution, but I'm not sure how happy I am
with it. Basically, instead of passing a single EventTarget nsCOMPtr to
FirePageHideEvent / FirePageShowEvent, I change it to an nsCOMArray of
targets (one array for "ours" and one array for "other"), and call
doc->OnPageFoo(true, item) for each item in the array. For non-e10s,
that'll just be the window parent - one per array. For e10s, that'll be
the chrome ev
17:25
(mconley)
ent handlers and TabChildGlobals - so 2 items per array.
17:25
(mconley)
smaug: that seems a bit hamfisted. Was wondering if you had advice on a better way of doing things.
17:26
(smaug)
mconley: I don't understand the e10s case
17:26
(smaug)
in e10s TabChildGlobal is in different process
17:29
(mconley)
smaug: ok, I'm clearly misunderstanding how this stuff is related.
Lemme get my thoughts together, and then I'll probably have more
questions tomorrow. Thanks. :)
17:35
(smaug)
mconley: in non-e10s event target chain is window->TabchildGlobal->xul:browser
17:35
(smaug)
in e10s, child process window->WindowRoot->TabChildGlobal ...<process boundary> ... xul:browser
17:36
(mconley)
ah, so TabChildGlobal exists in both
17:36
(mconley)
I see
17:36
(mconley)
(both e10s and non-e10s case)
17:36
(smaug)
InProcessTabchildGlobal and TabChildGlobal
17:36
(mconley)
right
17:36
(smaug)
I think those are the class names
So I think pagehide / pageshow work fine when doing normal bfcache
retrievals - it's just when swapping frameloaders where things go wrong.
I've filed blocking
bug 1058164
about that.
So I need to figure out how nsFrameLoader works, once and for all. How
does it fit in? Does it exist in chrome as well as content processes? I
guess it might, since content can have arbitrary subtrees of frames…
nsFrameLoader
I think I'm going to put this exploration on hold until I've checked out the rest of the tests.
browser_CTP_notificationBar.js
So what's this guy's problem? It's strange… I think the pageshow
clearing of the pluginData cache is wrong. I don't see anything like
that going on before this patch. I think I'm going to excise it and see
what happens.
Just need to async-ify some of these get notifications, and this one is fixed.
browser_bug743421.js
Looks like this one is attempting to reach into the document and read
the state of the plugin. A content script should fix this.
PHWOAR - I've decided to tackle browser_CTP_crashreporting, and I
injected the framescript as planned, but now I'm dealing with a leak on
that test…
Ok, I've added an unload listener to PluginContent which destroys
this.global and this.content, and that seems to have cleared up the
leak. Phew.
browser_plugins_added_dynamically.js
WHAT IS YOUR MAJOR MALFUNCTION.
Oh, this is hilarious. It only fails if it runs with the entire folder - just like browser_bug820497.js. Lovely.
*sigh*, time to figure out where the interaction is. Innnnteresting -
it looks like we're getting the same kind of issue as for
browser_CTP_data_urls.js - the buttons that are coming up in the popup
aren't the right ones for some reason.
I would wager that this is because we're not properly clearing out
pluginData in PluginContent.jsm. Ah… so, clearing out pluginData on
pageshow makes this work. But that breaks
browser_CTP_notificationBar.js…
I really need to figure out this lifetime of pluginData inside PluginContent.jsm.
PluginData
What is it, any why is it, how does it work, and how do we make it work that way in e10s?
So, it appears to be a cache that is tied to the lifetime of a popup
notification. We open a popup notification for CTP, and we populate it -
if we notice that there's no pluginData cache, we create a new one and
populate it.
It looks like a notification is only ever removed if we travel through the bfcache to a page that has no plugins at all.
PopupNotifications get dropped (ie, the removed event is fired) when
changing locations. That's good - we should be clearing the pluginData
in that case.
Ah! PopupNotifications don't fire a removed event when the tab their
browser belongs to is closed!! That's what's going on here. Wait… we
should be getting a new PluginContent.jsm per tab, so if we close a tab,
we should destroy that PluginContent.jsm, and the new one should get…
well, a new pluginData. Is that not what's happening here?
AH HAH - the pluginData Map in PluginContent.jsm was set on the
prototype of PluginContent, meaning that it was shared across every
instance!! I've made it so that the constructor gives each instance its
own cache, as expected. Whew!
Back to nsFrameLoader
17:35
(smaug)
mconley: in non-e10s event target chain is window->TabchildGlobal->xul:browser
17:35
(smaug)
in e10s, child process window->WindowRoot->TabChildGlobal ...<process boundary> ... xul:browser
And then in his comment on the bug:
"That all is for non-e10s of course.
In case of e10s we should probably dispatch events to xul:browsers _and_ to TabChildGlobals"
In case of e10s we should probably dispatch events to xul:browsers _and_ to TabChildGlobals"
So, we want to dispatch the pageshow / pagehide events to the window parents for non-e10s. For e10s, I have to wait until
bug 918634
is fixed.
I've got the pageshow event now dispatching properly to the content
script, and we're triggering things properly, and that's great. What's
not so great is that I'm seeing errors like this when we try to open the
CTP notification:
ERROR resource:///modules/PluginContent.jsm:742 -
NS_ERROR_NOT_IMPLEMENTED: Component returned failure code: 0x80004001
(NS_ERROR_NOT_IMPLEMENTED) [nsIURI.userPass]
and that line 742 maps to this piece of code:
this.global.sendAsyncMessage("PluginContent:ShowClickToPlayNotification", {
plugins: [... this.pluginData.values()],
showNow: showNow,
principal: this._remotePrincipal(principal),
host: principalHost,
});
plugins: [... this.pluginData.values()],
showNow: showNow,
principal: this._remotePrincipal(principal),
host: principalHost,
});
Something isn't getting cloned properly. The Principal is my top guess.
This bug, that bz fixed, introduced the frameloader swapping stuff:
https://bugzilla.mozilla.org/show_bug.cgi?id=113934
ourEventTarget: mRawPtr
nsInProcessTabChildGlobal *
0x12cda33a0 0x000000012cda33a0
otherEventTarget: mRawPtr
nsInProcessTabChildGlobal *
0x11e1ed2c0 0x000000011e1ed2c0
OK! Figured it out -
I explained in this comment and smaug confirmed.
ALL TESTS ARE NOW PASSING! \o/
Compare handleEvent in mbrubeck's PluginContent.jsm with the one in master
Just pass raw principals over the message manager instead of reconstituting them
(see billm's comment)
Fix browser_CTP_crashreporting.js and browser_pluginCrashCommentAndURL.js by using the plan I mentioned above.
Fix nested iframe click-to-play regression (iframe in an iframe with flash doesn't get blocked!)
Remove any really gross dump statements / debugging crap so I can post a WIP.
Make sure I've truly got the lifetime of pluginData down properly.
Split up patch into smaller chunks
Evaluate the gross hacks I used to fix the tests and try to come up with a better plan.
What smaller chunks can I split the patch up into?
- Changes to browser-plugins.js
- Copy of browser-plugins.js to PluginContent.jsm, and changes therein.
- Changes to tests.
- Misc changes to browser/ stuff that doesn't fall into the above.
Ok, I've posted my patches, and targeted jaws. Hopefully it's not too much!
Hold up… I've been spending this whole time just making tests pass.
Have I even ensured that CTP works for e10s, which is the whole point of
this?
Yeah, it seems to work. WHEW. Jesus.
Relevant tests:
browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js (fixed)
browser/base/content/test/plugins/browser_CTP_zoom.js (fixed)
browser/base/content/test/plugins/
browser_CTP_data_urls.js (fixed)
browser/base/content/test/plugins/
browser_CTP_crashreporting.js (fixed)
browser/base/content/test/plugins/
browser_pluginCrashCommentAndURL.js ("fixed" - this test needs a big cleanup though.)
browser/base/content/test/plugins/browser_CTP_drag_drop.js (fixed)
browser/base/content/test/plugins/browser_CTP_notificationBar.js (fixed)
browser/base/content/test/plugins/browser_bug743421.js (fixed)
browser/base/content/test/plugins/browser_bug820497.js (fixed)
browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js (fixed)
browser/base/content/test/plugins/browser_pluginnotification.js (fixed)
browser/base/content/test/plugins/browser_pluginplaypreview.js (fixed)
browser/base/content/test/plugins/browser_pluginplaypreview2.js (fixed)
browser/base/content/test/plugins/browser_plugins_added_dynamically.js (fixed)
browser/base/content/test/plugins/browser_CTP_iframe.js (fixed - solution needs slight cleanup)
Test cleanup - second pass
Ok, now that I've got tests that pass, I more or less know that the CTP implementation is in pretty good shape.
Now what I need to do is clean-up these tests so that they're in better
shape. I added some pretty hacky stuff to get them to pass. Let's see
if we can make that better. I'll go from easiest to hardest.
browser_globalplugin_crashinfobar.js (easy - clean)
browser_bug820497.js (easy - clean)
browser_CTP_notificationBar.js (medium - clean)
browser_CTP_iframe.js (medium - clean)
browser_CTP_drag_drop.js (medium - clean)
browser_pluginCrashCommentAndURL.js (hard)
browser_CTP_crashreporting.js (hard)
So… pluginCrashCommentAndURL and crashreporting are two tests that
follow a particular pattern - namely, they trigger crashes, then after
the PluginCrash event fires, they manipulate the crashed plugin UI, and
then listen for things in the crash submission notification and checks
things in there.
I think we should probably redesign these tests a little bit.
Instead of having this external content script, maybe we just do the
script-to-dataURI trick we used before, and forget about having some
kind of specialized tool for testing content-y things. I think that's
probably best.
Done my cleanup!
Here's a try push with everything:
BAH - some failures in plugin tests that I didn't know about under mozapps. And what appears like a leak. :/
Let's do mozapps failures first.
toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
toolkit/mozapps/extensions/test/browser/test-window/browser_CTP_plugins.js
Fixed! It was just a bunch of waiting for notifications again.
Now how about this leak
…
Ooooh… and maybe an intermittent:
browser/base/content/test/plugins/browser_pluginnotification.js | Test 24b, plugin should be activated -
Guh… so, this leak…
WARNING - TEST-UNEXPECTED-FAIL |
browser/base/content/test/general/browser_bug409481.js | leaked 1
window(s) until shutdown [url = chrome://browser/content/web-panels.xul]
I'm disabling this test to see if the leak goes away… but I have
my doubts that it'll go away. If it does, that's super interesting. I
seem to be able to reproduce this on my Ubuntu machine, but only when I
run bc1. :/
Guh. So hard to tell. Gonna try with a try push.
Er… hrm, interesting. Passes for both. Accidentally disabled the test
in the second as well. :/ But I didn't expect disabling the test to
work. Strange.
PluginContent removed.
https://tbpl.mozilla.org/?tree=Try&rev=e119b3817067
- wow - Still leaking!!
What if we remove all of the test fixups and browser misc?:
https://tbpl.mozilla.org/?tree=Try&rev=159a2fd63243
… LEAK
And what if we do _just_ test-fixups, but no CTP changes?:
https://tbpl.mozilla.org/?tree=Try&rev=740201e35419
- GREEN.
So, the problem seems to be not in PluginContent, but either in the browser-plugins.js changes, or the misc stuff…
So it's starting to look like something is up in browser-plugins.js.
Maybe we need to deinit gPluginHandler, and remove the message manager listeners.
https://tbpl.mozilla.org/?tree=Try&rev=6e28483c0614
YEAH, that fixed it. LEAK SOLVED, YO.
But now I see
intermittent: browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, plugin should be activated -
Same as before. Let's look at that now. Might just be a matter of upping the timeout, or waiting for something.
Also, I need to respond to georg's feedback, and then convince him that he has review powers!
Ok, I think I have made browser_pluginnotification.js more robust. Let's see what this try push shows:
https://tbpl.mozilla.org/?tree=Try&rev=9ba04fa90de9
Bunch-o-logging:
https://tbpl.mozilla.org/?tree=Try&rev=893047d17b34
Next time I need to just do bc1, just try mochitest-browser-chrome-1.
Ok, let's try bumping the timeouts a bit:
https://tbpl.mozilla.org/?tree=Try&rev=c4e1db8b62aa
Hm, now the whole test is timing out. I think perhaps the plugin just
isn't being activated. What the hell? Maybe I should dump the label of
the button that we're clicking to make sure we're actually doing the
activation. And maybe put some dumps around the critical part of the
test.
Even mooooore logging:
https://tbpl.mozilla.org/?tree=Try&rev=86035c69fc5c
Ah hah - according to the logging, we've got "Allow Now" instead of
"Allow Always" in the button that 24a is clicking. Strangely, it's also
"Allow Now" in the passing case. What's gone wrong here?
Let's see what happens if I make us push the secondary button ("Allow and remember") instead of the primary?
Grrr… still failing. What the hell?
What exactly is this test doing?
Hmm… nothing fishy there. Here's a screenshot of the test failure:
Yep, that's definitely not activated. Maybe even though the child is
receiving the activation message, we're not actually activating ever.
I've put a bunch of logging in PluginContent::activatePlugins to see if
it's bailing out anywhere.
Ok, instrumented nsObjectLoadingContent a bit… but now I've got a new
theory. In test24a, we click on the panel button to activate the plugin,
and then we immediately browse away. Y'know, I'll bet that plugin
activation used to be synchronous. With PluginContent.jsm though, it's
not - and I'll bet that's what's going wrong! We send the message to
activate, but it never makes it to the child before we browse away! So
we just need to wait for the plugin to activate before we browse away
and trigger test24b. I've added a wait and pushed to try. FINGERS
CROSSED!
Woo! I think that did it! Pushing to try for all platforms now.
Uh, whoops. Cruft in that patch.
GRALKHAKSJHKJHASKRAJSLRASL it's still there. :(((
*sigh*. Back to the logging patch. This time, without the thing that caused all that orange.
Uh… now orange is gone. Wtf? Let's try removing all of my printf statements and some dump statements…
Okayyyyy…. now it's gone again… cautiously push with the dump
statements removed… but keep SimpleTest.requestCompleteLog() (wtf)
Oh great, now another intermittent orange:
509 INFO TEST-UNEXPECTED-FAIL | chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_data_urls.js | Test 3a, Waited too long for plugin to activate -
511 INFO TEST-UNEXPECTED-FAIL | chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_CTP_data_urls.js | Test 3c, Plugin should be activated -
Ok… time for more instrumentation *sigh*
Ok, instrumented it like crazy. Here goes.
Oooh - and I've got some reviews from Georg. Great! Nothing too serious it seems - fantastic.
Ah, interesting data from those logs. It looks like in the failing
case, which is rare, the button that we're pressing in the popup is "Ok"
and not "Allow now". Under what circumstances is the popup saying "OK"?
Er… interesting. None of those buttons should be "OK"… and the request
is sends down is "Block". Wtf?
Ah… that's button-accept from dialog.properties.
Well… we'll see how bad that intermittent orange gets. I _think_ I know what's up with it, anyhow.
Landed! Let's see if it sticks on fx-team. Fingers crossed.
Things to do:
File a follow-up for handling content process crashes to clean up notification bars -
bug 1067495
File a follow-up to load PluginContent lazily -
bug 1067497
GRRRR - bounced.
browser_pluginnotification.js is failing again, at the same spot. The
good news is that I seem to be able to reproduce this locally with
--run-until-failure.
I've added code that waits for the notification to be removed before continuing. Testing…
Hm, seems to be better, but still room for improvement.
Bad state:
Child is sending ShowClickToPlayNotification
Telling content process to clear caches
Parent process is showing click to play notification
Clearing plugin data cache
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
3917 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Should have a click-to-play notification
3918 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Found plugin in page
3919 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY
3920 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin should have started
3921 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin should be activated
3922 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin should be unloaded
3923 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Plugin should not have activated
3924 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Plugin should be click-to-play
3925 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin node should not be activated
Child is sending ShowClickToPlayNotification
OHAI: removed
Telling content process to clear caches
Resolving
Parent process is showing click to play notification
Clearing plugin data cache
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
Ok, running after binding attached - test24a...
3926 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Should have a click-to-play notification
3927 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Found plugin in page
3928 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Plugin should be click-to-play
3929 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, plugin should not be activated
Clicking on Allow now..., right?: Allow Now
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
Telling content process to clear caches
Clearing plugin data cache
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
3930 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, Found plugin in page
3931 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, plugin should be activated -
Good state:
Child is sending ShowClickToPlayNotification
Telling content process to clear caches
Parent process is showing click to play notification
Clearing plugin data cache
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
152 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Should have a click-to-play notification
153 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Found plugin in page
154 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY
155 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin should have started
156 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin should be activated
157 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin should be unloaded
158 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Plugin should not have activated
159 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, Plugin should be click-to-play
160 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 23, plugin node should not be activated
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
OHAI: removed
Telling content process to clear caches
Resolving
Clearing plugin data cache
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
Ok, running after binding attached - test24a...
161 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Should have a click-to-play notification
162 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Found plugin in page
163 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Plugin should be click-to-play
164 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, plugin should not be activated
Clicking on Allow now..., right?: Allow Now
Child is sending ShowClickToPlayNotification
Parent process is showing click to play notification
Telling content process to clear caches
Clearing plugin data cache
Child is sending ShowClickToPlayNotification
165 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, Found plugin in page
Parent process is showing click to play notification
So I have a patch that works, but _why_ does it rely on the notification being reshown?
Bad state:
Setting permission for plugin:libnptest : 1 for expireType 1 in 1410919002828 ms.
Sending BrowserPlugins:ActivatePlugins
Handling activate plugins in child.
Playing plugin
Setting mActivated to true at checkpoint 3
Determining final type
Plugin type with no URI - skipping channel load
mActivated was not set to true because mActivated is true and mType is 2
updating notification UI in the child
Enabled state of plugin is: 1
Testing permission for plugin:libnptest - got 0
Shouldplay false - checkpoint 14
Showing overlay
Enabled state of plugin is: 1
Testing permission for plugin:libnptest - got 0
Shouldplay false - checkpoint 14
Child telling parent to show click to play notification.
Parent received message to show c2p notification.
FIRING REMOVED FROM CHECKPOINT 1
REMOVED
Determining final type
Plugin type with no URI - skipping channel load
Enabled state of plugin is: 1
Testing permission for plugin:libnptest - got 0
Shouldplay false - checkpoint 14
Nulling at checkpoint 3
mActivated was not set to true because mActivated is false and mType is 4
Nulling at checkpoint 11
Enabled state of plugin is: 1
Testing permission for plugin:libnptest - got 0
Shouldplay false - checkpoint 14
Enabled state of plugin is: 1
Testing permission for plugin:libnptest - got 0
Shouldplay false - checkpoint 14
Child telling parent to show click to play notification.
Parent received message to show c2p notification.
updating notification UI in the child
Enabled state of plugin is: 1
Testing permission for plugin:libnptest - got 0
Shouldplay false - checkpoint 14
Showing overlay
1878 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, Found plugin in page
1879 INFO TEST-UNEXPECTED-FAIL |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, plugin should be activated -
Good state:
161 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Should have a click-to-play notification
162 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Found plugin in page
163 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, Plugin should be click-to-play
164 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24a, plugin should not be activated
Setting permission for plugin:libnptest : 1
Sending BrowserPlugins:ActivatePlugins
Handling activate plugins in child.
Playing plugin
Setting mActivated to true at checkpoint 3
Determining final type
Plugin type with no URI - skipping channel load
mActivated was not set to true because mActivated is true and mType is 2
updating notification UI in the child
Enabled state of plugin is: 1
Shouldplay TRUE! Checkpoint 1!
Enabled state of plugin is: 1
Shouldplay TRUE! Checkpoint 1!
Child telling parent to show click to play notification.
Parent received message to show c2p notification.
FIRING REMOVED FROM CHECKPOINT 1
REMOVED
Determining final type
Plugin type with no URI - skipping channel load
Enabled state of plugin is: 1
Shouldplay TRUE! Checkpoint 1!
mActivated is true at checkpoint 2
Enabled state of plugin is: 1
Shouldplay TRUE! Checkpoint 1!
Child telling parent to show click to play notification.
Parent received message to show c2p notification.
165 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24b, Found plugin in page
updating notification UI in the child
Enabled state of plugin is: 1
Shouldplay TRUE! Checkpoint 1!
FIRING REMOVED FROM CHECKPOINT 1
Determining final type
Plugin type with no URI - skipping channel load
Enabled state of plugin is: 1
Shouldplay false - checkpoint 13
Nulling at checkpoint 3
mActivated was not set to true because mActivated is false and mType is 4
Nulling at checkpoint 11
Enabled state of plugin is: 1
Shouldplay false - checkpoint 13
Enabled state of plugin is: 1
Shouldplay false - checkpoint 13
Child telling parent to show click to play notification.
Parent received message to show c2p notification.
166 INFO TEST-PASS |
chrome://mochitests/content/browser/browser/base/content/test/plugins/browser_pluginnotification.js
| Test 24c, Should have a click-to-play notification
The Principal is wrong!
Theory - Test 23 appends a node which causes a click to play message to
come up from the child, and then test 24 starts to run. Test 23's
notification is mapped to the system principal, and suddenly shows up,
which we click, which …. plays Test 24a's plugin? Confirm?
And then when we reload, the system principal is not the one we want so 24b's plugin is not activated by default.
Ok, put together fix, got it reviewed, and re-landed. Here's hoping it sticks THIS TIME.
Ugh, slight problem.
20:13
(mconley)
billm: hey - so for bug 899347, I landed that on fx-team, but didn't
realize that the code that I used to fix the frequent orange for
non-e10s basically breaks the click-to-play doorhanger notification for
e10s mode. :(
20:13
(firebot)
https://bugzil.la/899347
— REOPENED,
mconley@mozilla.com
— Make click-to-play work in e10s
20:13
(mconley)
billm: and it breaks because I attempt to compare an nsIPrincipal passed through the message manager to an nsIPrincipal CPOW
20:14
(mconley)
apparently, nsIPrincipal.equals really doesn't expect to compare with a CPOW
20:14
(mconley)
so, suppose I have an nsIPrincipal on the parent side - what's the
best way of comparing it to the principal that the content in the
current selected browser is pointed at?
20:14
(mconley)
billm: --^?
20:16
(billm)
mconley: we should probably send a new contentPrincipal every time the browser changes location
20:16
(billm)
mconley: then remote-browser.xml could have its own contentPrincipal getter and we could get rid of the CPOW
20:17
(mconley)
billm: That sounds like a fair plan. My current click-to-play patch
doesn't break click-to-play for non-e10s, so I think what I'm going to
do is mark to keep the bug open, and work on a follow-up patch to do
what you just described to get it to actually work in e10s mode.
20:18
(billm)
mconley: ok, that sounds good. also, it looks like that will allow us to get rid of all the unremotePrincipal calls in
http://mxr.mozilla.org/mozilla-central/source/browser/base/content/nsContextMenu.js
20:18
(billm)
I forgot how gross that was
20:19
(billm)
mconley: anyway, do you know where to put the pieces? I think we can send the principals here:
http://mxr.mozilla.org/mozilla-central/source/toolkit/content/browser-child.js
20:19
(billm)
mconley: and then remote-browser.xml can just cache it in a field
20:20
(billm)
mconley: and then we can drop the AsCPOW stuff from browser.xml
20:20
(mconley)
billm: yeah, I saw we had a convenient way to send nsIPrincipals over the wire
20:20
(mconley)
so so long as we're sending a message when we change locations (which
we do), I think this should be reasonably straight forward.
20:20
(billm)
mconley: cool, thanks. that'll be a nice cleanup.
Ok, landed patch for
bug
1069567
to make the nsIPrincipal comparison work properly.