Bug 1113086 - AudioChannel policy in Browser API - patch 3 - right management of audiochannel-activity events in child processes, r=ehsan
☠☠ backed out by ee99ebac7761 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 10 Jul 2015 17:38:48 +0100
changeset 278014 5ec088f0892faffec5a6240bb8f53032a64c73dd
parent 278013 caf57ae8cbcef6b317692603e3738556d843b424
child 278015 380859ae955bbc8e88e5463eefc1511af2cec493
push id3422
push usercykesiopka.bmo@gmail.com
push dateSun, 12 Jul 2015 16:26:48 +0000
reviewersehsan
bugs1113086
milestone42.0a1
Bug 1113086 - AudioChannel policy in Browser API - patch 3 - right management of audiochannel-activity events in child processes, r=ehsan
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -872,16 +872,17 @@ TabChild::TabChild(nsIContentChild* aMan
   , mSetAllowedTouchBehaviorCallback(new TabChildSetAllowedTouchBehaviorCallback(this))
   , mHasValidInnerSize(false)
   , mDestroyed(false)
   , mUniqueId(aTabId)
   , mDPI(0)
   , mDefaultScale(0)
   , mIPCOpen(true)
   , mParentIsActive(false)
+  , mAudioChannelActive(false)
 {
   // In the general case having the TabParent tell us if APZ is enabled or not
   // doesn't really work because the TabParent itself may not have a reference
   // to the owning widget during initialization. Instead we assume that this
   // TabChild corresponds to a widget type that would have APZ enabled, and just
   // check the other conditions necessary for enabling APZ.
   mAsyncPanZoomEnabled = gfxPlatform::AsyncPanZoomEnabled();
 
@@ -983,20 +984,49 @@ TabChild::Observe(nsISupports *aSubject,
     topic.Append(table[i].tag);
 
     if (topic.Equals(aTopic)) {
       audioChannel = table[i].value;
       break;
     }
   }
 
-  if (audioChannel != -1) {
-    nsAutoString active(aData);
-    unused << SendAudioChannelActivityNotification(audioChannel,
-                                                   active.Equals(NS_LITERAL_STRING("active")));
+  if (audioChannel != -1 && mIPCOpen) {
+    // If the subject is not a wrapper, it is sent by the TabParent and we
+    // should ignore it.
+    nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
+    if (!wrapper) {
+      return NS_OK;
+    }
+
+    // We must have a window in order to compare the windowID contained into the
+    // wrapper.
+    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation());
+    if (!window) {
+      return NS_OK;
+    }
+
+    uint64_t windowID = 0;
+    nsresult rv = wrapper->GetData(&windowID);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    // In theory a tabChild should contain just 1 top window, but let's double
+    // check it comparing the windowID.
+    if (window->WindowID() != windowID) {
+      return NS_OK;
+    }
+
+    nsAutoString activeStr(aData);
+    bool active = activeStr.EqualsLiteral("active");
+    if (active != mAudioChannelActive) {
+      mAudioChannelActive = active;
+      unused << SendAudioChannelActivityNotification(audioChannel, active);
+    }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabChild::OnStateChange(nsIWebProgress* aWebProgress,
                         nsIRequest* aRequest,
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -654,16 +654,17 @@ private:
     bool mDestroyed;
     // Position of tab, relative to parent widget (typically the window)
     LayoutDeviceIntPoint mChromeDisp;
     TabId mUniqueId;
     float mDPI;
     double mDefaultScale;
     bool mIPCOpen;
     bool mParentIsActive;
+    bool mAudioChannelActive;
     bool mAsyncPanZoomEnabled;
     CSSSize mUnscaledInnerSize;
 
     DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 }
 }