Bug 1232348 - adjust nested-frame checking condition. a=jocheng
authorAlastor Wu <alwu@mozilla.com>
Fri, 18 Dec 2015 18:21:37 +0800
changeset 292694 4394647bdf0d
parent 292693 fd9437a5f9a3
child 292695 311b64761900
push id330
push usergachen@mozilla.com
push dateThu, 07 Apr 2016 08:55:15 +0000
reviewersjocheng
bugs1232348
milestone44.0
Bug 1232348 - adjust nested-frame checking condition. a=jocheng MozReview-Commit-ID: 4XDYbgs04RP
dom/browser-element/BrowserElementAudioChannel.cpp
dom/browser-element/BrowserElementAudioChannel.h
--- a/dom/browser-element/BrowserElementAudioChannel.cpp
+++ b/dom/browser-element/BrowserElementAudioChannel.cpp
@@ -1,21 +1,23 @@
 /* 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/. */
 
 #include "BrowserElementAudioChannel.h"
 
+#include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/BrowserElementAudioChannelBinding.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/DOMRequest.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "AudioChannelService.h"
+#include "nsIAppsService.h"
 #include "nsIBrowserElementAPI.h"
 #include "nsIDocShell.h"
 #include "nsIDOMDOMRequest.h"
 #include "nsIObserverService.h"
 #include "nsISupportsPrimitives.h"
 #include "nsITabParent.h"
 #include "nsPIDOMWindow.h"
 
@@ -285,16 +287,35 @@ public:
 protected:
   virtual void DoWork(AudioChannelService* aService, JSContext* aCx) override
   {
     JS::Rooted<JS::Value> value(aCx);
     mRequest->FireSuccess(value);
   }
 };
 
+uint32_t
+GetSystemAppID()
+{
+  uint32_t systemAppId = nsIScriptSecurityManager::NO_APP_ID;
+  nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
+  if (NS_WARN_IF(!appsService)) {
+    return systemAppId;
+  }
+
+  nsAdoptingString systemAppManifest =
+    mozilla::Preferences::GetString("b2g.system_manifest_url");
+  if (!systemAppManifest) {
+    return systemAppId;
+  }
+
+  appsService->GetAppLocalIdByManifestURL(systemAppManifest, &systemAppId);
+  return systemAppId;
+}
+
 } // anonymous namespace
 
 already_AddRefed<dom::DOMRequest>
 BrowserElementAudioChannel::GetVolume(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mFrameWindow) {
@@ -462,17 +483,17 @@ BrowserElementAudioChannel::Observe(nsIS
     if (mTabParent == aSubject) {
       ProcessStateChanged(aData);
     }
 
     return NS_OK;
   }
 
   nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
-  // This can be a nested iframe.
+  // This might be a nested iframe.
   if (!wrapper) {
     nsCOMPtr<nsITabParent> iTabParent = do_QueryInterface(aSubject);
     if (!iTabParent) {
       return NS_ERROR_FAILURE;
     }
 
     RefPtr<TabParent> tabParent = TabParent::GetFrom(iTabParent);
     if (!tabParent) {
@@ -480,17 +501,17 @@ BrowserElementAudioChannel::Observe(nsIS
     }
 
     Element* element = tabParent->GetOwnerElement();
     if (!element) {
       return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsPIDOMWindow> window = element->OwnerDoc()->GetWindow();
-    if (window == mFrameWindow) {
+    if (window == mFrameWindow && !IsSystemAppWindow(window)) {
       ProcessStateChanged(aData);
     }
 
     return NS_OK;
   }
 
   uint64_t windowID;
   nsresult rv = wrapper->GetData(&windowID);
@@ -509,10 +530,36 @@ BrowserElementAudioChannel::Observe(nsIS
 void
 BrowserElementAudioChannel::ProcessStateChanged(const char16_t* aData)
 {
   nsAutoString value(aData);
   mState = value.EqualsASCII("active") ? eStateActive : eStateInactive;
   DispatchTrustedEvent(NS_LITERAL_STRING("activestatechanged"));
 }
 
+bool
+BrowserElementAudioChannel::IsSystemAppWindow(nsPIDOMWindow* aWindow)
+{
+  nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
+  if (!doc) {
+    return false;
+  }
+
+  uint32_t appId;
+  nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
+  nsresult rv = principal->GetAppId(&appId);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return false;
+  }
+
+  if (appId == nsIScriptSecurityManager::NO_APP_ID ||
+      appId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
+    return false;
+  }
+
+  if (GetSystemAppID() == appId) {
+    return true;
+  }
+  return false;
+}
+
 } // dom namespace
 } // mozilla namespace
--- a/dom/browser-element/BrowserElementAudioChannel.h
+++ b/dom/browser-element/BrowserElementAudioChannel.h
@@ -60,16 +60,18 @@ public:
   IMPL_EVENT_HANDLER(activestatechanged);
 
 private:
   BrowserElementAudioChannel(nsPIDOMWindow* aWindow,
                              nsIFrameLoader* aFrameLoader,
                              nsIBrowserElementAPI* aAPI,
                              AudioChannel aAudioChannel);
 
+  bool IsSystemAppWindow(nsPIDOMWindow* aWindow);
+
   ~BrowserElementAudioChannel();
 
   nsresult Initialize();
 
   void ProcessStateChanged(const char16_t* aData);
 
   nsCOMPtr<nsIFrameLoader> mFrameLoader;
   nsCOMPtr<nsIBrowserElementAPI> mBrowserElementAPI;