Bug 1192101 - Part 1 - Support PresentationRequest / PresentationAvailability / getSession(s). Part 1 - WebIDL Bindings. r=smaug

This commit is contained in:
Sean Lin 2015-09-14 10:39:57 +08:00
parent c59ebacca3
commit 702df0ae17
22 changed files with 542 additions and 195 deletions

View File

@ -685,7 +685,6 @@ GK_ATOM(onantennaavailablechange, "onantennaavailablechange")
GK_ATOM(onAppCommand, "onAppCommand")
GK_ATOM(onattributechanged, "onattributechanged")
GK_ATOM(onaudioprocess, "onaudioprocess")
GK_ATOM(onavailablechange, "onavailablechange")
GK_ATOM(onbeforecopy, "onbeforecopy")
GK_ATOM(onbeforecut, "onbeforecut")
GK_ATOM(onbeforepaste, "onbeforepaste")
@ -886,6 +885,8 @@ GK_ATOM(onselectionchange, "onselectionchange")
GK_ATOM(onselectstart, "onselectstart")
GK_ATOM(onsending, "onsending")
GK_ATOM(onsent, "onsent")
GK_ATOM(onsessionavailable, "onsessionavailable")
GK_ATOM(onsessionconnect, "onsessionconnect")
GK_ATOM(onset, "onset")
GK_ATOM(onshow, "onshow")
GK_ATOM(onshutter, "onshutter")

View File

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/dom/PresentationAvailableEvent.h"
#include "mozilla/dom/PresentationBinding.h"
#include "mozilla/dom/Promise.h"
#include "nsCycleCollectionParticipant.h"
@ -23,19 +22,22 @@ using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_CLASS(Presentation)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Presentation, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSession)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDefaultRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingGetSessionPromises)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Presentation, DOMEventTargetHelper)
tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSession)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDefaultRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessions)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingGetSessionPromises)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(Presentation, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(Presentation, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Presentation)
NS_INTERFACE_MAP_ENTRY(nsIPresentationListener)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
/* static */ already_AddRefed<Presentation>
@ -47,7 +49,6 @@ Presentation::Create(nsPIDOMWindow* aWindow)
Presentation::Presentation(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow)
, mAvailable(false)
{
}
@ -65,61 +66,61 @@ Presentation::Init()
return false;
}
nsresult rv = service->RegisterListener(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
nsCOMPtr<nsIPresentationDeviceManager> deviceManager =
do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID);
if (NS_WARN_IF(!deviceManager)) {
return false;
}
deviceManager->GetDeviceAvailable(&mAvailable);
// Check if a session instance is required now. The receiver requires a
// session instance is ready at beginning because the web content may access
// it right away; whereas the sender doesn't until |startSession| succeeds.
// Check if a session instance is required now. A session may already be
// connecting before the web content gets loaded in a presenting browsing
// context (receiver).
nsAutoString sessionId;
rv = service->GetExistentSessionIdAtLaunch(GetOwner()->WindowID(), sessionId);
nsresult rv = service->GetExistentSessionIdAtLaunch(GetOwner()->WindowID(),
sessionId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!sessionId.IsEmpty()) {
mSession = PresentationSession::Create(GetOwner(), sessionId,
PresentationSessionState::Disconnected);
if (NS_WARN_IF(!mSession)) {
nsRefPtr<PresentationSession> session =
PresentationSession::Create(GetOwner(), sessionId,
PresentationSessionState::Disconnected);
if (NS_WARN_IF(!session)) {
return false;
}
mSessions.AppendElement(session);
}
// TODO Register listener for incoming sessions.
return true;
}
void Presentation::Shutdown()
{
mSession = nullptr;
mDefaultRequest = nullptr;
mSessions.Clear();
mPendingGetSessionPromises.Clear();
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if (NS_WARN_IF(!service)) {
return;
}
nsresult rv = service->UnregisterListener(this);
NS_WARN_IF(NS_FAILED(rv));
// TODO Unregister listener for incoming sessions.
}
/* virtual */ JSObject*
Presentation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
Presentation::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return PresentationBinding::Wrap(aCx, this, aGivenProto);
}
void
Presentation::SetDefaultRequest(PresentationRequest* aRequest)
{
mDefaultRequest = aRequest;
}
already_AddRefed<PresentationRequest>
Presentation::GetDefaultRequest() const
{
nsRefPtr<PresentationRequest> request = mDefaultRequest;
return request.forget();
}
already_AddRefed<Promise>
Presentation::StartSession(const nsAString& aUrl,
const Optional<nsAString>& aId,
ErrorResult& aRv)
Presentation::GetSession(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (NS_WARN_IF(!global)) {
@ -127,94 +128,37 @@ Presentation::StartSession(const nsAString& aUrl,
return nullptr;
}
// Get the origin.
nsAutoString origin;
nsresult rv = nsContentUtils::GetUTFOrigin(global->PrincipalOrNull(), origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// Ensure there's something to select.
if (NS_WARN_IF(!mAvailable)) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
// Ensure the URL is not empty.
if (NS_WARN_IF(aUrl.IsEmpty())) {
promise->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR);
return promise.forget();
}
// Generate an ID if it's not assigned.
nsAutoString id;
if (aId.WasPassed()) {
id = aId.Value();
// If there's no existing session, leave the promise pending until a
// connecting request arrives from the controlling browsing context (sender).
// http://w3c.github.io/presentation-api/#dom-presentation-getsession
if (!mSessions.IsEmpty()) {
promise->MaybeResolve(mSessions[0]);
} else {
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1");
if(NS_WARN_IF(!uuidgen)) {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
return promise.forget();
}
nsID uuid;
uuidgen->GenerateUUIDInPlace(&uuid);
char buffer[NSID_LENGTH];
uuid.ToProvidedString(buffer);
CopyASCIItoUTF16(buffer, id);
}
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if(NS_WARN_IF(!service)) {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
return promise.forget();
}
nsCOMPtr<nsIPresentationServiceCallback> callback =
new PresentationRequesterCallback(GetOwner(), aUrl, id, promise);
rv = service->StartSession(aUrl, id, origin, callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
mPendingGetSessionPromises.AppendElement(promise);
}
return promise.forget();
}
already_AddRefed<PresentationSession>
Presentation::GetSession() const
already_AddRefed<Promise>
Presentation::GetSessions(ErrorResult& aRv) const
{
nsRefPtr<PresentationSession> session = mSession;
return session.forget();
}
bool
Presentation::CachedAvailable() const
{
return mAvailable;
}
NS_IMETHODIMP
Presentation::NotifyAvailableChange(bool aAvailable)
{
mAvailable = aAvailable;
PresentationAvailableEventInit init;
init.mAvailable = mAvailable;
nsRefPtr<PresentationAvailableEvent> event =
PresentationAvailableEvent::Constructor(this,
NS_LITERAL_STRING("availablechange"),
init);
event->SetTrusted(true);
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, event);
return asyncDispatcher->PostDOMEvent();
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
promise->MaybeResolve(mSessions);
return promise.forget();
}

View File

@ -8,44 +8,49 @@
#define mozilla_dom_Presentation_h
#include "mozilla/DOMEventTargetHelper.h"
#include "nsIPresentationListener.h"
namespace mozilla {
namespace dom {
class Promise;
class PresentationRequest;
class PresentationSession;
class Presentation final : public DOMEventTargetHelper
, public nsIPresentationListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Presentation,
DOMEventTargetHelper)
NS_DECL_NSIPRESENTATIONLISTENER
static already_AddRefed<Presentation> Create(nsPIDOMWindow* aWindow);
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// WebIDL (public APIs)
already_AddRefed<Promise> StartSession(const nsAString& aUrl,
const Optional<nsAString>& aId,
ErrorResult& aRv);
already_AddRefed<PresentationSession> GetSession() const;
bool CachedAvailable() const;
IMPL_EVENT_HANDLER(availablechange);
void SetDefaultRequest(PresentationRequest* aRequest);
already_AddRefed<PresentationRequest> GetDefaultRequest() const;
already_AddRefed<Promise> GetSession(ErrorResult& aRv);
already_AddRefed<Promise> GetSessions(ErrorResult& aRv) const;
IMPL_EVENT_HANDLER(sessionavailable);
private:
explicit Presentation(nsPIDOMWindow* aWindow);
~Presentation();
bool Init();
void Shutdown();
bool mAvailable;
nsRefPtr<PresentationSession> mSession;
nsRefPtr<PresentationRequest> mDefaultRequest;
nsTArray<nsRefPtr<PresentationSession>> mSessions;
nsTArray<nsRefPtr<Promise>> mPendingGetSessionPromises;
};
} // namespace dom

View File

@ -0,0 +1,81 @@
/* -*- 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 "mozilla/dom/PresentationAvailabilityBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIPresentationDeviceManager.h"
#include "nsIPresentationService.h"
#include "nsServiceManagerUtils.h"
#include "PresentationAvailability.h"
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationAvailability)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationAvailability, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationAvailability, DOMEventTargetHelper)
tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(PresentationAvailability, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(PresentationAvailability, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationAvailability)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
/* static */ already_AddRefed<PresentationAvailability>
PresentationAvailability::Create(nsPIDOMWindow* aWindow)
{
nsRefPtr<PresentationAvailability> availability = new PresentationAvailability(aWindow);
return NS_WARN_IF(!availability->Init()) ? nullptr : availability.forget();
}
PresentationAvailability::PresentationAvailability(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow)
, mIsAvailable(false)
{
}
PresentationAvailability::~PresentationAvailability()
{
Shutdown();
}
bool
PresentationAvailability::Init()
{
// TODO Register listener for availability change.
nsCOMPtr<nsIPresentationDeviceManager> deviceManager =
do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID);
if (NS_WARN_IF(!deviceManager)) {
return false;
}
deviceManager->GetDeviceAvailable(&mIsAvailable);
return true;
}
void PresentationAvailability::Shutdown()
{
// TODO Unregister listener for availability change.
}
/* virtual */ JSObject*
PresentationAvailability::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return PresentationAvailabilityBinding::Wrap(aCx, this, aGivenProto);
}
bool
PresentationAvailability::Value() const
{
return mIsAvailable;
}

View File

@ -0,0 +1,47 @@
/* -*- 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_PresentationAvailability_h
#define mozilla_dom_PresentationAvailability_h
#include "mozilla/DOMEventTargetHelper.h"
namespace mozilla {
namespace dom {
class PresentationAvailability final : public DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationAvailability,
DOMEventTargetHelper)
static already_AddRefed<PresentationAvailability> Create(nsPIDOMWindow* aWindow);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// WebIDL (public APIs)
bool Value() const;
IMPL_EVENT_HANDLER(change);
private:
explicit PresentationAvailability(nsPIDOMWindow* aWindow);
~PresentationAvailability();
bool Init();
void Shutdown();
bool mIsAvailable;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PresentationAvailability_h

View File

@ -0,0 +1,150 @@
/* -*- 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 "mozilla/dom/PresentationRequestBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozIThirdPartyUtil.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIPresentationService.h"
#include "nsIUUIDGenerator.h"
#include "nsServiceManagerUtils.h"
#include "PresentationAvailability.h"
#include "PresentationCallbacks.h"
#include "PresentationRequest.h"
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_INHERITED(PresentationRequest, DOMEventTargetHelper,
mAvailability)
NS_IMPL_ADDREF_INHERITED(PresentationRequest, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(PresentationRequest, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationRequest)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
/* static */ already_AddRefed<PresentationRequest>
PresentationRequest::Constructor(const GlobalObject& aGlobal,
const nsAString& aUrl,
ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
if (!window) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
// Ensure the URL is not empty.
if (NS_WARN_IF(aUrl.IsEmpty())) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr;
}
nsRefPtr<PresentationRequest> request = new PresentationRequest(window, aUrl);
return NS_WARN_IF(!request->Init()) ? nullptr : request.forget();
}
PresentationRequest::PresentationRequest(nsPIDOMWindow* aWindow,
const nsAString& aUrl)
: DOMEventTargetHelper(aWindow)
, mUrl(aUrl)
{
}
PresentationRequest::~PresentationRequest()
{
}
bool
PresentationRequest::Init()
{
mAvailability = PresentationAvailability::Create(GetOwner());
if (NS_WARN_IF(!mAvailability)) {
return false;
}
return true;
}
/* virtual */ JSObject*
PresentationRequest::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return PresentationRequestBinding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<Promise>
PresentationRequest::Start(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
// Get the origin.
nsAutoString origin;
nsresult rv = nsContentUtils::GetUTFOrigin(global->PrincipalOrNull(), origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// Generate a session ID.
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1");
if(NS_WARN_IF(!uuidgen)) {
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
return promise.forget();
}
nsID uuid;
uuidgen->GenerateUUIDInPlace(&uuid);
char buffer[NSID_LENGTH];
uuid.ToProvidedString(buffer);
nsAutoString id;
CopyASCIItoUTF16(buffer, id);
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if(NS_WARN_IF(!service)) {
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
return promise.forget();
}
nsCOMPtr<nsIPresentationServiceCallback> callback =
new PresentationRequesterCallback(GetOwner(), mUrl, id, promise);
rv = service->StartSession(mUrl, id, origin, callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
}
return promise.forget();
}
already_AddRefed<Promise>
PresentationRequest::GetAvailability(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
promise->MaybeResolve(mAvailability);
return promise.forget();
}

View File

@ -0,0 +1,54 @@
/* -*- 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_PresentationRequest_h
#define mozilla_dom_PresentationRequest_h
#include "mozilla/DOMEventTargetHelper.h"
namespace mozilla {
namespace dom {
class Promise;
class PresentationAvailability;
class PresentationRequest final : public DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationRequest,
DOMEventTargetHelper)
static already_AddRefed<PresentationRequest> Constructor(const GlobalObject& aGlobal,
const nsAString& aUrl,
ErrorResult& aRv);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// WebIDL (public APIs)
already_AddRefed<Promise> Start(ErrorResult& aRv);
already_AddRefed<Promise> GetAvailability(ErrorResult& aRv);
IMPL_EVENT_HANDLER(sessionconnect);
private:
PresentationRequest(nsPIDOMWindow* aWindow,
const nsAString& aUrl);
~PresentationRequest();
bool Init();
nsString mUrl;
nsRefPtr<PresentationAvailability> mAvailability;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PresentationRequest_h

View File

@ -30,7 +30,7 @@ struct TerminateRequest
nsString sessionId;
};
union PresentationRequest
union PresentationIPCRequest
{
StartSessionRequest;
SendSessionMessageRequest;
@ -56,7 +56,7 @@ parent:
RegisterSessionHandler(nsString aSessionId);
UnregisterSessionHandler(nsString aSessionId);
PPresentationRequest(PresentationRequest aRequest);
PPresentationRequest(PresentationIPCRequest aRequest);
NotifyReceiverReady(nsString aSessionId);
};

View File

@ -44,7 +44,7 @@ PresentationChild::ActorDestroy(ActorDestroyReason aWhy)
}
PPresentationRequestChild*
PresentationChild::AllocPPresentationRequestChild(const PresentationRequest& aRequest)
PresentationChild::AllocPPresentationRequestChild(const PresentationIPCRequest& aRequest)
{
NS_NOTREACHED("We should never be manually allocating PPresentationRequestChild actors");
return nullptr;

View File

@ -26,7 +26,7 @@ public:
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PPresentationRequestChild*
AllocPPresentationRequestChild(const PresentationRequest& aRequest) override;
AllocPPresentationRequestChild(const PresentationIPCRequest& aRequest) override;
virtual bool
DeallocPPresentationRequestChild(PPresentationRequestChild* aActor) override;

View File

@ -78,7 +78,7 @@ PresentationIPCService::Terminate(const nsAString& aSessionId)
nsresult
PresentationIPCService::SendRequest(nsIPresentationServiceCallback* aCallback,
const PresentationRequest& aRequest)
const PresentationIPCRequest& aRequest)
{
if (sPresentationChild) {
PresentationRequestChild* actor = new PresentationRequestChild(aCallback);

View File

@ -16,7 +16,7 @@ class nsIDocShell;
namespace mozilla {
namespace dom {
class PresentationRequest;
class PresentationIPCRequest;
class PresentationResponderLoadingCallback;
class PresentationIPCService final : public nsIPresentationService
@ -43,7 +43,7 @@ public:
private:
virtual ~PresentationIPCService();
nsresult SendRequest(nsIPresentationServiceCallback* aCallback,
const PresentationRequest& aRequest);
const PresentationIPCRequest& aRequest);
nsTObserverArray<nsCOMPtr<nsIPresentationListener> > mListeners;
nsRefPtrHashtable<nsStringHashKey, nsIPresentationSessionListener> mSessionListeners;

View File

@ -54,23 +54,23 @@ PresentationParent::ActorDestroy(ActorDestroyReason aWhy)
bool
PresentationParent::RecvPPresentationRequestConstructor(
PPresentationRequestParent* aActor,
const PresentationRequest& aRequest)
const PresentationIPCRequest& aRequest)
{
PresentationRequestParent* actor = static_cast<PresentationRequestParent*>(aActor);
nsresult rv = NS_ERROR_FAILURE;
switch (aRequest.type()) {
case PresentationRequest::TStartSessionRequest:
case PresentationIPCRequest::TStartSessionRequest:
rv = actor->DoRequest(aRequest.get_StartSessionRequest());
break;
case PresentationRequest::TSendSessionMessageRequest:
case PresentationIPCRequest::TSendSessionMessageRequest:
rv = actor->DoRequest(aRequest.get_SendSessionMessageRequest());
break;
case PresentationRequest::TTerminateRequest:
case PresentationIPCRequest::TTerminateRequest:
rv = actor->DoRequest(aRequest.get_TerminateRequest());
break;
default:
MOZ_CRASH("Unknown PresentationRequest type");
MOZ_CRASH("Unknown PresentationIPCRequest type");
}
return NS_WARN_IF(NS_FAILED(rv)) ? false : true;
@ -78,7 +78,7 @@ PresentationParent::RecvPPresentationRequestConstructor(
PPresentationRequestParent*
PresentationParent::AllocPPresentationRequestParent(
const PresentationRequest& aRequest)
const PresentationIPCRequest& aRequest)
{
MOZ_ASSERT(mService);
nsRefPtr<PresentationRequestParent> actor = new PresentationRequestParent(mService);

View File

@ -32,10 +32,10 @@ public:
virtual bool
RecvPPresentationRequestConstructor(PPresentationRequestParent* aActor,
const PresentationRequest& aRequest) override;
const PresentationIPCRequest& aRequest) override;
virtual PPresentationRequestParent*
AllocPPresentationRequestParent(const PresentationRequest& aRequest) override;
AllocPPresentationRequestParent(const PresentationIPCRequest& aRequest) override;
virtual bool
DeallocPPresentationRequestParent(PPresentationRequestParent* aActor) override;

View File

@ -14,8 +14,10 @@ EXPORTS.mozilla.dom += [
'ipc/PresentationIPCService.h',
'ipc/PresentationParent.h',
'Presentation.h',
'PresentationAvailability.h',
'PresentationCallbacks.h',
'PresentationDeviceManager.h',
'PresentationRequest.h',
'PresentationService.h',
'PresentationSession.h',
'PresentationSessionInfo.h',
@ -27,8 +29,10 @@ UNIFIED_SOURCES += [
'ipc/PresentationIPCService.cpp',
'ipc/PresentationParent.cpp',
'Presentation.cpp',
'PresentationAvailability.cpp',
'PresentationCallbacks.cpp',
'PresentationDeviceManager.cpp',
'PresentationRequest.cpp',
'PresentationService.cpp',
'PresentationSession.cpp',
'PresentationSessionInfo.cpp',

View File

@ -931,6 +931,16 @@ var interfaceNamesInGlobalScope =
{name: "PresentationDeviceInfoManager",
disabled: true,
permission: ["presentation-device-manage"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Presentation", disabled: true, permission: ["presentation"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationAvailability", disabled: true, permission: ["presentation"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationRequest", disabled: true, permission: ["presentation"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationSession", disabled: true, permission: ["presentation"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationSessionConnectEvent", disabled: true, permission: ["presentation"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
"ProcessingInstruction",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -432,7 +432,7 @@ partial interface Navigator {
};
partial interface Navigator {
[Throws, Pref="dom.presentation.enabled", CheckAnyPermissions="presentation", AvailableIn="PrivilegedApps"]
[Throws, Pref="dom.presentation.enabled", CheckAnyPermissions="presentation", AvailableIn="PrivilegedApps", SameObject]
readonly attribute Presentation? presentation;
};

View File

@ -8,57 +8,37 @@
CheckAnyPermissions="presentation",
AvailableIn="PrivilegedApps"]
interface Presentation : EventTarget {
/*
* This should be used by the UA as the default presentation request for the
* controller. When the UA wishes to initiate a PresentationSession on the
* controller's behalf, it MUST start a presentation session using the default
* presentation request (as if the controller had called |defaultRequest.start()|).
*
* Only used by controlling browsing context (senders).
*/
attribute PresentationRequest? defaultRequest;
/*
* A requesting page use startSession() to start a new session, and the
* session will be returned with the promise. UA may show a prompt box with a
* list of available devices and ask the user to grant permission, choose a
* device, or cancel the operation.
* Get the first connected presentation session in a presenting browsing
* context.
*
* @url: The URL of presenting page.
* @sessionId: Optional. If it's not specified, a random alphanumeric value of
* at least 16 characters drawn from the character [A-Za-z0-9] is
* automatically generated as the id of the session.
*
* The promise is resolved when the presenting page is successfully loaded and
* the communication channel is established, i.e., the session state is
* "connected".
*
* The promise may be rejected duo to one of the following reasons:
* - "InternalError": Unexpected internal error occurs.
* - "NoDeviceAvailable": No available device.
* - "PermissionDenied": User dismiss the device prompt box.
* - "ControlChannelFailed": Failed to establish control channel.
* - "NoApplicationFound": app:// scheme is supported on Firefox OS, but no
* corresponding application is found on remote side.
* - "PageLoadTimeout": Presenting page takes too long to load.
* - "DataChannelFailed": Failed to establish data channel.
* Only used by presenting browsing context (receivers).
*/
[Throws]
Promise<PresentationSession> startSession(DOMString url,
optional DOMString sessionId);
Promise<PresentationSession> getSession();
/*
* This attribute is only available on the presenting page. It should be
* created when loading the presenting page, and it's ready to be used after
* 'onload' event is dispatched.
* Get all connected presentation sessions in a presenting browsing context.
*
* Only used by presenting browsing context (receivers).
*/
[Pure]
readonly attribute PresentationSession? session;
/*
* Device availability. If there is more than one device discovered by UA,
* the value is |true|. Otherwise, its value should be |false|.
*
* UA triggers device discovery mechanism periodically and cache the latest
* result in this attribute. Thus, it may be out-of-date when we're not in
* discovery mode, however, it is still useful to give the developers an idea
* that whether there are devices nearby some time ago.
*/
readonly attribute boolean cachedAvailable;
[Throws]
Promise<sequence<PresentationSession>> getSessions();
/*
* It is called when device availability changes. New value is dispatched with
* the event.
* It is called when an incoming session is connecting.
*
* Only used by presenting browsing context (receivers).
*/
attribute EventHandler onavailablechange;
attribute EventHandler onsessionavailable;
};

View File

@ -0,0 +1,21 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
[Pref="dom.presentation.enabled",
CheckAnyPermissions="presentation",
AvailableIn="PrivilegedApps"]
interface PresentationAvailability : EventTarget {
/*
* If there is at least one device discovered by UA, the value is |true|.
* Otherwise, its value should be |false|.
*/
readonly attribute boolean value;
/*
* It is called when device availability changes.
*/
attribute EventHandler onchange;
};

View File

@ -0,0 +1,47 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
[Constructor(DOMString url),
Pref="dom.presentation.enabled",
CheckAnyPermissions="presentation",
AvailableIn="PrivilegedApps"]
interface PresentationRequest : EventTarget {
/*
* A requesting page use start() to start a new session, and the session will
* be returned with the promise. UA may show a prompt box with a list of
* available devices and ask the user to grant permission, choose a device, or
* cancel the operation.
*
* The promise is resolved when the presenting page is successfully loaded and
* the communication channel is established, i.e., the session state is
* "connected".
*
* The promise may be rejected duo to one of the following reasons:
* - "OperationError": Unexpected error occurs.
* - "NotFoundError": No available device.
* - "AbortError": User dismiss/cancel the device prompt box.
* - "NetworkError": Failed to establish the control channel or data channel.
* - "TimeoutError": Presenting page takes too long to load.
*/
[Throws]
Promise<PresentationSession> start();
/*
* UA triggers device discovery mechanism periodically and monitor device
* availability.
*
* The promise may be rejected duo to one of the following reasons:
* - "NotSupportedError": Unable to continuously monitor the availability.
*/
[Throws]
Promise<PresentationAvailability> getAvailability();
/*
* It is called when a session associated with a PresentationRequest is created.
* The event is fired for all sessions that are created for the controller.
*/
attribute EventHandler onsessionconnect;
};

View File

@ -4,17 +4,18 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Constructor(DOMString typeArg,
optional PresentationAvailableEventInit eventInitDict),
[Constructor(DOMString type,
optional PresentationSessionConnectEventInit eventInitDict),
Pref="dom.presentation.enabled",
CheckAnyPermissions="presentation",
AvailableIn="PrivilegedApps"]
interface PresentationAvailableEvent : Event
interface PresentationSessionConnectEvent : Event
{
readonly attribute boolean available;
[SameObject]
readonly attribute PresentationSession session;
};
dictionary PresentationAvailableEventInit : EventInit
dictionary PresentationSessionConnectEventInit : EventInit
{
boolean available = false;
required PresentationSession session;
};

View File

@ -371,7 +371,9 @@ WEBIDL_FILES = [
'Position.webidl',
'PositionError.webidl',
'Presentation.webidl',
'PresentationAvailability.webidl',
'PresentationDeviceInfoManager.webidl',
'PresentationRequest.webidl',
'PresentationSession.webidl',
'ProcessingInstruction.webidl',
'ProfileTimelineMarker.webidl',
@ -786,7 +788,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'PluginCrashedEvent.webidl',
'PopStateEvent.webidl',
'PopupBlockedEvent.webidl',
'PresentationAvailableEvent.webidl',
'PresentationSessionConnectEvent.webidl',
'ProgressEvent.webidl',
'RecordErrorEvent.webidl',
'ScrollViewChangeEvent.webidl',