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.
|
// channel is ready. So we simply set the connection state as connected.
|
||||||
RefPtr<PresentationConnection> connection =
|
RefPtr<PresentationConnection> connection =
|
||||||
PresentationConnection::Create(mRequest->GetOwner(), mSessionId,
|
PresentationConnection::Create(mRequest->GetOwner(), mSessionId,
|
||||||
nsIPresentationService::ROLE_CONTROLLER,
|
nsIPresentationService::ROLE_CONTROLLER);
|
||||||
PresentationConnectionState::Connected);
|
|
||||||
if (NS_WARN_IF(!connection)) {
|
if (NS_WARN_IF(!connection)) {
|
||||||
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsStringStream.h"
|
#include "nsStringStream.h"
|
||||||
#include "PresentationConnection.h"
|
#include "PresentationConnection.h"
|
||||||
|
#include "PresentationConnectionList.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
@ -20,10 +21,12 @@ using namespace mozilla::dom;
|
|||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationConnection)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationConnection)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
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_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
||||||
tmp->Shutdown();
|
tmp->Shutdown();
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningConnectionList)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
NS_IMPL_ADDREF_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
||||||
@ -36,10 +39,11 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|||||||
PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
|
PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
|
||||||
const nsAString& aId,
|
const nsAString& aId,
|
||||||
const uint8_t aRole,
|
const uint8_t aRole,
|
||||||
PresentationConnectionState aState)
|
PresentationConnectionList* aList)
|
||||||
: DOMEventTargetHelper(aWindow)
|
: DOMEventTargetHelper(aWindow)
|
||||||
, mId(aId)
|
, mId(aId)
|
||||||
, mState(aState)
|
, mState(PresentationConnectionState::Connecting)
|
||||||
|
, mOwningConnectionList(aList)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
||||||
aRole == nsIPresentationService::ROLE_RECEIVER);
|
aRole == nsIPresentationService::ROLE_RECEIVER);
|
||||||
@ -54,12 +58,12 @@ PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
|
|||||||
PresentationConnection::Create(nsPIDOMWindowInner* aWindow,
|
PresentationConnection::Create(nsPIDOMWindowInner* aWindow,
|
||||||
const nsAString& aId,
|
const nsAString& aId,
|
||||||
const uint8_t aRole,
|
const uint8_t aRole,
|
||||||
PresentationConnectionState aState)
|
PresentationConnectionList* aList)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
||||||
aRole == nsIPresentationService::ROLE_RECEIVER);
|
aRole == nsIPresentationService::ROLE_RECEIVER);
|
||||||
RefPtr<PresentationConnection> connection =
|
RefPtr<PresentationConnection> connection =
|
||||||
new PresentationConnection(aWindow, aId, aRole, aState);
|
new PresentationConnection(aWindow, aId, aRole, aList);
|
||||||
return NS_WARN_IF(!connection->Init()) ? nullptr : connection.forget();
|
return NS_WARN_IF(!connection->Init()) ? nullptr : connection.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +190,9 @@ PresentationConnection::NotifyStateChange(const nsAString& aSessionId,
|
|||||||
|
|
||||||
PresentationConnectionState state;
|
PresentationConnectionState state;
|
||||||
switch (aState) {
|
switch (aState) {
|
||||||
|
case nsIPresentationSessionListener::STATE_CONNECTING:
|
||||||
|
state = PresentationConnectionState::Connecting;
|
||||||
|
break;
|
||||||
case nsIPresentationSessionListener::STATE_CONNECTED:
|
case nsIPresentationSessionListener::STATE_CONNECTED:
|
||||||
state = PresentationConnectionState::Connected;
|
state = PresentationConnectionState::Connected;
|
||||||
break;
|
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
|
NS_IMETHODIMP
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class PresentationConnectionList;
|
||||||
|
|
||||||
class PresentationConnection final : public DOMEventTargetHelper
|
class PresentationConnection final : public DOMEventTargetHelper
|
||||||
, public nsIPresentationSessionListener
|
, public nsIPresentationSessionListener
|
||||||
{
|
{
|
||||||
@ -23,10 +25,11 @@ public:
|
|||||||
DOMEventTargetHelper)
|
DOMEventTargetHelper)
|
||||||
NS_DECL_NSIPRESENTATIONSESSIONLISTENER
|
NS_DECL_NSIPRESENTATIONSESSIONLISTENER
|
||||||
|
|
||||||
static already_AddRefed<PresentationConnection> Create(nsPIDOMWindowInner* aWindow,
|
static already_AddRefed<PresentationConnection>
|
||||||
const nsAString& aId,
|
Create(nsPIDOMWindowInner* aWindow,
|
||||||
const uint8_t aRole,
|
const nsAString& aId,
|
||||||
PresentationConnectionState aState);
|
const uint8_t aRole,
|
||||||
|
PresentationConnectionList* aList = nullptr);
|
||||||
|
|
||||||
virtual void DisconnectFromOwner() override;
|
virtual void DisconnectFromOwner() override;
|
||||||
|
|
||||||
@ -52,7 +55,7 @@ private:
|
|||||||
PresentationConnection(nsPIDOMWindowInner* aWindow,
|
PresentationConnection(nsPIDOMWindowInner* aWindow,
|
||||||
const nsAString& aId,
|
const nsAString& aId,
|
||||||
const uint8_t aRole,
|
const uint8_t aRole,
|
||||||
PresentationConnectionState aState);
|
PresentationConnectionList* aList);
|
||||||
|
|
||||||
~PresentationConnection();
|
~PresentationConnection();
|
||||||
|
|
||||||
@ -67,6 +70,7 @@ private:
|
|||||||
nsString mId;
|
nsString mId;
|
||||||
uint8_t mRole;
|
uint8_t mRole;
|
||||||
PresentationConnectionState mState;
|
PresentationConnectionState mState;
|
||||||
|
RefPtr<PresentationConnectionList> mOwningConnectionList;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // 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
|
* 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/. */
|
* 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/PresentationReceiverBinding.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
|
||||||
#include "nsIPresentationService.h"
|
#include "nsIPresentationService.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "PresentationReceiver.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "PresentationConnection.h"
|
#include "PresentationConnection.h"
|
||||||
|
#include "PresentationConnectionList.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
namespace mozilla {
|
||||||
using namespace mozilla::dom;
|
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_COLLECTING_ADDREF(PresentationReceiver)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnections)
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationReceiver)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingGetConnectionPromises)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationReceiver, DOMEventTargetHelper)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationReceiver)
|
||||||
tmp->Shutdown();
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||||
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_ENTRY(nsIPresentationRespondingListener)
|
NS_INTERFACE_MAP_ENTRY(nsIPresentationRespondingListener)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
/* static */ already_AddRefed<PresentationReceiver>
|
/* static */ already_AddRefed<PresentationReceiver>
|
||||||
PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
|
PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
|
||||||
@ -44,8 +38,9 @@ PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PresentationReceiver::PresentationReceiver(nsPIDOMWindowInner* aWindow)
|
PresentationReceiver::PresentationReceiver(nsPIDOMWindowInner* aWindow)
|
||||||
: DOMEventTargetHelper(aWindow)
|
: mOwner(aWindow)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
PresentationReceiver::~PresentationReceiver()
|
PresentationReceiver::~PresentationReceiver()
|
||||||
@ -56,31 +51,16 @@ PresentationReceiver::~PresentationReceiver()
|
|||||||
bool
|
bool
|
||||||
PresentationReceiver::Init()
|
PresentationReceiver::Init()
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(!GetOwner())) {
|
if (NS_WARN_IF(!mOwner)) {
|
||||||
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))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
mWindowId = mOwner->WindowID();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentationReceiver::Shutdown()
|
void PresentationReceiver::Shutdown()
|
||||||
{
|
{
|
||||||
mConnections.Clear();
|
|
||||||
mPendingGetConnectionPromises.Clear();
|
|
||||||
|
|
||||||
// Unregister listener for incoming sessions.
|
// Unregister listener for incoming sessions.
|
||||||
nsCOMPtr<nsIPresentationService> service =
|
nsCOMPtr<nsIPresentationService> service =
|
||||||
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
||||||
@ -92,13 +72,6 @@ void PresentationReceiver::Shutdown()
|
|||||||
NS_WARN_IF(NS_FAILED(rv));
|
NS_WARN_IF(NS_FAILED(rv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
PresentationReceiver::DisconnectFromOwner()
|
|
||||||
{
|
|
||||||
Shutdown();
|
|
||||||
DOMEventTargetHelper::DisconnectFromOwner();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ JSObject*
|
/* virtual */ JSObject*
|
||||||
PresentationReceiver::WrapObject(JSContext* aCx,
|
PresentationReceiver::WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto)
|
JS::Handle<JSObject*> aGivenProto)
|
||||||
@ -106,86 +79,88 @@ PresentationReceiver::WrapObject(JSContext* aCx,
|
|||||||
return PresentationReceiverBinding::Wrap(aCx, this, aGivenProto);
|
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
|
NS_IMETHODIMP
|
||||||
PresentationReceiver::NotifySessionConnect(uint64_t aWindowId,
|
PresentationReceiver::NotifySessionConnect(uint64_t aWindowId,
|
||||||
const nsAString& aSessionId)
|
const nsAString& aSessionId)
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(!GetOwner())) {
|
if (NS_WARN_IF(!mOwner)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(aWindowId != GetOwner()->WindowID())) {
|
if (NS_WARN_IF(aWindowId != mWindowId)) {
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!mConnectionList)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<PresentationConnection> connection =
|
RefPtr<PresentationConnection> connection =
|
||||||
PresentationConnection::Create(GetOwner(), aSessionId,
|
PresentationConnection::Create(mOwner, aSessionId,
|
||||||
nsIPresentationService::ROLE_RECEIVER,
|
nsIPresentationService::ROLE_RECEIVER,
|
||||||
PresentationConnectionState::Closed);
|
mConnectionList);
|
||||||
if (NS_WARN_IF(!connection)) {
|
if (NS_WARN_IF(!connection)) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
mConnections.AppendElement(connection);
|
|
||||||
|
|
||||||
// Resolve pending |GetConnection| promises if any.
|
return NS_OK;
|
||||||
if (!mPendingGetConnectionPromises.IsEmpty()) {
|
}
|
||||||
for(uint32_t i = 0; i < mPendingGetConnectionPromises.Length(); i++) {
|
|
||||||
mPendingGetConnectionPromises[i]->MaybeResolve(connection);
|
already_AddRefed<Promise>
|
||||||
}
|
PresentationReceiver::GetConnectionList(ErrorResult& aRv)
|
||||||
mPendingGetConnectionPromises.Clear();
|
{
|
||||||
|
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
|
void
|
||||||
PresentationReceiver::DispatchConnectionAvailableEvent()
|
PresentationReceiver::CreateConnectionList()
|
||||||
{
|
{
|
||||||
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
MOZ_ASSERT(mGetConnectionListPromise);
|
||||||
new AsyncEventDispatcher(this, NS_LITERAL_STRING("connectionavailable"), false);
|
|
||||||
return asyncDispatcher->PostDOMEvent();
|
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
|
#ifndef mozilla_dom_PresentationReceiver_h
|
||||||
#define mozilla_dom_PresentationReceiver_h
|
#define mozilla_dom_PresentationReceiver_h
|
||||||
|
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "nsIPresentationListener.h"
|
#include "nsIPresentationListener.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class Promise;
|
|
||||||
class PresentationConnection;
|
class PresentationConnection;
|
||||||
|
class PresentationConnectionList;
|
||||||
|
class Promise;
|
||||||
|
|
||||||
class PresentationReceiver final : public DOMEventTargetHelper
|
class PresentationReceiver final : public nsIPresentationRespondingListener
|
||||||
, public nsIPresentationRespondingListener
|
, public nsWrapperCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationReceiver,
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PresentationReceiver)
|
||||||
DOMEventTargetHelper)
|
|
||||||
NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER
|
NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER
|
||||||
|
|
||||||
static already_AddRefed<PresentationReceiver> Create(nsPIDOMWindowInner* aWindow);
|
static already_AddRefed<PresentationReceiver> Create(nsPIDOMWindowInner* aWindow);
|
||||||
|
|
||||||
virtual void DisconnectFromOwner() override;
|
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx,
|
virtual JSObject* WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
nsISupports* GetParentObject() const
|
||||||
|
{
|
||||||
|
return mOwner;
|
||||||
|
}
|
||||||
|
|
||||||
// WebIDL (public APIs)
|
// WebIDL (public APIs)
|
||||||
already_AddRefed<Promise> GetConnection(ErrorResult& aRv);
|
already_AddRefed<Promise> GetConnectionList(ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<Promise> GetConnections(ErrorResult& aRv) const;
|
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(connectionavailable);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit PresentationReceiver(nsPIDOMWindowInner* aWindow);
|
explicit PresentationReceiver(nsPIDOMWindowInner* aWindow);
|
||||||
|
|
||||||
~PresentationReceiver();
|
virtual ~PresentationReceiver();
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
nsresult DispatchConnectionAvailableEvent();
|
void CreateConnectionList();
|
||||||
|
|
||||||
// Store the inner window ID for |UnregisterRespondingListener| call in
|
// Store the inner window ID for |UnregisterRespondingListener| call in
|
||||||
// |Shutdown| since the inner window may not exist at that moment.
|
// |Shutdown| since the inner window may not exist at that moment.
|
||||||
uint64_t mWindowId;
|
uint64_t mWindowId;
|
||||||
|
|
||||||
nsTArray<RefPtr<PresentationConnection>> mConnections;
|
nsCOMPtr<nsPIDOMWindowInner> mOwner;
|
||||||
nsTArray<RefPtr<Promise>> mPendingGetConnectionPromises;
|
RefPtr<Promise> mGetConnectionListPromise;
|
||||||
|
RefPtr<PresentationConnectionList> mConnectionList;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
, mSessionId(aSessionId)
|
, mSessionId(aSessionId)
|
||||||
, mIsResponderReady(false)
|
, mIsResponderReady(false)
|
||||||
, mIsTransportReady(false)
|
, mIsTransportReady(false)
|
||||||
, mState(nsIPresentationSessionListener::STATE_CLOSED)
|
, mState(nsIPresentationSessionListener::STATE_CONNECTING)
|
||||||
, mCallback(aCallback)
|
, mCallback(aCallback)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mUrl.IsEmpty());
|
MOZ_ASSERT(!mUrl.IsEmpty());
|
||||||
|
@ -16,9 +16,10 @@ interface nsIPresentationAvailabilityListener : nsISupports
|
|||||||
[scriptable, uuid(7dd48df8-8f8c-48c7-ac37-7b9fd1acf2f8)]
|
[scriptable, uuid(7dd48df8-8f8c-48c7-ac37-7b9fd1acf2f8)]
|
||||||
interface nsIPresentationSessionListener : nsISupports
|
interface nsIPresentationSessionListener : nsISupports
|
||||||
{
|
{
|
||||||
const unsigned short STATE_CONNECTED = 0;
|
const unsigned short STATE_CONNECTING = 0;
|
||||||
const unsigned short STATE_CLOSED = 1;
|
const unsigned short STATE_CONNECTED = 1;
|
||||||
const unsigned short STATE_TERMINATED = 2;
|
const unsigned short STATE_CLOSED = 2;
|
||||||
|
const unsigned short STATE_TERMINATED = 3;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when session state changes.
|
* Called when session state changes.
|
||||||
|
@ -18,6 +18,7 @@ EXPORTS.mozilla.dom += [
|
|||||||
'PresentationAvailability.h',
|
'PresentationAvailability.h',
|
||||||
'PresentationCallbacks.h',
|
'PresentationCallbacks.h',
|
||||||
'PresentationConnection.h',
|
'PresentationConnection.h',
|
||||||
|
'PresentationConnectionList.h',
|
||||||
'PresentationDeviceManager.h',
|
'PresentationDeviceManager.h',
|
||||||
'PresentationReceiver.h',
|
'PresentationReceiver.h',
|
||||||
'PresentationRequest.h',
|
'PresentationRequest.h',
|
||||||
@ -35,6 +36,7 @@ UNIFIED_SOURCES += [
|
|||||||
'PresentationAvailability.cpp',
|
'PresentationAvailability.cpp',
|
||||||
'PresentationCallbacks.cpp',
|
'PresentationCallbacks.cpp',
|
||||||
'PresentationConnection.cpp',
|
'PresentationConnection.cpp',
|
||||||
|
'PresentationConnectionList.cpp',
|
||||||
'PresentationDeviceManager.cpp',
|
'PresentationDeviceManager.cpp',
|
||||||
'PresentationReceiver.cpp',
|
'PresentationReceiver.cpp',
|
||||||
'PresentationRequest.cpp',
|
'PresentationRequest.cpp',
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
enum PresentationConnectionState
|
enum PresentationConnectionState
|
||||||
{
|
{
|
||||||
|
// The initial state when a PresentationConnection is ceated.
|
||||||
|
"connecting",
|
||||||
|
|
||||||
// Existing presentation, and the communication channel is active.
|
// Existing presentation, and the communication channel is active.
|
||||||
"connected",
|
"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",
|
[Pref="dom.presentation.enabled",
|
||||||
Func="Navigator::HasPresentationSupport"]
|
Func="Navigator::HasPresentationSupport"]
|
||||||
interface PresentationReceiver : EventTarget {
|
interface PresentationReceiver {
|
||||||
/*
|
/*
|
||||||
* Get the first connected presentation connection in a receiving browsing
|
* Get a list which contains all connected presentation connections
|
||||||
* context.
|
* in a receiving browsing context.
|
||||||
*/
|
*/
|
||||||
[Throws]
|
[SameObject, Throws]
|
||||||
Promise<PresentationConnection> getConnection();
|
readonly attribute Promise<PresentationConnectionList> connectionList;
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
};
|
};
|
@ -378,6 +378,7 @@ WEBIDL_FILES = [
|
|||||||
'Presentation.webidl',
|
'Presentation.webidl',
|
||||||
'PresentationAvailability.webidl',
|
'PresentationAvailability.webidl',
|
||||||
'PresentationConnection.webidl',
|
'PresentationConnection.webidl',
|
||||||
|
'PresentationConnectionList.webidl',
|
||||||
'PresentationDeviceInfoManager.webidl',
|
'PresentationDeviceInfoManager.webidl',
|
||||||
'PresentationReceiver.webidl',
|
'PresentationReceiver.webidl',
|
||||||
'PresentationRequest.webidl',
|
'PresentationRequest.webidl',
|
||||||
|
Loading…
Reference in New Issue
Block a user