Bug 1234492 - Part 1: Add direction in PresentationService. r=smaug

--HG--
extra : rebase_source : 56c30d5565e5875b2f30f8f07fad01f91a15f0f0
extra : histedit_source : 7273fb211f9656ab0487301227b3d6361644b7e8
This commit is contained in:
KuoE0 2015-11-27 16:06:32 +08:00
parent f55c5966d7
commit e5175b9483
14 changed files with 183 additions and 68 deletions

View File

@ -1709,7 +1709,7 @@ ContentChild::RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId)
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
NS_WARN_IF(!service);
NS_WARN_IF(NS_FAILED(service->UntrackSessionInfo(aSessionId)));
NS_WARN_IF(NS_FAILED(service->UntrackSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER)));
return true;
}

View File

@ -50,6 +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);
if (NS_WARN_IF(!connection)) {
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);

View File

@ -35,11 +35,15 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
const nsAString& aId,
const uint8_t aRole,
PresentationConnectionState aState)
: DOMEventTargetHelper(aWindow)
, mId(aId)
, mState(aState)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
mRole = aRole;
}
/* virtual */ PresentationConnection::~PresentationConnection()
@ -49,10 +53,13 @@ PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow,
/* static */ already_AddRefed<PresentationConnection>
PresentationConnection::Create(nsPIDOMWindowInner* aWindow,
const nsAString& aId,
const uint8_t aRole,
PresentationConnectionState aState)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationConnection> connection =
new PresentationConnection(aWindow, aId, aState);
new PresentationConnection(aWindow, aId, aRole, aState);
return NS_WARN_IF(!connection->Init()) ? nullptr : connection.forget();
}
@ -69,7 +76,7 @@ PresentationConnection::Init()
return false;
}
nsresult rv = service->RegisterSessionListener(mId, this);
nsresult rv = service->RegisterSessionListener(mId, mRole, this);
if(NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
@ -86,7 +93,7 @@ PresentationConnection::Shutdown()
return;
}
nsresult rv = service->UnregisterSessionListener(mId);
nsresult rv = service->UnregisterSessionListener(mId, mRole);
NS_WARN_IF(NS_FAILED(rv));
}
@ -133,7 +140,7 @@ PresentationConnection::Send(const nsAString& aData,
return;
}
nsresult rv = service->SendSessionMessage(mId, aData);
nsresult rv = service->SendSessionMessage(mId, mRole, aData);
if(NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
}
@ -166,7 +173,7 @@ PresentationConnection::Terminate(ErrorResult& aRv)
return;
}
NS_WARN_IF(NS_FAILED(service->TerminateSession(mId)));
NS_WARN_IF(NS_FAILED(service->TerminateSession(mId, mRole)));
}
NS_IMETHODIMP
@ -207,7 +214,7 @@ PresentationConnection::NotifyStateChange(const nsAString& aSessionId,
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv = service->UnregisterSessionListener(mId);
nsresult rv = service->UnregisterSessionListener(mId, mRole);
if(NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -25,6 +25,7 @@ public:
static already_AddRefed<PresentationConnection> Create(nsPIDOMWindowInner* aWindow,
const nsAString& aId,
const uint8_t aRole,
PresentationConnectionState aState);
virtual void DisconnectFromOwner() override;
@ -50,6 +51,7 @@ public:
private:
PresentationConnection(nsPIDOMWindowInner* aWindow,
const nsAString& aId,
const uint8_t aRole,
PresentationConnectionState aState);
~PresentationConnection();
@ -63,6 +65,7 @@ private:
nsresult DispatchMessageEvent(JS::Handle<JS::Value> aData);
nsString mId;
uint8_t mRole;
PresentationConnectionState mState;
};

View File

@ -172,6 +172,7 @@ PresentationReceiver::NotifySessionConnect(uint64_t aWindowId,
RefPtr<PresentationConnection> connection =
PresentationConnection::Create(GetOwner(), aSessionId,
nsIPresentationService::ROLE_RECEIVER,
PresentationConnectionState::Closed);
if (NS_WARN_IF(!connection)) {
return NS_ERROR_NOT_AVAILABLE;

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -100,7 +101,8 @@ PresentationDeviceRequest::Select(nsIPresentationDevice* aDevice)
// Update device in the session info.
RefPtr<PresentationSessionInfo> info =
static_cast<PresentationService*>(service.get())->GetSessionInfo(mId);
static_cast<PresentationService*>(service.get())->
GetSessionInfo(mId, nsIPresentationService::ROLE_CONTROLLER);
if (NS_WARN_IF(!info)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -133,7 +135,8 @@ PresentationDeviceRequest::Cancel()
}
RefPtr<PresentationSessionInfo> info =
static_cast<PresentationService*>(service.get())->GetSessionInfo(mId);
static_cast<PresentationService*>(service.get())->
GetSessionInfo(mId, nsIPresentationService::ROLE_CONTROLLER);
if (NS_WARN_IF(!info)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -224,7 +227,8 @@ PresentationService::HandleShutdown()
mAvailabilityListeners.Clear();
mRespondingListeners.Clear();
mSessionInfo.Clear();
mSessionInfoAtController.Clear();
mSessionInfoAtReceiver.Clear();
mRespondingSessionIds.Clear();
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
@ -311,7 +315,8 @@ PresentationService::HandleSessionRequest(nsIPresentationSessionRequest* aReques
#endif
// Create or reuse session info.
RefPtr<PresentationSessionInfo> info = GetSessionInfo(sessionId);
RefPtr<PresentationSessionInfo> info =
GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER);
if (NS_WARN_IF(info)) {
// TODO Bug 1195605. Update here after session join/resume becomes supported.
ctrlChannel->Close(NS_ERROR_DOM_OPERATION_ERR);
@ -325,7 +330,7 @@ PresentationService::HandleSessionRequest(nsIPresentationSessionRequest* aReques
return rv;
}
mSessionInfo.Put(sessionId, info);
mSessionInfoAtReceiver.Put(sessionId, info);
// Notify the receiver to launch.
nsCOMPtr<nsIPresentationRequestUIGlue> glue =
@ -399,7 +404,7 @@ PresentationService::StartSession(const nsAString& aUrl,
// request is finished.
RefPtr<PresentationSessionInfo> info =
new PresentationControllingInfo(aUrl, aSessionId, aCallback);
mSessionInfo.Put(aSessionId, info);
mSessionInfoAtController.Put(aSessionId, info);
// Only track the info when an actual window ID, which would never be 0, is
// provided (for an in-process sender page).
@ -468,13 +473,16 @@ PresentationService::StartSession(const nsAString& aUrl,
NS_IMETHODIMP
PresentationService::SendSessionMessage(const nsAString& aSessionId,
uint8_t aRole,
const nsAString& aData)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aData.IsEmpty());
MOZ_ASSERT(!aSessionId.IsEmpty());
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
if (NS_WARN_IF(!info)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -483,12 +491,15 @@ PresentationService::SendSessionMessage(const nsAString& aSessionId,
}
NS_IMETHODIMP
PresentationService::CloseSession(const nsAString& aSessionId)
PresentationService::CloseSession(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aSessionId.IsEmpty());
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
if (NS_WARN_IF(!info)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -497,12 +508,15 @@ PresentationService::CloseSession(const nsAString& aSessionId)
}
NS_IMETHODIMP
PresentationService::TerminateSession(const nsAString& aSessionId)
PresentationService::TerminateSession(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aSessionId.IsEmpty());
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
if (NS_WARN_IF(!info)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -534,12 +548,15 @@ PresentationService::UnregisterAvailabilityListener(nsIPresentationAvailabilityL
NS_IMETHODIMP
PresentationService::RegisterSessionListener(const nsAString& aSessionId,
uint8_t aRole,
nsIPresentationSessionListener* aListener)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aListener);
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
if (NS_WARN_IF(!info)) {
// Notify the listener of TERMINATED since no correspondent session info is
// available possibly due to establishment failure. This would be useful at
@ -557,14 +574,17 @@ PresentationService::RegisterSessionListener(const nsAString& aSessionId,
}
NS_IMETHODIMP
PresentationService::UnregisterSessionListener(const nsAString& aSessionId)
PresentationService::UnregisterSessionListener(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
if (info) {
NS_WARN_IF(NS_FAILED(info->Close(NS_OK, nsIPresentationSessionListener::STATE_TERMINATED)));
UntrackSessionInfo(aSessionId);
UntrackSessionInfo(aSessionId, aRole);
return info->SetListener(nullptr);
}
return NS_OK;
@ -614,7 +634,8 @@ NS_IMETHODIMP
PresentationService::NotifyReceiverReady(const nsAString& aSessionId,
uint64_t aWindowId)
{
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
RefPtr<PresentationSessionInfo> info =
GetSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER);
if (NS_WARN_IF(!info)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -630,10 +651,17 @@ PresentationService::NotifyReceiverReady(const nsAString& aSessionId,
}
NS_IMETHODIMP
PresentationService::UntrackSessionInfo(const nsAString& aSessionId)
PresentationService::UntrackSessionInfo(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
// Remove the session info.
mSessionInfo.Remove(aSessionId);
if (nsIPresentationService::ROLE_CONTROLLER == aRole) {
mSessionInfoAtController.Remove(aSessionId);
} else {
mSessionInfoAtReceiver.Remove(aSessionId);
}
// Remove the in-process responding info if there's still any.
uint64_t windowId = 0;
@ -657,9 +685,12 @@ PresentationService::GetWindowIdBySessionId(const nsAString& aSessionId,
bool
PresentationService::IsSessionAccessible(const nsAString& aSessionId,
const uint8_t aRole,
base::ProcessId aProcessId)
{
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId);
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
if (NS_WARN_IF(!info)) {
return false;
}

View File

@ -33,14 +33,23 @@ public:
bool Init();
already_AddRefed<PresentationSessionInfo>
GetSessionInfo(const nsAString& aSessionId)
GetSessionInfo(const nsAString& aSessionId, const uint8_t aRole)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
RefPtr<PresentationSessionInfo> info;
return mSessionInfo.Get(aSessionId, getter_AddRefs(info)) ?
info.forget() : nullptr;
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
return mSessionInfoAtController.Get(aSessionId, getter_AddRefs(info)) ?
info.forget() : nullptr;
} else {
return mSessionInfoAtReceiver.Get(aSessionId, getter_AddRefs(info)) ?
info.forget() : nullptr;
}
}
bool IsSessionAccessible(const nsAString& aSessionId,
const uint8_t aRole,
base::ProcessId aProcessId);
private:
@ -61,7 +70,8 @@ private:
// been called in any place until many-to-one session becomes supported.
nsRefPtrHashtable<nsUint64HashKey, nsIPresentationRespondingListener> mRespondingListeners;
nsRefPtrHashtable<nsStringHashKey, PresentationSessionInfo> mSessionInfo;
nsRefPtrHashtable<nsStringHashKey, PresentationSessionInfo> mSessionInfoAtController;
nsRefPtrHashtable<nsStringHashKey, PresentationSessionInfo> mSessionInfoAtReceiver;
// Store the mapping between the window ID of the in-process page and the ID
// of the responding session. It's used for an in-process receiver page to

View File

@ -325,7 +325,7 @@ PresentationSessionInfo::UntrackFromService()
if (NS_WARN_IF(!service)) {
return NS_ERROR_NOT_AVAILABLE;
}
static_cast<PresentationService*>(service.get())->UntrackSessionInfo(mSessionId);
static_cast<PresentationService*>(service.get())->UntrackSessionInfo(mSessionId, mRole);
return NS_OK;
}
@ -910,7 +910,7 @@ PresentationPresentingInfo::UntrackFromService()
if (NS_WARN_IF(!service)) {
return NS_ERROR_NOT_AVAILABLE;
}
static_cast<PresentationService*>(service.get())->UntrackSessionInfo(mSessionId);
static_cast<PresentationService*>(service.get())->UntrackSessionInfo(mSessionId, mRole);
return NS_OK;
}

View File

@ -38,6 +38,7 @@ public:
PresentationSessionInfo(const nsAString& aUrl,
const nsAString& aSessionId,
const uint8_t aRole,
nsIPresentationServiceCallback* aCallback)
: mUrl(aUrl)
, mSessionId(aSessionId)
@ -48,6 +49,9 @@ public:
{
MOZ_ASSERT(!mUrl.IsEmpty());
MOZ_ASSERT(!mSessionId.IsEmpty());
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
mRole = aRole;
}
virtual nsresult Init(nsIPresentationControlChannel* aControlChannel);
@ -62,6 +66,11 @@ public:
return mSessionId;
}
uint8_t GetRole() const
{
return mRole;
}
void SetCallback(nsIPresentationServiceCallback* aCallback)
{
mCallback = aCallback;
@ -137,6 +146,9 @@ protected:
nsString mUrl;
nsString mSessionId;
// mRole should be nsIPresentationService::ROLE_CONTROLLER
// or nsIPresentationService::ROLE_RECEIVER.
uint8_t mRole;
bool mIsResponderReady;
bool mIsTransportReady;
uint32_t mState; // CONNECTED, CLOSED, TERMINATED
@ -160,7 +172,10 @@ public:
PresentationControllingInfo(const nsAString& aUrl,
const nsAString& aSessionId,
nsIPresentationServiceCallback* aCallback)
: PresentationSessionInfo(aUrl, aSessionId, aCallback)
: PresentationSessionInfo(aUrl,
aSessionId,
nsIPresentationService::ROLE_CONTROLLER,
aCallback)
{
MOZ_ASSERT(mCallback);
}
@ -208,10 +223,12 @@ public:
PresentationPresentingInfo(const nsAString& aUrl,
const nsAString& aSessionId,
nsIPresentationDevice* aDevice)
: PresentationSessionInfo(aUrl, aSessionId, nullptr)
: PresentationSessionInfo(aUrl,
aSessionId,
nsIPresentationService::ROLE_RECEIVER,
nullptr)
{
MOZ_ASSERT(aDevice);
SetDevice(aDevice);
}

View File

@ -36,6 +36,9 @@ interface nsIPresentationServiceCallback : nsISupports
[scriptable, uuid(de42b741-5619-4650-b961-c2cebb572c95)]
interface nsIPresentationService : nsISupports
{
const unsigned short ROLE_CONTROLLER = 0x1;
const unsigned short ROLE_RECEIVER = 0x2;
/*
* Start a new presentation session and display a prompt box which asks users
* to select a device.
@ -65,24 +68,30 @@ interface nsIPresentationService : nsISupports
* Send the message to the session.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
* @param data: the message being sent out.
*/
void sendSessionMessage(in DOMString sessionId,
in uint8_t role,
in DOMString data);
/*
* Close the session.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
*/
void closeSession(in DOMString sessionId);
void closeSession(in DOMString sessionId,
in uint8_t role);
/*
* Terminate the session.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
*/
void terminateSession(in DOMString sessionId);
void terminateSession(in DOMString sessionId,
in uint8_t role);
/*
* Register an availability listener. Must be called from the main thread.
@ -101,17 +110,21 @@ interface nsIPresentationService : nsISupports
* Register a session listener. Must be called from the main thread.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
* @param listener: The listener to register.
*/
void registerSessionListener(in DOMString sessionId,
in uint8_t role,
in nsIPresentationSessionListener listener);
/*
* Unregister a session listener. Must be called from the main thread.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
*/
void unregisterSessionListener(in DOMString sessionId);
void unregisterSessionListener(in DOMString sessionId,
in uint8_t role);
/*
* Register a responding listener. Must be called from the main thread.
@ -154,8 +167,9 @@ interface nsIPresentationService : nsISupports
* Untrack the relevant info about the presentation session if there's any.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
*/
void untrackSessionInfo(in DOMString sessionId);
void untrackSessionInfo(in DOMString sessionId, in uint8_t role);
/*
* The windowId for building RTCDataChannel session transport

View File

@ -23,17 +23,20 @@ struct StartSessionRequest
struct SendSessionMessageRequest
{
nsString sessionId;
uint8_t role;
nsString data;
};
struct CloseSessionRequest
{
nsString sessionId;
uint8_t role;
};
struct TerminateSessionRequest
{
nsString sessionId;
uint8_t role;
};
union PresentationIPCRequest
@ -61,8 +64,8 @@ parent:
async RegisterAvailabilityHandler();
async UnregisterAvailabilityHandler();
async RegisterSessionHandler(nsString aSessionId);
async UnregisterSessionHandler(nsString aSessionId);
async RegisterSessionHandler(nsString aSessionId, uint8_t aRole);
async UnregisterSessionHandler(nsString aSessionId, uint8_t aRole);
async RegisterRespondingHandler(uint64_t aWindowId);
async UnregisterRespondingHandler(uint64_t aWindowId);

View File

@ -66,29 +66,33 @@ PresentationIPCService::StartSession(const nsAString& aUrl,
NS_IMETHODIMP
PresentationIPCService::SendSessionMessage(const nsAString& aSessionId,
uint8_t aRole,
const nsAString& aData)
{
MOZ_ASSERT(!aSessionId.IsEmpty());
MOZ_ASSERT(!aData.IsEmpty());
return SendRequest(nullptr, SendSessionMessageRequest(nsString(aSessionId),
aRole,
nsString(aData)));
}
NS_IMETHODIMP
PresentationIPCService::CloseSession(const nsAString& aSessionId)
PresentationIPCService::CloseSession(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(!aSessionId.IsEmpty());
return SendRequest(nullptr, CloseSessionRequest(nsString(aSessionId)));
return SendRequest(nullptr, CloseSessionRequest(nsString(aSessionId), aRole));
}
NS_IMETHODIMP
PresentationIPCService::TerminateSession(const nsAString& aSessionId)
PresentationIPCService::TerminateSession(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(!aSessionId.IsEmpty());
return SendRequest(nullptr, TerminateSessionRequest(nsString(aSessionId)));
return SendRequest(nullptr, TerminateSessionRequest(nsString(aSessionId), aRole));
}
nsresult
@ -130,6 +134,7 @@ PresentationIPCService::UnregisterAvailabilityListener(nsIPresentationAvailabili
NS_IMETHODIMP
PresentationIPCService::RegisterSessionListener(const nsAString& aSessionId,
uint8_t aRole,
nsIPresentationSessionListener* aListener)
{
MOZ_ASSERT(NS_IsMainThread());
@ -137,21 +142,22 @@ PresentationIPCService::RegisterSessionListener(const nsAString& aSessionId,
mSessionListeners.Put(aSessionId, aListener);
if (sPresentationChild) {
NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler(nsString(aSessionId)));
NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler(nsString(aSessionId), aRole));
}
return NS_OK;
}
NS_IMETHODIMP
PresentationIPCService::UnregisterSessionListener(const nsAString& aSessionId)
PresentationIPCService::UnregisterSessionListener(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(NS_IsMainThread());
UntrackSessionInfo(aSessionId);
UntrackSessionInfo(aSessionId, aRole);
mSessionListeners.Remove(aSessionId);
if (sPresentationChild) {
NS_WARN_IF(!sPresentationChild->SendUnregisterSessionHandler(nsString(aSessionId)));
NS_WARN_IF(!sPresentationChild->SendUnregisterSessionHandler(nsString(aSessionId), aRole));
}
return NS_OK;
}
@ -278,7 +284,8 @@ PresentationIPCService::NotifyReceiverReady(const nsAString& aSessionId,
}
NS_IMETHODIMP
PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId)
PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId,
uint8_t aRole)
{
// Remove the OOP responding info (if it has never been used).
uint64_t windowId = 0;

View File

@ -45,10 +45,17 @@ PresentationParent::ActorDestroy(ActorDestroyReason aWhy)
{
mActorDestroyed = true;
for (uint32_t i = 0; i < mSessionIds.Length(); i++) {
NS_WARN_IF(NS_FAILED(mService->UnregisterSessionListener(mSessionIds[i])));
for (uint32_t i = 0; i < mSessionIdsAtController.Length(); i++) {
NS_WARN_IF(NS_FAILED(mService->
UnregisterSessionListener(mSessionIdsAtController[i], nsIPresentationService::ROLE_CONTROLLER)));
}
mSessionIds.Clear();
mSessionIdsAtController.Clear();
for (uint32_t i = 0; i < mSessionIdsAtReceiver.Length(); i++) {
NS_WARN_IF(NS_FAILED(mService->
UnregisterSessionListener(mSessionIdsAtReceiver[i], nsIPresentationService::ROLE_RECEIVER)));
}
mSessionIdsAtReceiver.Clear();
for (uint32_t i = 0; i < mWindowIds.Length(); i++) {
NS_WARN_IF(NS_FAILED(mService->UnregisterRespondingListener(mWindowIds[i])));
@ -128,28 +135,38 @@ PresentationParent::RecvUnregisterAvailabilityHandler()
}
/* virtual */ bool
PresentationParent::RecvRegisterSessionHandler(const nsString& aSessionId)
PresentationParent::RecvRegisterSessionHandler(const nsString& aSessionId,
const uint8_t& aRole)
{
MOZ_ASSERT(mService);
// Validate the accessibility (primarily for receiver side) so that a
// compromised child process can't fake the ID.
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
IsSessionAccessible(aSessionId, OtherPid()))) {
IsSessionAccessible(aSessionId, aRole, OtherPid()))) {
return true;
}
mSessionIds.AppendElement(aSessionId);
NS_WARN_IF(NS_FAILED(mService->RegisterSessionListener(aSessionId, this)));
if (nsIPresentationService::ROLE_CONTROLLER == aRole) {
mSessionIdsAtController.AppendElement(aSessionId);
} else {
mSessionIdsAtReceiver.AppendElement(aSessionId);
}
NS_WARN_IF(NS_FAILED(mService->RegisterSessionListener(aSessionId, aRole, this)));
return true;
}
/* virtual */ bool
PresentationParent::RecvUnregisterSessionHandler(const nsString& aSessionId)
PresentationParent::RecvUnregisterSessionHandler(const nsString& aSessionId,
const uint8_t& aRole)
{
MOZ_ASSERT(mService);
mSessionIds.RemoveElement(aSessionId);
NS_WARN_IF(NS_FAILED(mService->UnregisterSessionListener(aSessionId)));
if (nsIPresentationService::ROLE_CONTROLLER == aRole) {
mSessionIdsAtController.RemoveElement(aSessionId);
} else {
mSessionIdsAtReceiver.RemoveElement(aSessionId);
}
NS_WARN_IF(NS_FAILED(mService->UnregisterSessionListener(aSessionId, aRole)));
return true;
}
@ -267,11 +284,12 @@ PresentationRequestParent::DoRequest(const SendSessionMessageRequest& aRequest)
// Validate the accessibility (primarily for receiver side) so that a
// compromised child process can't fake the ID.
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
IsSessionAccessible(aRequest.sessionId(), OtherPid()))) {
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
}
nsresult rv = mService->SendSessionMessage(aRequest.sessionId(),
aRequest.role(),
aRequest.data());
if (NS_WARN_IF(NS_FAILED(rv))) {
return NotifyError(rv);
@ -287,11 +305,11 @@ PresentationRequestParent::DoRequest(const CloseSessionRequest& aRequest)
// Validate the accessibility (primarily for receiver side) so that a
// compromised child process can't fake the ID.
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
IsSessionAccessible(aRequest.sessionId(), OtherPid()))) {
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
}
nsresult rv = mService->CloseSession(aRequest.sessionId());
nsresult rv = mService->CloseSession(aRequest.sessionId(), aRequest.role());
if (NS_WARN_IF(NS_FAILED(rv))) {
return NotifyError(rv);
}
@ -306,11 +324,11 @@ PresentationRequestParent::DoRequest(const TerminateSessionRequest& aRequest)
// Validate the accessibility (primarily for receiver side) so that a
// compromised child process can't fake the ID.
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
IsSessionAccessible(aRequest.sessionId(), OtherPid()))) {
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
}
nsresult rv = mService->TerminateSession(aRequest.sessionId());
nsresult rv = mService->TerminateSession(aRequest.sessionId(), aRequest.role());
if (NS_WARN_IF(NS_FAILED(rv))) {
return NotifyError(rv);
}

View File

@ -48,9 +48,11 @@ public:
virtual bool RecvUnregisterAvailabilityHandler() override;
virtual bool RecvRegisterSessionHandler(const nsString& aSessionId) override;
virtual bool RecvRegisterSessionHandler(const nsString& aSessionId,
const uint8_t& aRole) override;
virtual bool RecvUnregisterSessionHandler(const nsString& aSessionId) override;
virtual bool RecvUnregisterSessionHandler(const nsString& aSessionId,
const uint8_t& aRole) override;
virtual bool RecvRegisterRespondingHandler(const uint64_t& aWindowId) override;
@ -63,7 +65,8 @@ private:
bool mActorDestroyed;
nsCOMPtr<nsIPresentationService> mService;
nsTArray<nsString> mSessionIds;
nsTArray<nsString> mSessionIdsAtController;
nsTArray<nsString> mSessionIdsAtReceiver;
nsTArray<uint64_t> mWindowIds;
};