Backed out 3 changesets (bug 1234128) for Android crashtest failures.

Backed out changeset 11db59507360 (bug 1234128)
Backed out changeset 8a0848fb59ac (bug 1234128)
Backed out changeset 7cf300dda85a (bug 1234128)

CLOSED TREE

--HG--
rename : dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe.html => dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe_oop.html
rename : dom/presentation/tests/mochitest/file_presentation_non_receiver.html => dom/presentation/tests/mochitest/file_presentation_non_receiver_oop.html
rename : dom/presentation/tests/mochitest/file_presentation_receiver_inner_iframe.html => dom/presentation/tests/mochitest/file_presentation_receiver_inner_iframe_oop.html
This commit is contained in:
Ryan VanderMeulen 2016-05-19 10:32:02 -04:00
parent 1b2a06e879
commit 9d4120d4eb
28 changed files with 431 additions and 276 deletions

View File

@ -2403,36 +2403,40 @@ Navigator::HasPresentationSupport(JSContext* aCx, JSObject* aGlobal)
// Grant access to browser receiving pages and their same-origin iframes. (App
// pages should be controlled by "presentation" permission in app manifests.)
nsCOMPtr<nsIDocShell> docshell = inner->GetDocShell();
MOZ_ASSERT(docshell);
if (!docshell->GetIsInMozBrowserOrApp()) {
mozilla::dom::ContentChild* cc =
mozilla::dom::ContentChild::GetSingleton();
if (!cc || !cc->IsForBrowser()) {
return false;
}
nsAutoString presentationURL;
nsContentUtils::GetPresentationURL(docshell, presentationURL);
if (presentationURL.IsEmpty()) {
nsCOMPtr<nsPIDOMWindowOuter> win = inner->GetOuterWindow();
nsCOMPtr<nsPIDOMWindowOuter> top = win->GetTop();
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(win);
nsCOMPtr<nsIScriptObjectPrincipal> topSop = do_QueryInterface(top);
if (!sop || !topSop) {
return false;
}
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
if (!securityManager) {
nsIPrincipal* principal = sop->GetPrincipal();
nsIPrincipal* topPrincipal = topSop->GetPrincipal();
if (!principal || !topPrincipal || !principal->Subsumes(topPrincipal)) {
return false;
}
nsCOMPtr<nsIURI> presentationURI;
nsresult rv = NS_NewURI(getter_AddRefs(presentationURI), presentationURL);
if (NS_FAILED(rv)) {
nsCOMPtr<nsPIDOMWindowInner> topInner;
if (!(topInner = top->GetCurrentInnerWindow())) {
return false;
}
nsCOMPtr<nsIURI> docURI = inner->GetDocumentURI();
return NS_SUCCEEDED(securityManager->CheckSameOriginURI(presentationURI,
docURI,
false));
nsCOMPtr<nsIPresentationService> presentationService =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!presentationService)) {
return false;
}
nsAutoString sessionId;
presentationService->GetExistentSessionIdAtLaunch(topInner->WindowID(), sessionId);
return !sessionId.IsEmpty();
}
/* static */

View File

@ -115,7 +115,6 @@
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentType.h"
#include "nsIDOMEvent.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMHTMLInputElement.h"
@ -204,7 +203,6 @@
#include "nsICookieService.h"
#include "mozilla/EnumSet.h"
#include "mozilla/BloomFilter.h"
#include "TabChild.h"
#include "nsIBidiKeyboard.h"
@ -8841,31 +8839,3 @@ nsContentUtils::SetScrollbarsVisibility(nsIDocShell* aDocShell, bool aVisible)
nsIScrollable::ScrollOrientation_X, prefValue);
}
}
/* static */ void
nsContentUtils::GetPresentationURL(nsIDocShell* aDocShell, nsAString& aPresentationUrl)
{
MOZ_ASSERT(aDocShell);
if (XRE_IsContentProcess()) {
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
aDocShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
nsCOMPtr<nsIDocShellTreeItem> root;
aDocShell->GetRootTreeItem(getter_AddRefs(root));
if (sameTypeRoot.get() == root.get()) {
// presentation URL is stored in TabChild for the top most
// <iframe mozbrowser> in content process.
TabChild* tabChild = TabChild::GetFrom(aDocShell);
if (tabChild) {
aPresentationUrl = tabChild->PresentationURL();
}
return;
}
}
nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(aDocShell));
nsCOMPtr<nsIDOMElement> topFrameElement;
loadContext->GetTopFrameElement(getter_AddRefs(topFrameElement));
topFrameElement->GetAttribute(NS_LITERAL_STRING("mozpresentation"), aPresentationUrl);
}

View File

@ -2553,12 +2553,6 @@ public:
static void SetScrollbarsVisibility(nsIDocShell* aDocShell, bool aVisible);
/*
* Return the associated presentation URL of the presented content.
* Will return empty string if the docshell is not in a presented content.
*/
static void GetPresentationURL(nsIDocShell* aDocShell, nsAString& aPresentationUrl);
private:
static bool InitializeEventTable();

View File

@ -3340,18 +3340,12 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
attrs.mUserContextId = userContextId;
}
nsAutoString presentationURLStr;
mOwnerContent->GetAttr(kNameSpaceID_None,
nsGkAtoms::mozpresentation,
presentationURLStr);
bool tabContextUpdated =
aTabContext->SetTabContext(OwnerIsMozBrowserFrame(),
ownApp,
containingApp,
attrs,
signedPkgOrigin,
presentationURLStr);
signedPkgOrigin);
NS_ENSURE_STATE(tabContextUpdated);
return NS_OK;

View File

@ -1014,7 +1014,6 @@ GK_ATOM(predicate, "predicate")
GK_ATOM(prefix, "prefix")
GK_ATOM(preload, "preload")
GK_ATOM(prerendered, "prerendered")
GK_ATOM(mozpresentation, "mozpresentation")
GK_ATOM(preserve, "preserve")
GK_ATOM(preserveSpace, "preserve-space")
GK_ATOM(preventdefault, "preventdefault")

View File

@ -47,11 +47,6 @@ struct FrameIPCTabContext
// Whether this is a mozbrowser frame. <iframe mozbrowser mozapp> and
// <xul:browser> are not considered to be mozbrowser frames.
bool isMozBrowserElement;
// The requested presentation URL.
// This value would be empty if the TabContext isn't created for
// presented content.
nsString presentationURL;
};
// XXXcatalinb: This is only used by ServiceWorkerClients::OpenWindow.

View File

@ -190,19 +190,12 @@ TabContext::SignedPkgOriginNoSuffix() const
return mSignedPkgOriginNoSuffix;
}
const nsAString&
TabContext::PresentationURL() const
{
return mPresentationURL;
}
bool
TabContext::SetTabContext(bool aIsMozBrowserElement,
mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const DocShellOriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix,
const nsAString& aPresentationURL)
const nsACString& aSignedPkgOriginNoSuffix)
{
NS_ENSURE_FALSE(mInitialized, false);
@ -234,7 +227,6 @@ TabContext::SetTabContext(bool aIsMozBrowserElement,
mOwnApp = aOwnApp;
mContainingApp = aAppFrameOwnerApp;
mSignedPkgOriginNoSuffix = aSignedPkgOriginNoSuffix;
mPresentationURL = aPresentationURL;
return true;
}
@ -246,8 +238,7 @@ TabContext::AsIPCTabContext() const
return IPCTabContext(FrameIPCTabContext(originSuffix,
mContainingAppId,
mSignedPkgOriginNoSuffix,
mIsMozBrowserElement,
mPresentationURL));
mIsMozBrowserElement));
}
static already_AddRefed<mozIApplication>
@ -270,7 +261,6 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
DocShellOriginAttributes originAttributes;
nsAutoCString originSuffix;
nsAutoCString signedPkgOriginNoSuffix;
nsAutoString presentationURL;
switch(aParams.type()) {
case IPCTabContext::TPopupIPCTabContext: {
@ -331,7 +321,6 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
isMozBrowserElement = ipcContext.isMozBrowserElement();
containingAppId = ipcContext.frameOwnerAppId();
signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
presentationURL = ipcContext.presentationURL();
originSuffix = ipcContext.originSuffix();
originAttributes.PopulateFromSuffix(originSuffix);
break;
@ -380,8 +369,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
ownApp,
containingApp,
originAttributes,
signedPkgOriginNoSuffix,
presentationURL);
signedPkgOriginNoSuffix);
if (!rv) {
mInvalidReason = "Couldn't initialize TabContext.";
}

View File

@ -130,12 +130,6 @@ public:
*/
const nsACString& SignedPkgOriginNoSuffix() const;
/**
* Returns the presentation URL associated with the tab if this tab is
* created for presented content
*/
const nsAString& PresentationURL() const;
protected:
friend class MaybeInvalidTabContext;
@ -164,8 +158,7 @@ protected:
mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const DocShellOriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix,
const nsAString& aPresentationURL);
const nsACString& aSignedPkgOriginNoSuffix);
/**
* Modify this TabContext to match the given TabContext. This is a special
@ -222,11 +215,6 @@ private:
* doesn't own a signed package, this value would be empty.
*/
nsCString mSignedPkgOriginNoSuffix;
/**
* The requested presentation URL.
*/
nsString mPresentationURL;
};
/**
@ -247,15 +235,13 @@ public:
mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const DocShellOriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString(),
const nsAString& aPresentationURL = EmptyString())
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
{
return TabContext::SetTabContext(aIsMozBrowserElement,
aOwnApp,
aAppFrameOwnerApp,
aOriginAttributes,
aSignedPkgOriginNoSuffix,
aPresentationURL);
aSignedPkgOriginNoSuffix);
}
};

View File

@ -6,9 +6,7 @@
#include "mozilla/dom/PresentationBinding.h"
#include "mozilla/dom/Promise.h"
#include "nsContentUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDocShell.h"
#include "nsIPresentationService.h"
#include "nsServiceManagerUtils.h"
#include "Presentation.h"
@ -30,7 +28,7 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
Presentation::Create(nsPIDOMWindowInner* aWindow)
{
RefPtr<Presentation> presentation = new Presentation(aWindow);
return presentation.forget();
return NS_WARN_IF(!presentation->Init()) ? nullptr : presentation.forget();
}
Presentation::Presentation(nsPIDOMWindowInner* aWindow)
@ -42,6 +40,37 @@ Presentation::~Presentation()
{
}
bool
Presentation::Init()
{
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!service)) {
return false;
}
if (NS_WARN_IF(!GetOwner())) {
return false;
}
// Check if a receiver instance is required now. A session may already be
// connecting before the web content gets loaded in a receiving browsing
// context.
nsAutoString sessionId;
nsresult rv = service->GetExistentSessionIdAtLaunch(GetOwner()->WindowID(), sessionId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!sessionId.IsEmpty()) {
mReceiver = PresentationReceiver::Create(GetOwner(), sessionId);
if (NS_WARN_IF(!mReceiver)) {
return false;
}
}
return true;
}
/* virtual */ JSObject*
Presentation::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
@ -63,36 +92,8 @@ Presentation::GetDefaultRequest() const
}
already_AddRefed<PresentationReceiver>
Presentation::GetReceiver()
Presentation::GetReceiver() const
{
// return the same receiver if already created
if (mReceiver) {
RefPtr<PresentationReceiver> receiver = mReceiver;
return receiver.forget();
}
if (!IsInPresentedContent()) {
return nullptr;
}
mReceiver = PresentationReceiver::Create(GetOwner());
if (NS_WARN_IF(!mReceiver)) {
MOZ_ASSERT(mReceiver);
return nullptr;
}
RefPtr<PresentationReceiver> receiver = mReceiver;
return receiver.forget();
}
bool
Presentation::IsInPresentedContent() const
{
nsCOMPtr<nsIDocShell> docShell = GetOwner()->GetDocShell();
MOZ_ASSERT(docShell);
nsAutoString presentationURL;
nsContentUtils::GetPresentationURL(docShell, presentationURL);
return !presentationURL.IsEmpty();
}

View File

@ -33,14 +33,14 @@ public:
already_AddRefed<PresentationRequest> GetDefaultRequest() const;
already_AddRefed<PresentationReceiver> GetReceiver();
already_AddRefed<PresentationReceiver> GetReceiver() const;
private:
explicit Presentation(nsPIDOMWindowInner* aWindow);
~Presentation();
bool IsInPresentedContent() const;
bool Init();
RefPtr<PresentationRequest> mDefaultRequest;
RefPtr<PresentationReceiver> mReceiver;

View File

@ -37,10 +37,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationReceiver)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
/* static */ already_AddRefed<PresentationReceiver>
PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
PresentationReceiver::Create(nsPIDOMWindowInner* aWindow,
const nsAString& aSessionId)
{
RefPtr<PresentationReceiver> receiver = new PresentationReceiver(aWindow);
return NS_WARN_IF(!receiver->Init()) ? nullptr : receiver.forget();
return NS_WARN_IF(!receiver->Init(aSessionId)) ? nullptr : receiver.forget();
}
PresentationReceiver::PresentationReceiver(nsPIDOMWindowInner* aWindow)
@ -54,36 +55,28 @@ PresentationReceiver::~PresentationReceiver()
}
bool
PresentationReceiver::Init()
PresentationReceiver::Init(const nsAString& aSessionId)
{
if (NS_WARN_IF(!GetOwner())) {
return false;
}
mWindowId = GetOwner()->WindowID();
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!service)) {
return false;
}
// A session may already be connecting before the web content
// request for access in a receiving browsing context.
nsAutoString sessionId;
nsresult rv = service->GetExistentSessionIdAtLaunch(mWindowId, sessionId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!sessionId.IsEmpty()) {
rv = NotifySessionConnect(mWindowId, sessionId);
if (!aSessionId.IsEmpty()) {
nsresult rv = NotifySessionConnect(mWindowId, aSessionId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
}
// Register listener for incoming sessions.
rv = service->RegisterRespondingListener(mWindowId, this);
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!service)) {
return false;
}
nsresult rv = service->RegisterRespondingListener(mWindowId, this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}

View File

@ -25,7 +25,8 @@ public:
DOMEventTargetHelper)
NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER
static already_AddRefed<PresentationReceiver> Create(nsPIDOMWindowInner* aWindow);
static already_AddRefed<PresentationReceiver> Create(nsPIDOMWindowInner* aWindow,
const nsAString& aSessionId);
virtual void DisconnectFromOwner() override;
@ -44,7 +45,7 @@ private:
~PresentationReceiver();
bool Init();
bool Init(const nsAString& aSessionId);
void Shutdown();

View File

@ -257,6 +257,7 @@ const mockedSessionTransport = {
},
// in-process case
buildDataChannelTransport: function(role, window, controlChannel, listener) {
dump("build data channel transport\n");
this._listener = listener;
this._role = role;

View File

@ -13,26 +13,26 @@
function is(a, b, msg) {
if (a === b) {
alert('OK ' + msg);
window.parent.postMessage('OK ' + msg, '*');
} else {
alert('KO ' + msg + ' | reason: ' + a + ' != ' + b);
window.parent.postMessage('KO ' + msg + ' | reason: ' + a + ' != ' + b, '*');
}
}
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
window.parent.postMessage((a ? 'OK ' : 'KO ') + msg, '*');
}
function info(msg) {
alert('INFO ' + msg);
window.parent.postMessage('INFO ' + msg, '*');
}
function command(name, data) {
alert('COMMAND ' + JSON.stringify({name: name, data: data}));
window.parent.postMessage('COMMAND ' + JSON.stringify({name: name, data: data}), '*');
}
function finish() {
alert('DONE');
window.parent.postMessage('DONE', '*');
}
var connection;
@ -41,6 +41,12 @@ function testConnectionAvailable() {
return new Promise(function(aResolve, aReject) {
info('Receiver: --- testConnectionAvailable ---');
ok(navigator.presentation, "Receiver: navigator.presentation should be available.");
// FIXME Sometimes navigator.presentation.receiver is initialized lately.
// See bug 1234128 - navigator.presentation.receiver is null in 1-UA use case.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1234128
while (!navigator.presentation.receiver) {
info('Receiver: navigator.presentation.receiver is null, see Bug 1234128');
}
ok(navigator.presentation.receiver, "Receiver: navigator.presentation.receiver should be available.");
navigator.presentation.receiver.getConnection()
.then((aConnection) => {
@ -89,14 +95,14 @@ function testIncomingMessage() {
function testSendMessage() {
return new Promise(function(aResolve, aReject) {
window.addEventListener('hashchange', function hashchangeHandler(evt) {
var message = JSON.parse(decodeURIComponent(window.location.hash.substring(1)));
window.addEventListener('message', function messageHandler(evt) {
var message = evt.data;
if (message.type === 'trigger-message-from-receiver') {
info('Receiver: --- testSendMessage ---');
connection.send('msg-receiver-to-sender');
}
if (message.type === 'message-from-receiver-received') {
window.removeEventListener('hashchange', hashchangeHandler);
window.removeEventListener('message', messageHandler);
aResolve();
}
});

View File

@ -0,0 +1,137 @@
<!DOCTYPE HTML>
<!-- vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: -->
<html>
<head>
<meta charset="utf-8">
<title>Test for B2G PresentationReceiver at receiver side</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript;version=1.7">
"use strict";
function is(a, b, msg) {
if (a === b) {
alert('OK ' + msg);
} else {
alert('KO ' + msg + ' | reason: ' + a + ' != ' + b);
}
}
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
}
function info(msg) {
alert('INFO ' + msg);
}
function command(name, data) {
alert('COMMAND ' + JSON.stringify({name: name, data: data}));
}
function finish() {
alert('DONE');
}
var connection;
function testConnectionAvailable() {
return new Promise(function(aResolve, aReject) {
info('Receiver: --- testConnectionAvailable ---');
ok(navigator.presentation, "Receiver: navigator.presentation should be available.");
// FIXME Sometimes navigator.presentation.receiver is initialized lately.
// See bug 1234128 - navigator.presentation.receiver is null in 1-UA use case.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1234128
while (!navigator.presentation.receiver) {
info('Receiver: navigator.presentation.receiver is null, see Bug 1234128');
}
ok(navigator.presentation.receiver, "Receiver: navigator.presentation.receiver should be available.");
navigator.presentation.receiver.getConnection()
.then((aConnection) => {
connection = aConnection;
ok(connection.id, "Receiver: Connection ID should be set: " + connection.id);
is(connection.state, "closed", "Connection state at receiver side should be closed by default.");
aResolve();
})
.catch((aError) => {
ok(false, "Receiver: Error occurred when getting the connection: " + aError);
finish();
aReject();
});
});
}
function testConnectionReady() {
return new Promise(function(aResolve, aReject) {
info('Receiver: --- testConnectionReady ---');
connection.onstatechange = function() {
connection.onstatechange = null;
is(connection.state, "connected", "Receiver: Connection state should become connected.");
aResolve();
};
if (connection.state === "connected") {
connection.onstatechange = null;
is(connection.state, "connected", "Receiver: Connection state should become connected.");
aResolve();
}
});
}
function testIncomingMessage() {
return new Promise(function(aResolve, aReject) {
info('Receiver: --- testIncomingMessage ---');
connection.addEventListener('message', function messageHandler(evt) {
connection.removeEventListener('message', messageHandler);
let msg = evt.data;
is(msg, 'msg-sender-to-receiver', 'Receiver: Receiver should receive message from sender.');
command('forward-command', JSON.stringify({ name: 'message-from-sender-received' }));
aResolve();
});
command('forward-command', JSON.stringify({ name: 'trigger-message-from-sender' }));
});
}
function testSendMessage() {
return new Promise(function(aResolve, aReject) {
window.addEventListener('hashchange', function hashchangeHandler(evt) {
var message = JSON.parse(decodeURIComponent(window.location.hash.substring(1)));
if (message.type === 'trigger-message-from-receiver') {
info('Receiver: --- testSendMessage ---');
connection.send('msg-receiver-to-sender');
}
if (message.type === 'message-from-receiver-received') {
window.removeEventListener('hashchange', hashchangeHandler);
aResolve();
}
});
});
}
function testTerminateConnection() {
return new Promise(function(aResolve, aReject) {
info('Receiver: --- testTerminateConnection ---');
connection.onstatechange = function() {
connection.onstatechange = null;
is(connection.state, "terminated", "Receiver: Connection should be terminated.");
aResolve();
};
connection.terminate();
});
}
function runTests() {
testConnectionAvailable()
.then(testConnectionReady)
.then(testIncomingMessage)
.then(testSendMessage)
.then(testTerminateConnection)
.then(finish);
}
runTests();
</script>
</body>
</html>

View File

@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<title>Test for B2G PresentationReceiver at receiver side (OOP)</title>
<title>Test for B2G PresentationReceiver at receiver side</title>
</head>
<body>
<div id="content"></div>
@ -11,31 +11,31 @@
"use strict";
function is(a, b, msg) {
alert((a === b ? 'OK ' : 'KO ') + msg);
window.parent.postMessage((a === b ? 'OK ' : 'KO ') + msg, '*');
}
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
window.parent.postMessage((a ? 'OK ' : 'KO ') + msg, '*');
}
function info(msg) {
alert('INFO ' + msg);
window.parent.postMessage('INFO ' + msg, '*');
}
function command(msg) {
alert('COMMAND ' + JSON.stringify(msg));
window.parent.postMessage('COMMAND ' + JSON.stringify(msg), '*');
}
function finish() {
alert('DONE');
window.parent.postMessage('DONE', '*');
}
var connection;
function testConnectionAvailable() {
return new Promise(function(aResolve, aReject) {
ok(navigator.presentation, "navigator.presentation should be available in OOP receiving pages.");
ok(navigator.presentation.receiver, "navigator.presentation.receiver should be available in OOP receiving pages.");
ok(navigator.presentation, "navigator.presentation should be available.");
ok(navigator.presentation.receiver, "navigator.presentation.receiver should be available.");
navigator.presentation.receiver.getConnection().then(
function(aConnection) {
@ -54,26 +54,6 @@ function testConnectionAvailable() {
});
}
function testConnectionAvailableSameOriginInnerIframe() {
return new Promise(function(aResolve, aReject) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', './file_presentation_receiver_inner_iframe.html');
document.body.appendChild(iframe);
aResolve();
});
}
function testConnectionUnavailableDiffOriginInnerIframe() {
return new Promise(function(aResolve, aReject) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', 'http://example.com/tests/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe.html');
document.body.appendChild(iframe);
aResolve();
});
}
function testConnectionReady() {
return new Promise(function(aResolve, aReject) {
connection.onstatechange = function() {
@ -97,7 +77,7 @@ function testIncomingMessage() {
});
command({ name: 'trigger-incoming-message',
data: incomingMessage });
data: incomingMessage });
});
}
@ -114,8 +94,6 @@ function testTerminateConnection() {
}
testConnectionAvailable().
then(testConnectionAvailableSameOriginInnerIframe).
then(testConnectionUnavailableDiffOriginInnerIframe).
then(testConnectionReady).
then(testIncomingMessage).
then(testTerminateConnection).

View File

@ -11,27 +11,23 @@
"use strict";
function is(a, b, msg) {
if (a === b) {
alert('OK ' + msg);
} else {
alert('KO ' + msg + ' | reason: ' + a + ' != ' + b);
}
window.parent.postMessage((a === b ? 'OK ' : 'KO ') + msg, '*');
}
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
window.parent.postMessage((a ? 'OK ' : 'KO ') + msg, '*');
}
function info(msg) {
alert('INFO ' + msg);
window.parent.postMessage('INFO ' + msg, '*');
}
function command(name, data) {
alert('COMMAND ' + JSON.stringify({name: name, data: data}));
function command(msg) {
window.parent.postMessage('COMMAND ' + JSON.stringify(msg), '*');
}
function finish() {
alert('DONE');
window.parent.postMessage('DONE', '*');
}
var connection;
@ -67,7 +63,7 @@ function testUnexpectedControlChannelClose() {
};
// Trigger the control channel to be closed with error code.
command('trigger-control-channel-close', 0x80004004 /* NS_ERROR_ABORT */);
command({ name: 'trigger-control-channel-close', data: 0x80004004 /* NS_ERROR_ABORT */ });
});
}

View File

@ -0,0 +1,129 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for B2G PresentationReceiver at receiver side (OOP)</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript;version=1.7">
"use strict";
function is(a, b, msg) {
alert((a === b ? 'OK ' : 'KO ') + msg);
}
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
}
function info(msg) {
alert('INFO ' + msg);
}
function command(msg) {
alert('COMMAND ' + JSON.stringify(msg));
}
function finish() {
alert('DONE');
}
var connection;
function testConnectionAvailable() {
return new Promise(function(aResolve, aReject) {
ok(navigator.presentation, "navigator.presentation should be available in OOP receiving pages.");
ok(navigator.presentation.receiver, "navigator.presentation.receiver should be available in OOP receiving pages.");
navigator.presentation.receiver.getConnection().then(
function(aConnection) {
connection = aConnection;
ok(connection.id, "Connection ID should be set: " + connection.id);
is(connection.state, "closed", "Connection state at receiver side should be closed by default.");
aResolve();
},
function(aError) {
ok(false, "Error occurred when getting the connection: " + aError);
finish();
aReject();
}
);
});
}
function testConnectionAvailableSameOriginInnerIframe() {
return new Promise(function(aResolve, aReject) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', './file_presentation_receiver_inner_iframe_oop.html');
document.body.appendChild(iframe);
aResolve();
});
}
function testConnectionUnavailableDiffOriginInnerIframe() {
return new Promise(function(aResolve, aReject) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', 'http://example.com/tests/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe_oop.html');
document.body.appendChild(iframe);
aResolve();
});
}
function testConnectionReady() {
return new Promise(function(aResolve, aReject) {
connection.onstatechange = function() {
connection.onstatechange = null;
is(connection.state, "connected", "Connection state should become connected.");
aResolve();
};
command({ name: 'trigger-incoming-offer' });
});
}
function testIncomingMessage() {
return new Promise(function(aResolve, aReject) {
const incomingMessage = "test incoming message";
connection.addEventListener('message', function messageHandler(aEvent) {
connection.removeEventListener('message', messageHandler);
is(aEvent.data, incomingMessage, "An incoming message should be received.");
aResolve();
});
command({ name: 'trigger-incoming-message',
data: incomingMessage });
});
}
function testTerminateConnection() {
return new Promise(function(aResolve, aReject) {
connection.onstatechange = function() {
connection.onstatechange = null;
is(connection.state, "terminated", "Connection should be terminated.");
aResolve();
};
connection.terminate();
});
}
testConnectionAvailable().
// TODO Bug 1234128 - Fix the timing issue for navigator.presentation.receiver.
// This test fails intermittently under some edge cases. Disable it for now until
// the issue gets fixed.
// then(testConnectionAvailableSameOriginInnerIframe).
then(testConnectionUnavailableDiffOriginInnerIframe).
then(testConnectionReady).
then(testIncomingMessage).
then(testTerminateConnection).
then(finish);
</script>
</body>
</html>

View File

@ -4,11 +4,13 @@ support-files =
PresentationSessionChromeScript.js
PresentationSessionChromeScript1UA.js
file_presentation_1ua_receiver.html
file_presentation_non_receiver_inner_iframe.html
file_presentation_non_receiver.html
file_presentation_1ua_receiver_oop.html
file_presentation_non_receiver_inner_iframe_oop.html
file_presentation_non_receiver_oop.html
file_presentation_receiver.html
file_presentation_receiver_establish_connection_error.html
file_presentation_receiver_inner_iframe.html
file_presentation_receiver_inner_iframe_oop.html
file_presentation_receiver_oop.html
[test_presentation_dc_sender.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785

View File

@ -26,9 +26,26 @@ var request;
var connection;
var receiverIframe;
// This event is triggered when the iframe calls "postMessage".
window.addEventListener('message', function messageHandler(evt) {
var message = evt.data;
if (/^OK /.exec(message)) {
ok(true, message.replace(/^OK /, ''));
} else if (/^KO /.exec(message)) {
ok(false, message.replace(/^KO /, ''));
} else if (/^INFO /.exec(message)) {
info(message.replace(/^INFO /, ''));
} else if (/^COMMAND /.exec(message)) {
var command = JSON.parse(message.replace(/^COMMAND /, ''));
gScript.sendAsyncMessage(command.name, command.data);
} else if (/^DONE$/.exec(message)) {
window.removeEventListener('message', messageHandler);
teardown();
}
}, false);
function postMessageToIframe(aType) {
receiverIframe.src = receiverUrl + "#" +
encodeURIComponent(JSON.stringify({ type: aType }));
receiverIframe.contentWindow.postMessage({ type: aType }, '*');
}
function setup() {
@ -44,33 +61,11 @@ function setup() {
gScript.removeMessageListener('control-channel-established', controlChannelEstablishedHandler);
receiverIframe = document.createElement('iframe');
receiverIframe.setAttribute('src', receiverUrl);
receiverIframe.setAttribute("mozbrowser", "true");
receiverIframe.setAttribute("mozpresentation", receiverUrl);
receiverIframe.onload = function() {
info('Receiver loaded.');
gScript.sendAsyncMessage('trigger-control-channel-open');
};
// This event is triggered when the iframe calls "alert".
receiverIframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) {
var message = evt.detail.message;
debug('Got iframe message: ' + message);
if (/^OK /.exec(message)) {
ok(true, message.replace(/^OK /, ""));
} else if (/^KO /.exec(message)) {
ok(false, message.replace(/^KO /, ""));
} else if (/^INFO /.exec(message)) {
info(message.replace(/^INFO /, ""));
} else if (/^COMMAND /.exec(message)) {
var command = JSON.parse(message.replace(/^COMMAND /, ""));
gScript.sendAsyncMessage(command.name, command.data);
} else if (/^DONE$/.exec(message)) {
receiverIframe.removeEventListener("mozbrowsershowmodalprompt",
receiverListener);
teardown();
}
}, false);
var promise = new Promise(function(aResolve, aReject) {
document.body.appendChild(receiverIframe);
aResolve(receiverIframe);
@ -205,12 +200,10 @@ SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPermissions([
{type: 'presentation-device-manage', allow: false, context: document},
{type: 'presentation', allow: true, context: document},
{type: "browser", allow: true, context: document},
], () => {
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
["dom.presentation.test.enabled", true],
["dom.presentation.test.stage", 0],
["dom.mozBrowserFramesEnabled", true]]},
["dom.presentation.test.stage", 0]]},
runTests);
});

View File

@ -17,7 +17,7 @@
'use strict';
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js'));
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_receiver.html');
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_receiver_oop.html');
var request;
var connection;
var receiverIframe;
@ -46,7 +46,6 @@ function setup() {
receiverIframe = document.createElement('iframe');
receiverIframe.setAttribute("remote", "true");
receiverIframe.setAttribute("mozbrowser", "true");
receiverIframe.setAttribute("mozpresentation", receiverUrl);
receiverIframe.setAttribute('src', receiverUrl);
receiverIframe.addEventListener("mozbrowserloadend", function mozbrowserloadendHander() {
receiverIframe.removeEventListener("mozbrowserloadend", mozbrowserloadendHander);

View File

@ -29,24 +29,23 @@ function setup() {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', receiverUrl);
iframe.setAttribute("mozbrowser", "true");
iframe.setAttribute("mozpresentation", receiverUrl);
// This event is triggered when the iframe calls "alert".
iframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) {
var message = evt.detail.message;
// This event is triggered when the iframe calls "postMessage".
window.addEventListener('message', function listener(aEvent) {
var message = aEvent.data;
if (/^OK /.exec(message)) {
ok(true, message.replace(/^OK /, ""));
ok(true, "Message from iframe: " + message);
} else if (/^KO /.exec(message)) {
ok(false, message.replace(/^KO /, ""));
ok(false, "Message from iframe: " + message);
} else if (/^INFO /.exec(message)) {
info(message.replace(/^INFO /, ""));
info("Message from iframe: " + message);
} else if (/^COMMAND /.exec(message)) {
var command = JSON.parse(message.replace(/^COMMAND /, ""));
var command = JSON.parse(message.replace(/^COMMAND /, ''));
gScript.sendAsyncMessage(command.name, command.data);
} else if (/^DONE$/.exec(message)) {
iframe.removeEventListener("mozbrowsershowmodalprompt",
receiverListener);
ok(true, "Messaging from iframe complete.");
window.removeEventListener('message', listener);
teardown();
}
}, false);
@ -126,11 +125,9 @@ SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPermissions([
{type: 'presentation-device-manage', allow: false, context: document},
{type: 'presentation', allow: true, context: document},
{type: "browser", allow: true, context: document},
], function() {
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
["dom.presentation.session_transport.data_channel.enable", true],
["dom.mozBrowserFramesEnabled", true]]},
["dom.presentation.session_transport.data_channel.enable", true]]},
runTests);
});

View File

@ -28,13 +28,11 @@ function setup() {
gScript.sendAsyncMessage('trigger-device-add');
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.setAttribute('mozpresentation', receiverUrl);
iframe.setAttribute('src', receiverUrl);
// This event is triggered when the iframe calls "postMessage".
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(aEvent) {
var message = aEvent.detail.message;
window.addEventListener('message', function listener(aEvent) {
var message = aEvent.data;
if (/^OK /.exec(message)) {
ok(true, "Message from iframe: " + message);
} else if (/^KO /.exec(message)) {
@ -46,7 +44,7 @@ function setup() {
gScript.sendAsyncMessage(command.name, command.data);
} else if (/^DONE$/.exec(message)) {
ok(true, "Messaging from iframe complete.");
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
window.removeEventListener('message', listener);
teardown();
}
@ -122,10 +120,8 @@ SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPermissions([
{type: 'presentation-device-manage', allow: false, context: document},
{type: 'presentation', allow: true, context: document},
{type: 'browser', allow: true, context: document},
], function() {
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
["dom.mozBrowserFramesEnabled", true],
["dom.presentation.session_transport.data_channel.enable", false]]},
runTests);
});

View File

@ -26,24 +26,23 @@ function setup() {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', receiverUrl);
iframe.setAttribute("mozbrowser", "true");
iframe.setAttribute("mozpresentation", receiverUrl);
// This event is triggered when the iframe calls "alert".
iframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) {
var message = evt.detail.message;
// This event is triggered when the iframe calls "postMessage".
window.addEventListener('message', function listener(aEvent) {
var message = aEvent.data;
if (/^OK /.exec(message)) {
ok(true, message.replace(/^OK /, ""));
ok(true, "Message from iframe: " + message);
} else if (/^KO /.exec(message)) {
ok(false, message.replace(/^KO /, ""));
ok(false, "Message from iframe: " + message);
} else if (/^INFO /.exec(message)) {
info(message.replace(/^INFO /, ""));
info("Message from iframe: " + message);
} else if (/^COMMAND /.exec(message)) {
var command = JSON.parse(message.replace(/^COMMAND /, ""));
var command = JSON.parse(message.replace(/^COMMAND /, ''));
gScript.sendAsyncMessage(command.name, command.data);
} else if (/^DONE$/.exec(message)) {
iframe.removeEventListener("mozbrowsershowmodalprompt",
receiverListener);
ok(true, "Messaging from iframe complete.");
window.removeEventListener('message', listener);
teardown();
}
}, false);
@ -96,11 +95,9 @@ SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPermissions([
{type: 'presentation-device-manage', allow: false, context: document},
{type: 'presentation', allow: true, context: document},
{type: "browser", allow: true, context: document},
], function() {
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
["dom.presentation.session_transport.data_channel.enable", false],
["dom.mozBrowserFramesEnabled", true]]},
["dom.presentation.session_transport.data_channel.enable", false]]},
runTests);
});

View File

@ -18,8 +18,8 @@
'use strict';
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_receiver.html');
var nonReceiverUrl = SimpleTest.getTestFileURL('file_presentation_non_receiver.html');
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_receiver_oop.html');
var nonReceiverUrl = SimpleTest.getTestFileURL('file_presentation_non_receiver_oop.html');
var isReceiverFinished = false;
var isNonReceiverFinished = false;
@ -35,7 +35,6 @@ function setup() {
var receiverIframe = document.createElement('iframe');
receiverIframe.setAttribute('remote', 'true');
receiverIframe.setAttribute('mozbrowser', 'true');
receiverIframe.setAttribute('mozpresentation', receiverUrl);
receiverIframe.setAttribute('src', receiverUrl);
// This event is triggered when the iframe calls "alert".