Bug 1274919 - part3 : only send msg if someone is waiting for it.
Only send the msg "Browser:UnselectedTabHover" when someone requests for the
msg, it can reduce non-necessary communication.
MozReview-Commit-ID: 2mBUMB4AMVo
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -154,34 +154,94 @@ class MediaDecoder::BackgroundVideoDecod
}
void RegisterEvent() {
MOZ_ASSERT(!mIsRegisteredForEvent);
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (observerService) {
observerService->AddObserver(this, "unselected-tab-hover", false);
mIsRegisteredForEvent = true;
+ EnableEvent();
}
}
void UnregisterEvent() {
MOZ_ASSERT(mIsRegisteredForEvent);
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (observerService) {
observerService->RemoveObserver(this, "unselected-tab-hover");
mIsRegisteredForEvent = false;
mDecoder->mIsBackgroundVideoDecodingAllowed = false;
mDecoder->UpdateVideoDecodeMode();
+ DisableEvent();
}
}
private:
~BackgroundVideoDecodingPermissionObserver() {
MOZ_ASSERT(!mIsRegisteredForEvent);
}
+ void EnableEvent() const
+ {
+ nsCOMPtr<nsPIDOMWindowOuter> win = GetOwnerWindow();
+ if (!win) {
+ return;
+ }
+ nsContentUtils::DispatchEventOnlyToChrome(
+ GetOwnerDoc(), ToSupports(win),
+ NS_LITERAL_STRING("UnselectedTabHover:Enable"),
+ /* Bubbles */ true,
+ /* Cancelable */ false,
+ /* DefaultAction */ nullptr);
+ }
+
+ void DisableEvent() const
+ {
+ nsCOMPtr<nsPIDOMWindowOuter> win = GetOwnerWindow();
+ if (!win) {
+ return;
+ }
+ nsContentUtils::DispatchEventOnlyToChrome(
+ GetOwnerDoc(), ToSupports(win),
+ NS_LITERAL_STRING("UnselectedTabHover:Disable"),
+ /* Bubbles */ true,
+ /* Cancelable */ false,
+ /* DefaultAction */ nullptr);
+ }
+
+ already_AddRefed<nsPIDOMWindowOuter> GetOwnerWindow() const
+ {
+ nsIDocument* doc = GetOwnerDoc();
+ if (!doc) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsPIDOMWindowInner> innerWin = doc->GetInnerWindow();
+ if (!innerWin) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsPIDOMWindowOuter> outerWin = innerWin->GetOuterWindow();
+ if (!outerWin) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsPIDOMWindowOuter> topWin = outerWin->GetTop();
+ return topWin.forget();
+ }
+
+ nsIDocument* GetOwnerDoc() const
+ {
+ if (!mDecoder->mOwner) {
+ return nullptr;
+ }
+
+ return mDecoder->mOwner->GetDocument();
+ }
+
bool IsValidEventSender(nsISupports* aSubject) const
{
nsCOMPtr<nsPIDOMWindowInner> senderInner(do_QueryInterface(aSubject));
if (!senderInner) {
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> senderOuter = senderInner->GetOuterWindow();
@@ -189,32 +249,21 @@ class MediaDecoder::BackgroundVideoDecod
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> senderTop = senderOuter->GetTop();
if (!senderTop) {
return false;
}
- nsIDocument* doc = mDecoder->GetOwner()->GetDocument();
- if (!doc) {
+ nsCOMPtr<nsPIDOMWindowOuter> ownerTop = GetOwnerWindow();
+ if (!ownerTop) {
return false;
}
- nsCOMPtr<nsPIDOMWindowInner> ownerInner = doc->GetInnerWindow();
- if (!ownerInner) {
- return false;
- }
-
- nsCOMPtr<nsPIDOMWindowOuter> ownerOuter = ownerInner->GetOuterWindow();
- if (!ownerOuter) {
- return false;
- }
-
- nsCOMPtr<nsPIDOMWindowOuter> ownerTop = ownerOuter->GetTop();
return ownerTop == senderTop;
}
// The life cycle of observer would always be shorter than decoder, so we
// use raw pointer here.
MediaDecoder* mDecoder;
bool mIsRegisteredForEvent;
};
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -977,20 +977,16 @@ addMessageListener("WebChannelMessageToC
} else {
Cu.reportError("WebChannel message failed. Principal mismatch.");
}
} else {
Cu.reportError("WebChannel message failed. No message data.");
}
});
-addMessageListener("Browser:UnselectedTabHover", message => {
- Services.obs.notifyObservers(content.window, "unselected-tab-hover", message.data.hovered);
-});
-
var AudioPlaybackListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
init() {
Services.obs.addObserver(this, "audio-playback");
addMessageListener("AudioPlayback", this);
addEventListener("unload", () => {
@@ -1060,16 +1056,33 @@ var AudioPlaybackListener = {
receiveMessage(msg) {
if (msg.name == "AudioPlayback") {
this.handleMediaControlMessage(msg.data.type);
}
},
};
AudioPlaybackListener.init();
+var UnselectedTabHoverObserver = {
+ init() {
+ addMessageListener("Browser:UnselectedTabHover", this);
+ addEventListener("UnselectedTabHover:Enable", this);
+ addEventListener("UnselectedTabHover:Disable", this);
+ },
+ receiveMessage(message) {
+ Services.obs.notifyObservers(content.window, "unselected-tab-hover",
+ message.data.hovered);
+ },
+ handleEvent(event) {
+ sendAsyncMessage("UnselectedTabHover:Toggle",
+ { enable: event.type == "UnselectedTabHover:Enable" });
+ }
+};
+UnselectedTabHoverObserver.init();
+
addMessageListener("Browser:PurgeSessionHistory", function BrowserPurgeHistory() {
let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
if (!sessionHistory) {
return;
}
// place the entry at current index at the end of the history list, so it won't get removed
if (sessionHistory.index < sessionHistory.count - 1) {
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -845,21 +845,30 @@
let event = document.createEvent("Events");
event.initEvent("DOMAudioPlaybackBlockStopped", true, false);
this.dispatchEvent(event);
}
]]>
</body>
</method>
+ <!--
+ Only send the message "Browser:UnselectedTabHover" when someone requests
+ for the message, which can reduce non-necessary communication.
+ -->
+ <field name="_shouldSendUnselectedTabHover">false</field>
+ <field name="_unselectedTabHoverMessageListenerCount">0</field>
+
<method name="unselectedTabHover">
<parameter name="hovered"/>
<body>
<![CDATA[
- // TODO : only dispatch event when someone is waiting for this message
+ if (!this._shouldSendUnselectedTabHover) {
+ return;
+ }
this.messageManager.sendAsyncMessage("Browser:UnselectedTabHover",
{ hovered });
]]>
</body>
</method>
<property name="securityUI">
<getter>
@@ -987,16 +996,17 @@
this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);
this.messageManager.addMessageListener("Autoscroll:Start", this);
this.messageManager.addMessageListener("Autoscroll:Cancel", this);
this.messageManager.addMessageListener("AudioPlayback:Start", this);
this.messageManager.addMessageListener("AudioPlayback:Stop", this);
this.messageManager.addMessageListener("AudioPlayback:ActiveMediaBlockStart", this);
this.messageManager.addMessageListener("AudioPlayback:ActiveMediaBlockStop", this);
this.messageManager.addMessageListener("AudioPlayback:MediaBlockStop", this);
+ this.messageManager.addMessageListener("UnselectedTabHover:Toggle", this);
if (this.hasAttribute("selectmenulist")) {
this.messageManager.addMessageListener("Forms:ShowDropDown", this);
this.messageManager.addMessageListener("Forms:HideDropDown", this);
}
}
]]>
@@ -1093,16 +1103,21 @@
this.activeMediaBlockStarted();
break;
case "AudioPlayback:ActiveMediaBlockStop":
this.activeMediaBlockStopped();
break;
case "AudioPlayback:MediaBlockStop":
this.mediaBlockStopped();
break;
+ case "UnselectedTabHover:Toggle":
+ this._shouldSendUnselectedTabHover = data.enable ?
+ ++this._unselectedTabHoverMessageListenerCount > 0 :
+ --this._unselectedTabHoverMessageListenerCount == 0;
+ break;
case "Forms:ShowDropDown": {
if (!this._selectParentHelper) {
this._selectParentHelper =
Cu.import("resource://gre/modules/SelectParentHelper.jsm", {}).SelectParentHelper;
}
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
menulist.menupopup.style.direction = data.direction;