mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1214148 - patch 1 - propagation from the nested iframe back to the toplevel iframe, r=alwu
This commit is contained in:
parent
f0f60b7dff
commit
09dc802de5
@ -5,6 +5,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface mozIApplication;
|
||||
interface nsFrameLoader;
|
||||
interface nsIDocShell;
|
||||
interface nsIURI;
|
||||
@ -214,7 +215,7 @@ class nsFrameLoader;
|
||||
|
||||
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
||||
|
||||
[scriptable, uuid(c4abebcf-55f3-47d4-af15-151311971255)]
|
||||
[scriptable, uuid(adc1b3ba-8deb-4943-8045-e6de0044f2ce)]
|
||||
interface nsIFrameLoaderOwner : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -223,6 +224,12 @@ interface nsIFrameLoaderOwner : nsISupports
|
||||
readonly attribute nsIFrameLoader frameLoader;
|
||||
[noscript, notxpcom] alreadyAddRefed_nsFrameLoader GetFrameLoader();
|
||||
|
||||
/**
|
||||
* The principal of parent mozIApplication in case of nested mozbrowser
|
||||
* iframes.
|
||||
*/
|
||||
readonly attribute mozIApplication parentApplication;
|
||||
|
||||
/**
|
||||
* Puts the FrameLoaderOwner in prerendering mode.
|
||||
*/
|
||||
|
@ -1215,6 +1215,17 @@ nsObjectLoadingContent::GetFrameLoader()
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::GetParentApplication(mozIApplication** aApplication)
|
||||
{
|
||||
if (!aApplication) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aApplication = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SetIsPrerendered()
|
||||
{
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/dom/BrowserElementAudioChannelBinding.h"
|
||||
#include "mozilla/dom/DOMRequest.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
@ -23,16 +25,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
AssertIsInMainProcess()
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -89,7 +81,6 @@ BrowserElementAudioChannel::BrowserElementAudioChannel(
|
||||
, mState(eStateUnknown)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
@ -107,7 +98,6 @@ BrowserElementAudioChannel::BrowserElementAudioChannel(
|
||||
BrowserElementAudioChannel::~BrowserElementAudioChannel()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
@ -173,8 +163,6 @@ AudioChannel
|
||||
BrowserElementAudioChannel::Name() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
return mAudioChannel;
|
||||
}
|
||||
|
||||
@ -361,7 +349,6 @@ already_AddRefed<dom::DOMRequest>
|
||||
BrowserElementAudioChannel::GetVolume(ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
if (!mFrameWindow) {
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
@ -387,7 +374,6 @@ already_AddRefed<dom::DOMRequest>
|
||||
BrowserElementAudioChannel::SetVolume(float aVolume, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
if (!mFrameWindow) {
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
@ -420,7 +406,6 @@ already_AddRefed<dom::DOMRequest>
|
||||
BrowserElementAudioChannel::GetMuted(ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
if (!mFrameWindow) {
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
@ -446,7 +431,6 @@ already_AddRefed<dom::DOMRequest>
|
||||
BrowserElementAudioChannel::SetMuted(bool aMuted, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
if (!mFrameWindow) {
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
@ -479,7 +463,6 @@ already_AddRefed<dom::DOMRequest>
|
||||
BrowserElementAudioChannel::IsActive(ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
|
||||
if (mState != eStateUnknown) {
|
||||
RefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
||||
@ -593,8 +576,29 @@ BrowserElementAudioChannel::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
||||
if (NS_WARN_IF(!wrapper)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
// This can 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) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
Element* element = tabParent->GetOwnerElement();
|
||||
if (!element) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = element->OwnerDoc()->GetWindow();
|
||||
if (window == mFrameWindow) {
|
||||
ProcessStateChanged(aData);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint64_t windowID;
|
||||
|
@ -0,0 +1,76 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 1113086 - tests for AudioChannel API into BrowserElement
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
function runTests() {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
|
||||
|
||||
var listener = function(e) {
|
||||
var message = e.detail.message;
|
||||
if (/^OK/.exec(message)) {
|
||||
ok(true, "Message from app: " + message);
|
||||
} else if (/^KO/.exec(message)) {
|
||||
ok(false, "Message from app: " + message);
|
||||
} else if (/DONE/.exec(message)) {
|
||||
ok(true, "Messaging from app complete");
|
||||
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
|
||||
}
|
||||
}
|
||||
|
||||
function audio_loadend() {
|
||||
ok("mute" in iframe, "iframe.mute exists");
|
||||
ok("unmute" in iframe, "iframe.unmute exists");
|
||||
ok("getMuted" in iframe, "iframe.getMuted exists");
|
||||
ok("getVolume" in iframe, "iframe.getVolume exists");
|
||||
ok("setVolume" in iframe, "iframe.setVolume exists");
|
||||
|
||||
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
|
||||
var channels = iframe.allowedAudioChannels;
|
||||
is(channels.length, 1, "1 audio channel by default");
|
||||
|
||||
var ac = channels[0];
|
||||
|
||||
ok(ac instanceof BrowserElementAudioChannel, "Correct class");
|
||||
ok("getVolume" in ac, "ac.getVolume exists");
|
||||
ok("setVolume" in ac, "ac.setVolume exists");
|
||||
ok("getMuted" in ac, "ac.getMuted exists");
|
||||
ok("setMuted" in ac, "ac.setMuted exists");
|
||||
ok("isActive" in ac, "ac.isActive exists");
|
||||
|
||||
info("Setting the volume...");
|
||||
ac.setVolume(0.5);
|
||||
|
||||
ac.onactivestatechanged = function() {
|
||||
ok(true, "activestatechanged event received.");
|
||||
ac.onactivestatechanged = null;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
iframe.addEventListener('mozbrowserloadend', audio_loadend);
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', listener, false);
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
var context = { 'url': 'http://example.org',
|
||||
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
'isInBrowserElement': true };
|
||||
SpecialPowers.pushPermissions([
|
||||
{'type': 'browser', 'allow': 1, 'context': context},
|
||||
{'type': 'embed-apps', 'allow': 1, 'context': context}
|
||||
], function() {
|
||||
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AudioChannel_nested.html';
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener('testready', function() {
|
||||
SimpleTest.executeSoon(runTests);
|
||||
});
|
@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
|
||||
function ok(a, msg) {
|
||||
alert((!!a ? "OK" : "KO") + " " + msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
ok(a === b, msg);
|
||||
}
|
||||
|
||||
function finish(a, b, msg) {
|
||||
alert("DONE");
|
||||
}
|
||||
|
||||
addEventListener('load', function(e) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
// set 'remote' to true here will make the the iframe remote in _inproc_
|
||||
// test and in-process in _oop_ test.
|
||||
iframe.setAttribute('remote', 'true');
|
||||
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
|
||||
|
||||
iframe.addEventListener('mozbrowserloadend', function(e) {
|
||||
ok("mute" in iframe, "iframe.mute exists");
|
||||
ok("unmute" in iframe, "iframe.unmute exists");
|
||||
ok("getMuted" in iframe, "iframe.getMuted exists");
|
||||
ok("getVolume" in iframe, "iframe.getVolume exists");
|
||||
ok("setVolume" in iframe, "iframe.setVolume exists");
|
||||
|
||||
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
|
||||
var channels = iframe.allowedAudioChannels;
|
||||
is(channels.length, 1, "1 audio channel by default");
|
||||
|
||||
var ac = channels[0];
|
||||
|
||||
ok(ac instanceof BrowserElementAudioChannel, "Correct class");
|
||||
ok("getVolume" in ac, "ac.getVolume exists");
|
||||
ok("setVolume" in ac, "ac.setVolume exists");
|
||||
ok("getMuted" in ac, "ac.getMuted exists");
|
||||
ok("setMuted" in ac, "ac.setMuted exists");
|
||||
ok("isActive" in ac, "ac.isActive exists");
|
||||
|
||||
ac.onactivestatechanged = function() {
|
||||
ok("activestatechanged event received.");
|
||||
|
||||
ac.getVolume().onsuccess = function(e) {
|
||||
ok(e.target.result, 1, "Default volume is 1");
|
||||
};
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_audio.html';
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -121,6 +121,7 @@ disabled = bug 924771
|
||||
disabled = bug 924771
|
||||
[test_browserElement_oop_GetContentDimensions.html]
|
||||
[test_browserElement_oop_AudioChannel.html]
|
||||
[test_browserElement_oop_AudioChannel_nested.html]
|
||||
[test_browserElement_oop_SetNFCFocus.html]
|
||||
[test_browserElement_oop_getWebManifest.html]
|
||||
[test_browserElement_oop_OpenWindowEmpty.html]
|
||||
|
@ -83,11 +83,13 @@ support-files =
|
||||
browserElement_XFrameOptionsSameOrigin.js
|
||||
browserElement_GetContentDimensions.js
|
||||
browserElement_AudioChannel.js
|
||||
browserElement_AudioChannel_nested.js
|
||||
file_browserElement_AlertInFrame.html
|
||||
file_browserElement_AlertInFrame_Inner.html
|
||||
file_browserElement_AllowEmbedAppsInNestedOOIframe.html
|
||||
file_browserElement_AppFramePermission.html
|
||||
file_browserElement_AppWindowNamespace.html
|
||||
file_browserElement_AudioChannel_nested.html
|
||||
file_browserElement_Viewmode.html
|
||||
file_browserElement_ThemeColor.html
|
||||
file_browserElement_BrowserWindowNamespace.html
|
||||
@ -250,6 +252,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
|
||||
disabled = bug 774100
|
||||
[test_browserElement_inproc_GetContentDimensions.html]
|
||||
[test_browserElement_inproc_AudioChannel.html]
|
||||
[test_browserElement_inproc_AudioChannel_nested.html]
|
||||
[test_browserElement_inproc_SetNFCFocus.html]
|
||||
[test_browserElement_inproc_getStructuredData.html]
|
||||
[test_browserElement_inproc_OpenWindowEmpty.html]
|
||||
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test of browser element audioChannel in nested mozbrowser iframes.</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_AudioChannel_nested.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test of browser element audioChannel.</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_AudioChannel_nested.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -563,12 +563,18 @@ nsBrowserElement::GetAllowedAudioChannels(
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIApplication> parentApp;
|
||||
aRv = GetParentApplication(getter_AddRefs(parentApp));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
|
||||
("nsBrowserElement, GetAllowedAudioChannels, this = %p\n", this));
|
||||
|
||||
GenerateAllowedAudioChannels(window, frameLoader, mBrowserElementAPI,
|
||||
manifestURL, mBrowserElementAudioChannels,
|
||||
aRv);
|
||||
manifestURL, parentApp,
|
||||
mBrowserElementAudioChannels, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
@ -583,6 +589,7 @@ nsBrowserElement::GenerateAllowedAudioChannels(
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
const nsAString& aManifestURL,
|
||||
mozIApplication* aParentApp,
|
||||
nsTArray<RefPtr<BrowserElementAudioChannel>>& aAudioChannels,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -625,6 +632,19 @@ nsBrowserElement::GenerateAllowedAudioChannels(
|
||||
permissionName.AssignASCII("audio-channel-");
|
||||
permissionName.AppendASCII(audioChannelTable[i].tag);
|
||||
|
||||
// In case of nested iframes we want to check if the parent has the
|
||||
// permission to use this AudioChannel.
|
||||
if (aParentApp) {
|
||||
aRv = aParentApp->HasPermission(permissionName.get(), &allowed);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!allowed) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = app->HasPermission(permissionName.get(), &allowed);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
|
@ -125,11 +125,14 @@ public:
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
const nsAString& aManifestURL,
|
||||
mozIApplication* aParentApp,
|
||||
nsTArray<RefPtr<dom::BrowserElementAudioChannel>>& aAudioChannels,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
NS_IMETHOD_(already_AddRefed<nsFrameLoader>) GetFrameLoader() = 0;
|
||||
NS_IMETHOD GetParentApplication(mozIApplication** aApplication) = 0;
|
||||
|
||||
void InitBrowserElementAPI();
|
||||
nsCOMPtr<nsIBrowserElementAPI> mBrowserElementAPI;
|
||||
nsTArray<RefPtr<dom::BrowserElementAudioChannel>> mBrowserElementAudioChannels;
|
||||
|
@ -191,6 +191,35 @@ nsGenericHTMLFrameElement::GetFrameLoader()
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::GetParentApplication(mozIApplication** aApplication)
|
||||
{
|
||||
if (!aApplication) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aApplication = nullptr;
|
||||
|
||||
uint32_t appId;
|
||||
nsIPrincipal *principal = NodePrincipal();
|
||||
nsresult rv = principal->GetAppId(&appId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
if (NS_WARN_IF(!appsService)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = appsService->GetAppByLocalId(appId, aApplication);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(7615408c-1fb3-4128-8dd5-a3e2f3fa8842)]
|
||||
[builtinclass, scriptable, uuid(8e49f7b0-1f98-4939-bf91-e9c39cd56434)]
|
||||
interface nsITabParent : nsISupports
|
||||
{
|
||||
void injectTouchEvent(in AString aType,
|
||||
|
@ -1616,6 +1616,17 @@ nsXULElement::GetFrameLoader()
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::GetParentApplication(mozIApplication** aApplication)
|
||||
{
|
||||
if (!aApplication) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aApplication = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::SetIsPrerendered()
|
||||
{
|
||||
|
@ -412,6 +412,7 @@ public:
|
||||
virtual mozilla::EventStates IntrinsicState() const override;
|
||||
|
||||
nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
|
||||
nsresult GetParentApplication(mozIApplication** aApplication);
|
||||
nsresult SetIsPrerendered();
|
||||
nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user