Bug 1214148 - patch 3 - correct window for nested iframes, r=alwu

This commit is contained in:
Andrea Marchesini 2015-12-11 11:17:33 -05:00
parent 4f57cd1c8f
commit a1a56f1e5f
5 changed files with 99 additions and 16 deletions

View File

@ -6,7 +6,11 @@
#include "AudioChannelAgent.h"
#include "AudioChannelService.h"
#include "mozilla/Preferences.h"
#include "nsIAppsService.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIPrincipal.h"
#include "nsPIDOMWindow.h"
#include "nsXULAppAPI.h"
@ -77,6 +81,81 @@ AudioChannelAgent::InitWithWeakCallback(nsIDOMWindow* aWindow,
/* useWeakRef = */ true);
}
nsresult
AudioChannelAgent::FindCorrectWindow(nsIDOMWindow* aWindow)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window->IsInnerWindow());
mWindow = window->GetScriptableTop();
if (NS_WARN_IF(!mWindow)) {
return NS_OK;
}
mWindow = mWindow->GetOuterWindow();
if (NS_WARN_IF(!mWindow)) {
return NS_ERROR_FAILURE;
}
// From here we do an hack for nested iframes.
// The system app doesn't have access to the nested iframe objects so it
// cannot control the volume of the agents running in nested apps. What we do
// here is to assign those Agents to the top scriptable window of the parent
// iframe (what is controlled by the system app).
// For doing this we go recursively back into the chain of windows until we
// find apps that are not the system one.
window = mWindow->GetParent();
if (!window || window == mWindow) {
return NS_OK;
}
window = window->GetCurrentInnerWindow();
if (!window) {
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (!doc) {
return NS_OK;
}
nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
uint32_t appId;
nsresult rv = principal->GetAppId(&appId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (appId == nsIScriptSecurityManager::NO_APP_ID ||
appId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
return NS_OK;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
if (NS_WARN_IF(!appsService)) {
return NS_ERROR_FAILURE;
}
nsAdoptingString systemAppManifest =
mozilla::Preferences::GetString("b2g.system_manifest_url");
if (!systemAppManifest) {
return NS_OK;
}
uint32_t systemAppId;
rv = appsService->GetAppLocalIdByManifestURL(systemAppManifest, &systemAppId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (systemAppId == appId) {
return NS_OK;
}
return FindCorrectWindow(window);
}
nsresult
AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback,
@ -108,18 +187,9 @@ AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
MOZ_ASSERT(pInnerWindow->IsInnerWindow());
mInnerWindowID = pInnerWindow->WindowID();
nsCOMPtr<nsPIDOMWindow> topWindow = pInnerWindow->GetScriptableTop();
if (NS_WARN_IF(!topWindow)) {
return NS_OK;
}
mWindow = do_QueryInterface(topWindow);
if (mWindow) {
mWindow = mWindow->GetOuterWindow();
}
if (NS_WARN_IF(!mWindow)) {
return NS_ERROR_FAILURE;
nsresult rv = FindCorrectWindow(aWindow);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mAudioChannelType = aChannelType;

View File

@ -56,6 +56,8 @@ private:
void Shutdown();
nsresult FindCorrectWindow(nsIDOMWindow* aWindow);
nsCOMPtr<nsPIDOMWindow> mWindow;
nsCOMPtr<nsIAudioChannelAgentCallback> mCallback;

View File

@ -192,7 +192,10 @@ function runTests() {
}
addEventListener('load', function() {
SimpleTest.executeSoon(runTests);
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv({'set': [["b2g.system_manifest_url", "http://mochi.test:8888/manifest.webapp"]]},
function() {
SimpleTest.executeSoon(runTests);
});
});

View File

@ -72,5 +72,8 @@ function runTests() {
}
addEventListener('testready', function() {
SimpleTest.executeSoon(runTests);
SpecialPowers.pushPrefEnv({'set': [["b2g.system_manifest_url", "http://mochi.test:8888/manifest.webapp"]]},
function() {
SimpleTest.executeSoon(runTests);
});
});

View File

@ -68,4 +68,9 @@ function runTest() {
iframe.src = browserElementTestHelpers.emptyPage1;
}
addEventListener('testready', runTest);
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv({'set': [["b2g.system_manifest_url", "http://mochi.test:8888/manifest.webapp"]]},
function() {
SimpleTest.executeSoon(runTest);
});
});