Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #41 from KershawChang/presentationAPI
Browse files Browse the repository at this point in the history
Bug 1197690 - Presentation API
  • Loading branch information
xeonchen committed Aug 9, 2016
2 parents 2410b6a + cb4655d commit 9db666a
Show file tree
Hide file tree
Showing 57 changed files with 2,094 additions and 94 deletions.
1 change: 1 addition & 0 deletions dom/base/nsGkAtomList.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ GK_ATOM(allowfullscreen, "allowfullscreen")
GK_ATOM(alloworientationlock,"allow-orientation-lock")
GK_ATOM(allowpointerlock,"allow-pointer-lock")
GK_ATOM(allowpopups,"allow-popups")
GK_ATOM(allowpresentation,"allow-presentation")
GK_ATOM(allowsameorigin,"allow-same-origin")
GK_ATOM(allowscripts,"allow-scripts")
GK_ATOM(allowtopnavigation,"allow-top-navigation")
Expand Down
5 changes: 5 additions & 0 deletions dom/base/nsSandboxFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,9 @@ const unsigned long SANDBOXED_AUXILIARY_NAVIGATION = 0x200;
* This flag prevents locking screen orientation.
*/
const unsigned long SANDBOXED_ORIENTATION_LOCK = 0x400;

/**
* This flag disables the Presentation API.
*/
const unsigned long SANDBOXED_PRESENTATION = 0x800;
#endif
116 changes: 116 additions & 0 deletions dom/presentation/ControllerConnectionCollection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "ControllerConnectionCollection.h"

#include "mozilla/ClearOnShutdown.h"
#include "nsIPresentationService.h"
#include "PresentationConnection.h"

namespace mozilla {
namespace dom {

/* static */
StaticAutoPtr<ControllerConnectionCollection>
ControllerConnectionCollection::sSingleton;

/* static */ ControllerConnectionCollection*
ControllerConnectionCollection::GetSingleton()
{
MOZ_ASSERT(NS_IsMainThread());

if (!sSingleton) {
sSingleton = new ControllerConnectionCollection();
ClearOnShutdown(&sSingleton);
}

return sSingleton;
}

ControllerConnectionCollection::ControllerConnectionCollection()
{
MOZ_COUNT_CTOR(ControllerConnectionCollection);
}

ControllerConnectionCollection::~ControllerConnectionCollection()
{
MOZ_COUNT_DTOR(ControllerConnectionCollection);
}

void
ControllerConnectionCollection::AddConnection(
PresentationConnection* aConnection,
const uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
MOZ_ASSERT(false, "This is allowed only to be called at controller side.");
return;
}

if (!aConnection) {
return;
}

WeakPtr<PresentationConnection> connection = aConnection;
if (mConnections.Contains(connection)) {
return;
}

mConnections.AppendElement(connection);
}

void
ControllerConnectionCollection::RemoveConnection(
PresentationConnection* aConnection,
const uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
MOZ_ASSERT(false, "This is allowed only to be called at controller side.");
return;
}

if (!aConnection) {
return;
}

WeakPtr<PresentationConnection> connection = aConnection;
mConnections.RemoveElement(connection);
}

already_AddRefed<PresentationConnection>
ControllerConnectionCollection::FindConnection(
uint64_t aWindowId,
const nsAString& aId,
const uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
MOZ_ASSERT(false, "This is allowed only to be called at controller side.");
return nullptr;
}

// Loop backwards to allow removing elements in the loop.
for (int i = mConnections.Length() - 1; i >= 0; --i) {
WeakPtr<PresentationConnection> connection = mConnections[i];
if (!connection) {
// The connection was destroyed. Remove it from the list.
mConnections.RemoveElementAt(i);
continue;
}

if (connection->Equals(aWindowId, aId)) {
RefPtr<PresentationConnection> matchedConnection = connection.get();
return matchedConnection.forget();
}
}

return nullptr;
}

} // namespace dom
} // namespace mozilla
49 changes: 49 additions & 0 deletions dom/presentation/ControllerConnectionCollection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */

#ifndef mozilla_dom_ControllerConnectionCollection_h
#define mozilla_dom_ControllerConnectionCollection_h

#include "mozilla/StaticPtr.h"
#include "mozilla/WeakPtr.h"
#include "nsString.h"
#include "nsTArray.h"

namespace mozilla {
namespace dom {

class PresentationConnection;

class ControllerConnectionCollection final
{
public:
static ControllerConnectionCollection* GetSingleton();

void AddConnection(PresentationConnection* aConnection,
const uint8_t aRole);

void RemoveConnection(PresentationConnection* aConnection,
const uint8_t aRole);

already_AddRefed<PresentationConnection>
FindConnection(uint64_t aWindowId,
const nsAString& aId,
const uint8_t aRole);

private:
friend class StaticAutoPtr<ControllerConnectionCollection>;

ControllerConnectionCollection();
virtual ~ControllerConnectionCollection();

static StaticAutoPtr<ControllerConnectionCollection> sSingleton;
nsTArray<WeakPtr<PresentationConnection>> mConnections;
};

} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_ControllerConnectionCollection_h
13 changes: 12 additions & 1 deletion dom/presentation/Presentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
* 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 "Presentation.h"

#include "mozilla/dom/PresentationBinding.h"
#include "mozilla/dom/Promise.h"
#include "nsContentUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDocShell.h"
#include "nsIPresentationService.h"
#include "nsSandboxFlags.h"
#include "nsServiceManagerUtils.h"
#include "Presentation.h"
#include "PresentationReceiver.h"

using namespace mozilla;
Expand Down Expand Up @@ -56,6 +58,15 @@ Presentation::SetDefaultRequest(PresentationRequest* aRequest)
return;
}

nsCOMPtr<nsIDocument> doc = GetOwner() ? GetOwner()->GetExtantDoc() : nullptr;
if (NS_WARN_IF(!doc)) {
return;
}

if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) {
return;
}

mDefaultRequest = aRequest;
}

Expand Down
74 changes: 71 additions & 3 deletions dom/presentation/PresentationCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "PresentationCallbacks.h"
#include "PresentationRequest.h"
#include "PresentationConnection.h"
#include "nsThreadUtils.h"

using namespace mozilla;
using namespace mozilla::dom;
Expand All @@ -28,6 +29,7 @@ PresentationRequesterCallback::PresentationRequesterCallback(PresentationRequest
const nsAString& aSessionId,
Promise* aPromise)
: mRequest(aRequest)
, mUrl(aUrl)
, mSessionId(aSessionId)
, mPromise(aPromise)
{
Expand All @@ -46,10 +48,8 @@ PresentationRequesterCallback::NotifySuccess()
{
MOZ_ASSERT(NS_IsMainThread());

// At the sender side, this function must get called after the transport
// channel is ready. So we simply set the connection state as connected.
RefPtr<PresentationConnection> connection =
PresentationConnection::Create(mRequest->GetOwner(), mSessionId,
PresentationConnection::Create(mRequest->GetOwner(), mSessionId, mUrl,
nsIPresentationService::ROLE_CONTROLLER);
if (NS_WARN_IF(!connection)) {
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
Expand All @@ -74,6 +74,74 @@ PresentationRequesterCallback::NotifyError(nsresult aError)
* Implementation of PresentationRequesterCallback
*/

NS_IMPL_ISUPPORTS_INHERITED0(PresentationReconnectCallback,
PresentationRequesterCallback)

PresentationReconnectCallback::PresentationReconnectCallback(
PresentationRequest* aRequest,
const nsAString& aUrl,
const nsAString& aSessionId,
Promise* aPromise,
PresentationConnection* aConnection)
: PresentationRequesterCallback(aRequest, aUrl, aSessionId, aPromise)
, mConnection(aConnection)
{
}

PresentationReconnectCallback::~PresentationReconnectCallback()
{
}

NS_IMETHODIMP
PresentationReconnectCallback::NotifySuccess()
{
MOZ_ASSERT(NS_IsMainThread());

nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!service)) {
return NS_ERROR_NOT_AVAILABLE;
}

nsresult rv = NS_OK;
// We found a matched connection with the same window ID, URL, and
// the session ID. Resolve the promise with this connection and dispatch
// the event.
if (mConnection) {
mPromise->MaybeResolve(mConnection);
rv = mRequest->DispatchConnectionAvailableEvent(mConnection);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
// Use |PresentationRequesterCallback::NotifySuccess| to create a new
// connection since we don't find one that can be reused.
rv = PresentationRequesterCallback::NotifySuccess();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

rv = service->UpdateWindowIdBySessionId(mSessionId,
mRequest->GetOwner()->WindowID());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}

nsString sessionId = nsString(mSessionId);
return NS_DispatchToMainThread(
NS_NewRunnableFunction([sessionId, service]() -> void {
service->BuildTransport(sessionId,
nsIPresentationService::ROLE_CONTROLLER);
}));
}

NS_IMETHODIMP
PresentationReconnectCallback::NotifyError(nsresult aError)
{
return PresentationRequesterCallback::NotifyError(aError);
}

NS_IMPL_ISUPPORTS(PresentationResponderLoadingCallback,
nsIWebProgressListener,
nsISupportsWeakReference)
Expand Down
26 changes: 23 additions & 3 deletions dom/presentation/PresentationCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ class nsIWebProgress;
namespace mozilla {
namespace dom {

class PresentationConnection;
class PresentationRequest;
class Promise;

class PresentationRequesterCallback final : public nsIPresentationServiceCallback
class PresentationRequesterCallback : public nsIPresentationServiceCallback
{
public:
NS_DECL_ISUPPORTS
Expand All @@ -34,14 +35,33 @@ class PresentationRequesterCallback final : public nsIPresentationServiceCallbac
const nsAString& aSessionId,
Promise* aPromise);

private:
~PresentationRequesterCallback();
protected:
virtual ~PresentationRequesterCallback();

RefPtr<PresentationRequest> mRequest;
nsString mUrl;
nsString mSessionId;
RefPtr<Promise> mPromise;
};

class PresentationReconnectCallback final : public PresentationRequesterCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIPRESENTATIONSERVICECALLBACK

PresentationReconnectCallback(PresentationRequest* aRequest,
const nsAString& aUrl,
const nsAString& aSessionId,
Promise* aPromise,
PresentationConnection* aConnection);

private:
virtual ~PresentationReconnectCallback();

RefPtr<PresentationConnection> mConnection;
};

class PresentationResponderLoadingCallback final : public nsIWebProgressListener
, public nsSupportsWeakReference
{
Expand Down
Loading

0 comments on commit 9db666a

Please sign in to comment.