NS_IMETHODIMP PresentationService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { HandleShutdown(); return NS_OK; } else if (!strcmp(aTopic, PRESENTATION_DEVICE_CHANGE_TOPIC)) { // Ignore the "update" case here, since we only care about the arrival and // removal of the device. if (!NS_strcmp(aData, u"add")) { nsCOMPtr<nsIPresentationDevice> device = do_QueryInterface(aSubject); if (NS_WARN_IF(!device)) { return NS_ERROR_FAILURE; } return HandleDeviceAdded(device); } else if (!NS_strcmp(aData, u"remove")) { return HandleDeviceRemoved(); } return NS_OK; } else if (!strcmp(aTopic, PRESENTATION_SESSION_REQUEST_TOPIC)) { nsCOMPtr<nsIPresentationSessionRequest> request( do_QueryInterface(aSubject)); if (NS_WARN_IF(!request)) { return NS_ERROR_FAILURE; } return HandleSessionRequest(request); } else if (!strcmp(aTopic, PRESENTATION_TERMINATE_REQUEST_TOPIC)) { nsCOMPtr<nsIPresentationTerminateRequest> request( do_QueryInterface(aSubject)); if (NS_WARN_IF(!request)) { return NS_ERROR_FAILURE; } return HandleTerminateRequest(request); } else if (!strcmp(aTopic, PRESENTATION_RECONNECT_REQUEST_TOPIC)) { nsCOMPtr<nsIPresentationSessionRequest> request( do_QueryInterface(aSubject)); if (NS_WARN_IF(!request)) { return NS_ERROR_FAILURE; } return HandleReconnectRequest(request); } else if (!strcmp(aTopic, "profile-after-change")) { // It's expected since we add and entry to |kLayoutCategories| in // |nsLayoutModule.cpp| to launch this service earlier. return NS_OK; } MOZ_ASSERT(false, "Unexpected topic for PresentationService"); return NS_ERROR_UNEXPECTED; }
nsresult PresentationService::HandleReconnectRequest(nsIPresentationSessionRequest* aRequest) { nsCOMPtr<nsIPresentationControlChannel> ctrlChannel; nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel)); if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) { return rv; } nsAutoString sessionId; rv = aRequest->GetPresentationId(sessionId); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } uint64_t windowId; rv = GetWindowIdBySessionIdInternal(sessionId, nsIPresentationService::ROLE_RECEIVER, &windowId); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } RefPtr<PresentationSessionInfo> info = GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER); if (NS_WARN_IF(!info)) { // Cannot reconnect non-existed session ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR); return NS_ERROR_DOM_ABORT_ERR; } nsAutoString url; rv = aRequest->GetUrl(url); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } // Make sure the url is the same as the previous one. if (NS_WARN_IF(!info->GetUrl().Equals(url))) { ctrlChannel->Disconnect(rv); return rv; } return HandleSessionRequest(aRequest); }