diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index d67e34b6112e..c3e4bab8beb9 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -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; } diff --git a/dom/presentation/PresentationCallbacks.cpp b/dom/presentation/PresentationCallbacks.cpp index f89d1e3b281b..5f0c62d735ef 100644 --- a/dom/presentation/PresentationCallbacks.cpp +++ b/dom/presentation/PresentationCallbacks.cpp @@ -50,6 +50,7 @@ PresentationRequesterCallback::NotifySuccess() // channel is ready. So we simply set the connection state as connected. RefPtr connection = PresentationConnection::Create(mRequest->GetOwner(), mSessionId, + nsIPresentationService::ROLE_CONTROLLER, PresentationConnectionState::Connected); if (NS_WARN_IF(!connection)) { mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); diff --git a/dom/presentation/PresentationConnection.cpp b/dom/presentation/PresentationConnection.cpp index 8de4b51d1889..273c049144b3 100644 --- a/dom/presentation/PresentationConnection.cpp +++ b/dom/presentation/PresentationConnection.cpp @@ -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::Create(nsPIDOMWindowInner* aWindow, const nsAString& aId, + const uint8_t aRole, PresentationConnectionState aState) { + MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || + aRole == nsIPresentationService::ROLE_RECEIVER); RefPtr 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; } diff --git a/dom/presentation/PresentationConnection.h b/dom/presentation/PresentationConnection.h index ca6bfa421c2c..cd195e209d66 100644 --- a/dom/presentation/PresentationConnection.h +++ b/dom/presentation/PresentationConnection.h @@ -25,6 +25,7 @@ public: static already_AddRefed 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 aData); nsString mId; + uint8_t mRole; PresentationConnectionState mState; }; diff --git a/dom/presentation/PresentationReceiver.cpp b/dom/presentation/PresentationReceiver.cpp index fedf6ab2fe65..015e038cbf95 100644 --- a/dom/presentation/PresentationReceiver.cpp +++ b/dom/presentation/PresentationReceiver.cpp @@ -172,6 +172,7 @@ PresentationReceiver::NotifySessionConnect(uint64_t aWindowId, RefPtr connection = PresentationConnection::Create(GetOwner(), aSessionId, + nsIPresentationService::ROLE_RECEIVER, PresentationConnectionState::Closed); if (NS_WARN_IF(!connection)) { return NS_ERROR_NOT_AVAILABLE; diff --git a/dom/presentation/PresentationService.cpp b/dom/presentation/PresentationService.cpp index 11d706148a30..5986a6e79e7d 100644 --- a/dom/presentation/PresentationService.cpp +++ b/dom/presentation/PresentationService.cpp @@ -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 info = - static_cast(service.get())->GetSessionInfo(mId); + static_cast(service.get())-> + GetSessionInfo(mId, nsIPresentationService::ROLE_CONTROLLER); if (NS_WARN_IF(!info)) { return NS_ERROR_NOT_AVAILABLE; } @@ -133,7 +135,8 @@ PresentationDeviceRequest::Cancel() } RefPtr info = - static_cast(service.get())->GetSessionInfo(mId); + static_cast(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 obs = services::GetObserverService(); @@ -311,7 +315,8 @@ PresentationService::HandleSessionRequest(nsIPresentationSessionRequest* aReques #endif // Create or reuse session info. - RefPtr info = GetSessionInfo(sessionId); + RefPtr 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 glue = @@ -399,7 +404,7 @@ PresentationService::StartSession(const nsAString& aUrl, // request is finished. RefPtr 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 info = GetSessionInfo(aSessionId); + RefPtr 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 info = GetSessionInfo(aSessionId); + RefPtr 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 info = GetSessionInfo(aSessionId); + RefPtr 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 info = GetSessionInfo(aSessionId); + RefPtr 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 info = GetSessionInfo(aSessionId); + RefPtr 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 info = GetSessionInfo(aSessionId); + RefPtr 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 info = GetSessionInfo(aSessionId); + MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || + aRole == nsIPresentationService::ROLE_RECEIVER); + RefPtr info = GetSessionInfo(aSessionId, aRole); if (NS_WARN_IF(!info)) { return false; } diff --git a/dom/presentation/PresentationService.h b/dom/presentation/PresentationService.h index d6e95f87002e..6b285094ec15 100644 --- a/dom/presentation/PresentationService.h +++ b/dom/presentation/PresentationService.h @@ -33,14 +33,23 @@ public: bool Init(); already_AddRefed - GetSessionInfo(const nsAString& aSessionId) + GetSessionInfo(const nsAString& aSessionId, const uint8_t aRole) { + MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || + aRole == nsIPresentationService::ROLE_RECEIVER); + RefPtr 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 mRespondingListeners; - nsRefPtrHashtable mSessionInfo; + nsRefPtrHashtable mSessionInfoAtController; + nsRefPtrHashtable 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 diff --git a/dom/presentation/PresentationSessionInfo.cpp b/dom/presentation/PresentationSessionInfo.cpp index a35bee07fd62..4d646d526543 100644 --- a/dom/presentation/PresentationSessionInfo.cpp +++ b/dom/presentation/PresentationSessionInfo.cpp @@ -325,7 +325,7 @@ PresentationSessionInfo::UntrackFromService() if (NS_WARN_IF(!service)) { return NS_ERROR_NOT_AVAILABLE; } - static_cast(service.get())->UntrackSessionInfo(mSessionId); + static_cast(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(service.get())->UntrackSessionInfo(mSessionId); + static_cast(service.get())->UntrackSessionInfo(mSessionId, mRole); return NS_OK; } diff --git a/dom/presentation/PresentationSessionInfo.h b/dom/presentation/PresentationSessionInfo.h index 415aae86d565..a5c21ed14fff 100644 --- a/dom/presentation/PresentationSessionInfo.h +++ b/dom/presentation/PresentationSessionInfo.h @@ -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); } diff --git a/dom/presentation/interfaces/nsIPresentationService.idl b/dom/presentation/interfaces/nsIPresentationService.idl index 681b21500560..413c2a2c1d66 100644 --- a/dom/presentation/interfaces/nsIPresentationService.idl +++ b/dom/presentation/interfaces/nsIPresentationService.idl @@ -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 diff --git a/dom/presentation/ipc/PPresentation.ipdl b/dom/presentation/ipc/PPresentation.ipdl index 7e1a659b82df..fc25dd25ba63 100644 --- a/dom/presentation/ipc/PPresentation.ipdl +++ b/dom/presentation/ipc/PPresentation.ipdl @@ -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); diff --git a/dom/presentation/ipc/PresentationIPCService.cpp b/dom/presentation/ipc/PresentationIPCService.cpp index 0dfb05e07dbc..e296d66a91ef 100644 --- a/dom/presentation/ipc/PresentationIPCService.cpp +++ b/dom/presentation/ipc/PresentationIPCService.cpp @@ -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; diff --git a/dom/presentation/ipc/PresentationParent.cpp b/dom/presentation/ipc/PresentationParent.cpp index 2c59334f0302..266f814cba20 100644 --- a/dom/presentation/ipc/PresentationParent.cpp +++ b/dom/presentation/ipc/PresentationParent.cpp @@ -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(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(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(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(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); } diff --git a/dom/presentation/ipc/PresentationParent.h b/dom/presentation/ipc/PresentationParent.h index aaca2d4ecfc8..6ebfade5d72b 100644 --- a/dom/presentation/ipc/PresentationParent.h +++ b/dom/presentation/ipc/PresentationParent.h @@ -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 mService; - nsTArray mSessionIds; + nsTArray mSessionIdsAtController; + nsTArray mSessionIdsAtReceiver; nsTArray mWindowIds; };