mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1258602 - Part1: Add PresentationConnectionList, r=smaug
This commit is contained in:
parent
6ba3ad8ecf
commit
70abe8c5e3
@ -50,8 +50,7 @@ PresentationRequesterCallback::NotifySuccess()
|
||||
// channel is ready. So we simply set the connection state as connected.
|
||||
RefPtr<PresentationConnection> connection =
|
||||
PresentationConnection::Create(mRequest->GetOwner(), mSessionId,
|
||||
nsIPresentationService::ROLE_CONTROLLER,
|
||||
PresentationConnectionState::Connected);
|
||||
nsIPresentationService::ROLE_CONTROLLER);
|
||||
if (NS_WARN_IF(!connection)) {
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
return NS_OK;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "PresentationConnection.h"
|
||||
#include "PresentationConnectionList.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -20,10 +21,12 @@ using namespace mozilla::dom;
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationConnection)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningConnectionList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
||||
tmp->Shutdown();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningConnectionList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
||||
@ -36,10 +39,11 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aId,
|
||||
const uint8_t aRole,
|
||||
PresentationConnectionState aState)
|
||||
PresentationConnectionList* aList)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mId(aId)
|
||||
, mState(aState)
|
||||
, mState(PresentationConnectionState::Connecting)
|
||||
, mOwningConnectionList(aList)
|
||||
{
|
||||
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
||||
aRole == nsIPresentationService::ROLE_RECEIVER);
|
||||
@ -54,12 +58,12 @@ PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
|
||||
PresentationConnection::Create(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aId,
|
||||
const uint8_t aRole,
|
||||
PresentationConnectionState aState)
|
||||
PresentationConnectionList* aList)
|
||||
{
|
||||
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
||||
aRole == nsIPresentationService::ROLE_RECEIVER);
|
||||
RefPtr<PresentationConnection> connection =
|
||||
new PresentationConnection(aWindow, aId, aRole, aState);
|
||||
new PresentationConnection(aWindow, aId, aRole, aList);
|
||||
return NS_WARN_IF(!connection->Init()) ? nullptr : connection.forget();
|
||||
}
|
||||
|
||||
@ -186,6 +190,9 @@ PresentationConnection::NotifyStateChange(const nsAString& aSessionId,
|
||||
|
||||
PresentationConnectionState state;
|
||||
switch (aState) {
|
||||
case nsIPresentationSessionListener::STATE_CONNECTING:
|
||||
state = PresentationConnectionState::Connecting;
|
||||
break;
|
||||
case nsIPresentationSessionListener::STATE_CONNECTED:
|
||||
state = PresentationConnectionState::Connected;
|
||||
break;
|
||||
@ -220,7 +227,16 @@ PresentationConnection::NotifyStateChange(const nsAString& aSessionId,
|
||||
}
|
||||
}
|
||||
|
||||
return DispatchStateChangeEvent();
|
||||
nsresult rv = DispatchStateChangeEvent();
|
||||
if(NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mOwningConnectionList) {
|
||||
mOwningConnectionList->NotifyStateChange(aSessionId, this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -14,6 +14,8 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class PresentationConnectionList;
|
||||
|
||||
class PresentationConnection final : public DOMEventTargetHelper
|
||||
, public nsIPresentationSessionListener
|
||||
{
|
||||
@ -23,10 +25,11 @@ public:
|
||||
DOMEventTargetHelper)
|
||||
NS_DECL_NSIPRESENTATIONSESSIONLISTENER
|
||||
|
||||
static already_AddRefed<PresentationConnection> Create(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aId,
|
||||
const uint8_t aRole,
|
||||
PresentationConnectionState aState);
|
||||
static already_AddRefed<PresentationConnection>
|
||||
Create(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aId,
|
||||
const uint8_t aRole,
|
||||
PresentationConnectionList* aList = nullptr);
|
||||
|
||||
virtual void DisconnectFromOwner() override;
|
||||
|
||||
@ -52,7 +55,7 @@ private:
|
||||
PresentationConnection(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aId,
|
||||
const uint8_t aRole,
|
||||
PresentationConnectionState aState);
|
||||
PresentationConnectionList* aList);
|
||||
|
||||
~PresentationConnection();
|
||||
|
||||
@ -67,6 +70,7 @@ private:
|
||||
nsString mId;
|
||||
uint8_t mRole;
|
||||
PresentationConnectionState mState;
|
||||
RefPtr<PresentationConnectionList> mOwningConnectionList;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
125
dom/presentation/PresentationConnectionList.cpp
Normal file
125
dom/presentation/PresentationConnectionList.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/* -*- 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 "PresentationConnectionList.h"
|
||||
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/dom/PresentationConnectionAvailableEvent.h"
|
||||
#include "mozilla/dom/PresentationConnectionListBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "PresentationConnection.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(PresentationConnectionList, DOMEventTargetHelper,
|
||||
mGetConnectionListPromise,
|
||||
mConnections)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(PresentationConnectionList, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(PresentationConnectionList, DOMEventTargetHelper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationConnectionList)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
PresentationConnectionList::PresentationConnectionList(nsPIDOMWindowInner* aWindow,
|
||||
Promise* aPromise)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mGetConnectionListPromise(aPromise)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aPromise);
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
PresentationConnectionList::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return PresentationConnectionListBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
PresentationConnectionList::GetConnections(
|
||||
nsTArray<RefPtr<PresentationConnection>>& aConnections) const
|
||||
{
|
||||
aConnections = mConnections;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationConnectionList::DispatchConnectionAvailableEvent(
|
||||
PresentationConnection* aConnection)
|
||||
{
|
||||
PresentationConnectionAvailableEventInit init;
|
||||
init.mConnection = aConnection;
|
||||
|
||||
RefPtr<PresentationConnectionAvailableEvent> event =
|
||||
PresentationConnectionAvailableEvent::Constructor(
|
||||
this,
|
||||
NS_LITERAL_STRING("connectionavailable"),
|
||||
init);
|
||||
|
||||
if (NS_WARN_IF(!event)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
event->SetTrusted(true);
|
||||
|
||||
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(this, event);
|
||||
return asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
|
||||
PresentationConnectionList::ConnectionArrayIndex
|
||||
PresentationConnectionList::FindConnectionById(
|
||||
const nsAString& aId)
|
||||
{
|
||||
for (ConnectionArrayIndex i = 0; i < mConnections.Length(); i++) {
|
||||
nsAutoString id;
|
||||
mConnections[i]->GetId(id);
|
||||
if (id == nsAutoString(aId)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return mConnections.NoIndex;
|
||||
}
|
||||
|
||||
void
|
||||
PresentationConnectionList::NotifyStateChange(const nsAString& aSessionId,
|
||||
PresentationConnection* aConnection)
|
||||
{
|
||||
if (!aConnection) {
|
||||
MOZ_ASSERT(false, "PresentationConnection can not be null.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool connectionFound =
|
||||
FindConnectionById(aSessionId) != mConnections.NoIndex ? true : false;
|
||||
|
||||
PresentationConnectionListBinding::ClearCachedConnectionsValue(this);
|
||||
switch (aConnection->State()) {
|
||||
case PresentationConnectionState::Connected:
|
||||
if (!connectionFound) {
|
||||
mConnections.AppendElement(aConnection);
|
||||
if (mGetConnectionListPromise) {
|
||||
mGetConnectionListPromise->MaybeResolve(this);
|
||||
mGetConnectionListPromise = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
DispatchConnectionAvailableEvent(aConnection);
|
||||
break;
|
||||
case PresentationConnectionState::Terminated:
|
||||
if (connectionFound) {
|
||||
mConnections.RemoveElement(aConnection);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
57
dom/presentation/PresentationConnectionList.h
Normal file
57
dom/presentation/PresentationConnectionList.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- 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_PresentationConnectionList_h
|
||||
#define mozilla_dom_PresentationConnectionList_h
|
||||
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class PresentationConnection;
|
||||
class Promise;
|
||||
|
||||
class PresentationConnectionList final : public DOMEventTargetHelper
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationConnectionList,
|
||||
DOMEventTargetHelper)
|
||||
|
||||
PresentationConnectionList(nsPIDOMWindowInner* aWindow,
|
||||
Promise* aPromise);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void GetConnections(nsTArray<RefPtr<PresentationConnection>>& aConnections) const;
|
||||
|
||||
void NotifyStateChange(const nsAString& aSessionId, PresentationConnection* aConnection);
|
||||
|
||||
IMPL_EVENT_HANDLER(connectionavailable);
|
||||
|
||||
private:
|
||||
virtual ~PresentationConnectionList() = default;
|
||||
|
||||
nsresult DispatchConnectionAvailableEvent(PresentationConnection* aConnection);
|
||||
|
||||
typedef nsTArray<RefPtr<PresentationConnection>> ConnectionArray;
|
||||
typedef ConnectionArray::index_type ConnectionArrayIndex;
|
||||
|
||||
ConnectionArrayIndex FindConnectionById(const nsAString& aId);
|
||||
|
||||
RefPtr<Promise> mGetConnectionListPromise;
|
||||
|
||||
// This array stores only non-terminsted connections.
|
||||
ConnectionArray mConnections;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_PresentationConnectionList_h
|
@ -4,37 +4,31 @@
|
||||
* 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/AsyncEventDispatcher.h"
|
||||
#include "PresentationReceiver.h"
|
||||
|
||||
#include "mozilla/dom/PresentationReceiverBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIPresentationService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PresentationReceiver.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "PresentationConnection.h"
|
||||
#include "PresentationConnectionList.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationReceiver)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PresentationReceiver,
|
||||
mOwner,
|
||||
mGetConnectionListPromise,
|
||||
mConnectionList)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationReceiver, DOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnections)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingGetConnectionPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationReceiver)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationReceiver)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationReceiver, DOMEventTargetHelper)
|
||||
tmp->Shutdown();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConnections)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingGetConnectionPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(PresentationReceiver, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(PresentationReceiver, DOMEventTargetHelper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationReceiver)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationReceiver)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPresentationRespondingListener)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
/* static */ already_AddRefed<PresentationReceiver>
|
||||
PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
|
||||
@ -44,8 +38,9 @@ PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
|
||||
}
|
||||
|
||||
PresentationReceiver::PresentationReceiver(nsPIDOMWindowInner* aWindow)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
: mOwner(aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
}
|
||||
|
||||
PresentationReceiver::~PresentationReceiver()
|
||||
@ -56,31 +51,16 @@ PresentationReceiver::~PresentationReceiver()
|
||||
bool
|
||||
PresentationReceiver::Init()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Register listener for incoming sessions.
|
||||
nsresult rv = service->RegisterRespondingListener(mWindowId, this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (NS_WARN_IF(!mOwner)) {
|
||||
return false;
|
||||
}
|
||||
mWindowId = mOwner->WindowID();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PresentationReceiver::Shutdown()
|
||||
{
|
||||
mConnections.Clear();
|
||||
mPendingGetConnectionPromises.Clear();
|
||||
|
||||
// Unregister listener for incoming sessions.
|
||||
nsCOMPtr<nsIPresentationService> service =
|
||||
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
||||
@ -92,13 +72,6 @@ void PresentationReceiver::Shutdown()
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
PresentationReceiver::DisconnectFromOwner()
|
||||
{
|
||||
Shutdown();
|
||||
DOMEventTargetHelper::DisconnectFromOwner();
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
PresentationReceiver::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
@ -106,86 +79,88 @@ PresentationReceiver::WrapObject(JSContext* aCx,
|
||||
return PresentationReceiverBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
PresentationReceiver::GetConnection(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (NS_WARN_IF(!global)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If there's no existing connection, leave the promise pending until a
|
||||
// connecting request arrives from the controlling browsing context (sender).
|
||||
// http://w3c.github.io/presentation-api/#dom-presentation-getconnection
|
||||
if (!mConnections.IsEmpty()) {
|
||||
promise->MaybeResolve(mConnections[0]);
|
||||
} else {
|
||||
mPendingGetConnectionPromises.AppendElement(promise);
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
PresentationReceiver::GetConnections(ErrorResult& aRv) const
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (NS_WARN_IF(!global)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(mConnections);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationReceiver::NotifySessionConnect(uint64_t aWindowId,
|
||||
const nsAString& aSessionId)
|
||||
{
|
||||
if (NS_WARN_IF(!GetOwner())) {
|
||||
if (NS_WARN_IF(!mOwner)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aWindowId != GetOwner()->WindowID())) {
|
||||
if (NS_WARN_IF(aWindowId != mWindowId)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mConnectionList)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<PresentationConnection> connection =
|
||||
PresentationConnection::Create(GetOwner(), aSessionId,
|
||||
PresentationConnection::Create(mOwner, aSessionId,
|
||||
nsIPresentationService::ROLE_RECEIVER,
|
||||
PresentationConnectionState::Closed);
|
||||
mConnectionList);
|
||||
if (NS_WARN_IF(!connection)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
mConnections.AppendElement(connection);
|
||||
|
||||
// Resolve pending |GetConnection| promises if any.
|
||||
if (!mPendingGetConnectionPromises.IsEmpty()) {
|
||||
for(uint32_t i = 0; i < mPendingGetConnectionPromises.Length(); i++) {
|
||||
mPendingGetConnectionPromises[i]->MaybeResolve(connection);
|
||||
}
|
||||
mPendingGetConnectionPromises.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
PresentationReceiver::GetConnectionList(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mOwner);
|
||||
if (NS_WARN_IF(!global)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return DispatchConnectionAvailableEvent();
|
||||
if (!mGetConnectionListPromise) {
|
||||
mGetConnectionListPromise = Promise::Create(global, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PresentationReceiver> self = this;
|
||||
nsresult rv =
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction([self] () -> void {
|
||||
self->CreateConnectionList();
|
||||
}));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = mGetConnectionListPromise;
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationReceiver::DispatchConnectionAvailableEvent()
|
||||
void
|
||||
PresentationReceiver::CreateConnectionList()
|
||||
{
|
||||
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(this, NS_LITERAL_STRING("connectionavailable"), false);
|
||||
return asyncDispatcher->PostDOMEvent();
|
||||
MOZ_ASSERT(mGetConnectionListPromise);
|
||||
|
||||
if (mConnectionList) {
|
||||
return;
|
||||
}
|
||||
|
||||
mConnectionList = new PresentationConnectionList(mOwner,
|
||||
mGetConnectionListPromise);
|
||||
|
||||
// Register listener for incoming sessions.
|
||||
nsCOMPtr<nsIPresentationService> service =
|
||||
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
||||
if (NS_WARN_IF(!service)) {
|
||||
mGetConnectionListPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = service->RegisterRespondingListener(mWindowId, this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mGetConnectionListPromise->MaybeReject(rv);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -7,55 +7,55 @@
|
||||
#ifndef mozilla_dom_PresentationReceiver_h
|
||||
#define mozilla_dom_PresentationReceiver_h
|
||||
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIPresentationListener.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
class PresentationConnection;
|
||||
class PresentationConnectionList;
|
||||
class Promise;
|
||||
|
||||
class PresentationReceiver final : public DOMEventTargetHelper
|
||||
, public nsIPresentationRespondingListener
|
||||
class PresentationReceiver final : public nsIPresentationRespondingListener
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationReceiver,
|
||||
DOMEventTargetHelper)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PresentationReceiver)
|
||||
NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER
|
||||
|
||||
static already_AddRefed<PresentationReceiver> Create(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
virtual void DisconnectFromOwner() override;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
// WebIDL (public APIs)
|
||||
already_AddRefed<Promise> GetConnection(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> GetConnections(ErrorResult& aRv) const;
|
||||
|
||||
IMPL_EVENT_HANDLER(connectionavailable);
|
||||
already_AddRefed<Promise> GetConnectionList(ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
explicit PresentationReceiver(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
~PresentationReceiver();
|
||||
virtual ~PresentationReceiver();
|
||||
|
||||
bool Init();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
nsresult DispatchConnectionAvailableEvent();
|
||||
void CreateConnectionList();
|
||||
|
||||
// Store the inner window ID for |UnregisterRespondingListener| call in
|
||||
// |Shutdown| since the inner window may not exist at that moment.
|
||||
uint64_t mWindowId;
|
||||
|
||||
nsTArray<RefPtr<PresentationConnection>> mConnections;
|
||||
nsTArray<RefPtr<Promise>> mPendingGetConnectionPromises;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mOwner;
|
||||
RefPtr<Promise> mGetConnectionListPromise;
|
||||
RefPtr<PresentationConnectionList> mConnectionList;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
, mSessionId(aSessionId)
|
||||
, mIsResponderReady(false)
|
||||
, mIsTransportReady(false)
|
||||
, mState(nsIPresentationSessionListener::STATE_CLOSED)
|
||||
, mState(nsIPresentationSessionListener::STATE_CONNECTING)
|
||||
, mCallback(aCallback)
|
||||
{
|
||||
MOZ_ASSERT(!mUrl.IsEmpty());
|
||||
|
@ -16,9 +16,10 @@ interface nsIPresentationAvailabilityListener : nsISupports
|
||||
[scriptable, uuid(7dd48df8-8f8c-48c7-ac37-7b9fd1acf2f8)]
|
||||
interface nsIPresentationSessionListener : nsISupports
|
||||
{
|
||||
const unsigned short STATE_CONNECTED = 0;
|
||||
const unsigned short STATE_CLOSED = 1;
|
||||
const unsigned short STATE_TERMINATED = 2;
|
||||
const unsigned short STATE_CONNECTING = 0;
|
||||
const unsigned short STATE_CONNECTED = 1;
|
||||
const unsigned short STATE_CLOSED = 2;
|
||||
const unsigned short STATE_TERMINATED = 3;
|
||||
|
||||
/*
|
||||
* Called when session state changes.
|
||||
|
@ -18,6 +18,7 @@ EXPORTS.mozilla.dom += [
|
||||
'PresentationAvailability.h',
|
||||
'PresentationCallbacks.h',
|
||||
'PresentationConnection.h',
|
||||
'PresentationConnectionList.h',
|
||||
'PresentationDeviceManager.h',
|
||||
'PresentationReceiver.h',
|
||||
'PresentationRequest.h',
|
||||
@ -35,6 +36,7 @@ UNIFIED_SOURCES += [
|
||||
'PresentationAvailability.cpp',
|
||||
'PresentationCallbacks.cpp',
|
||||
'PresentationConnection.cpp',
|
||||
'PresentationConnectionList.cpp',
|
||||
'PresentationDeviceManager.cpp',
|
||||
'PresentationReceiver.cpp',
|
||||
'PresentationRequest.cpp',
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
enum PresentationConnectionState
|
||||
{
|
||||
// The initial state when a PresentationConnection is ceated.
|
||||
"connecting",
|
||||
|
||||
// Existing presentation, and the communication channel is active.
|
||||
"connected",
|
||||
|
||||
|
23
dom/webidl/PresentationConnectionList.webidl
Normal file
23
dom/webidl/PresentationConnectionList.webidl
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- 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",
|
||||
Func="Navigator::HasPresentationSupport"]
|
||||
interface PresentationConnectionList : EventTarget {
|
||||
/*
|
||||
* Return the non-terminated set of presentation connections in the
|
||||
* set of presentation controllers.
|
||||
* TODO: Use FrozenArray once available. (Bug 1236777)
|
||||
* readonly attribute FrozenArray<PresentationConnection> connections;
|
||||
*/
|
||||
[Frozen, Cached, Pure]
|
||||
readonly attribute sequence<PresentationConnection> connections;
|
||||
|
||||
/*
|
||||
* It is called when an incoming connection is connected.
|
||||
*/
|
||||
attribute EventHandler onconnectionavailable;
|
||||
};
|
@ -6,22 +6,11 @@
|
||||
|
||||
[Pref="dom.presentation.enabled",
|
||||
Func="Navigator::HasPresentationSupport"]
|
||||
interface PresentationReceiver : EventTarget {
|
||||
interface PresentationReceiver {
|
||||
/*
|
||||
* Get the first connected presentation connection in a receiving browsing
|
||||
* context.
|
||||
* Get a list which contains all connected presentation connections
|
||||
* in a receiving browsing context.
|
||||
*/
|
||||
[Throws]
|
||||
Promise<PresentationConnection> getConnection();
|
||||
|
||||
/*
|
||||
* Get all connected presentation connections in a receiving browsing context.
|
||||
*/
|
||||
[Throws]
|
||||
Promise<sequence<PresentationConnection>> getConnections();
|
||||
|
||||
/*
|
||||
* It is called when an incoming connection is connecting.
|
||||
*/
|
||||
attribute EventHandler onconnectionavailable;
|
||||
[SameObject, Throws]
|
||||
readonly attribute Promise<PresentationConnectionList> connectionList;
|
||||
};
|
@ -378,6 +378,7 @@ WEBIDL_FILES = [
|
||||
'Presentation.webidl',
|
||||
'PresentationAvailability.webidl',
|
||||
'PresentationConnection.webidl',
|
||||
'PresentationConnectionList.webidl',
|
||||
'PresentationDeviceInfoManager.webidl',
|
||||
'PresentationReceiver.webidl',
|
||||
'PresentationRequest.webidl',
|
||||
|
Loading…
Reference in New Issue
Block a user