mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 08:18:41 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
538
dom/presentation/ipc/PresentationIPCService.cpp
Normal file
538
dom/presentation/ipc/PresentationIPCService.cpp
Normal file
|
|
@ -0,0 +1,538 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* 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 "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/PPresentation.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIPresentationListener.h"
|
||||
#include "PresentationCallbacks.h"
|
||||
#include "PresentationChild.h"
|
||||
#include "PresentationContentSessionInfo.h"
|
||||
#include "PresentationIPCService.h"
|
||||
#include "PresentationLog.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace {
|
||||
|
||||
PresentationChild* sPresentationChild;
|
||||
|
||||
} // anonymous
|
||||
|
||||
NS_IMPL_ISUPPORTS(PresentationIPCService,
|
||||
nsIPresentationService,
|
||||
nsIPresentationAvailabilityListener)
|
||||
|
||||
PresentationIPCService::PresentationIPCService()
|
||||
{
|
||||
ContentChild* contentChild = ContentChild::GetSingleton();
|
||||
if (NS_WARN_IF(!contentChild)) {
|
||||
return;
|
||||
}
|
||||
sPresentationChild = new PresentationChild(this);
|
||||
Unused <<
|
||||
NS_WARN_IF(!contentChild->SendPPresentationConstructor(sPresentationChild));
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
PresentationIPCService::~PresentationIPCService()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
mSessionListeners.Clear();
|
||||
mSessionInfoAtController.Clear();
|
||||
mSessionInfoAtReceiver.Clear();
|
||||
sPresentationChild = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::StartSession(
|
||||
const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aSessionId,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aDeviceId,
|
||||
uint64_t aWindowId,
|
||||
nsIDOMEventTarget* aEventTarget,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPresentationServiceCallback* aCallback,
|
||||
nsIPresentationTransportBuilderConstructor* aBuilderConstructor)
|
||||
{
|
||||
if (aWindowId != 0) {
|
||||
AddRespondingSessionId(aWindowId,
|
||||
aSessionId,
|
||||
nsIPresentationService::ROLE_CONTROLLER);
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* window =
|
||||
nsGlobalWindow::GetInnerWindowWithId(aWindowId)->AsInner();
|
||||
TabId tabId = TabParent::GetTabIdFrom(window->GetDocShell());
|
||||
|
||||
return SendRequest(aCallback, StartSessionRequest(aUrls,
|
||||
nsString(aSessionId),
|
||||
nsString(aOrigin),
|
||||
nsString(aDeviceId),
|
||||
aWindowId,
|
||||
tabId,
|
||||
IPC::Principal(aPrincipal)));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::SendSessionMessage(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
const nsAString& aData)
|
||||
{
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
MOZ_ASSERT(!aData.IsEmpty());
|
||||
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
// data channel session transport is maintained by content process
|
||||
if (info) {
|
||||
return info->Send(aData);
|
||||
}
|
||||
|
||||
return SendRequest(nullptr, SendSessionMessageRequest(nsString(aSessionId),
|
||||
aRole,
|
||||
nsString(aData)));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::SendSessionBinaryMsg(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
const nsACString &aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aData.IsEmpty());
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
||||
aRole == nsIPresentationService::ROLE_RECEIVER);
|
||||
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
// data channel session transport is maintained by content process
|
||||
if (info) {
|
||||
return info->SendBinaryMsg(aData);
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::SendSessionBlob(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsIDOMBlob* aBlob)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
||||
aRole == nsIPresentationService::ROLE_RECEIVER);
|
||||
MOZ_ASSERT(aBlob);
|
||||
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
// data channel session transport is maintained by content process
|
||||
if (info) {
|
||||
return info->SendBlob(aBlob);
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::CloseSession(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
uint8_t aClosedReason)
|
||||
{
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
|
||||
nsresult rv = SendRequest(nullptr, CloseSessionRequest(nsString(aSessionId),
|
||||
aRole,
|
||||
aClosedReason));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
if (info) {
|
||||
return info->Close(NS_OK);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::TerminateSession(const nsAString& aSessionId,
|
||||
uint8_t aRole)
|
||||
{
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
|
||||
nsresult rv = SendRequest(nullptr, TerminateSessionRequest(nsString(aSessionId), aRole));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
if (info) {
|
||||
return info->Close(NS_OK);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::ReconnectSession(const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsIPresentationServiceCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
|
||||
if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
|
||||
MOZ_ASSERT(false, "Only controller can call ReconnectSession.");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return SendRequest(aCallback, ReconnectSessionRequest(aUrls,
|
||||
nsString(aSessionId),
|
||||
aRole));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::BuildTransport(const nsAString& aSessionId,
|
||||
uint8_t aRole)
|
||||
{
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
|
||||
if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
|
||||
MOZ_ASSERT(false, "Only controller can call ReconnectSession.");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return SendRequest(nullptr, BuildTransportRequest(nsString(aSessionId),
|
||||
aRole));
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationIPCService::SendRequest(nsIPresentationServiceCallback* aCallback,
|
||||
const PresentationIPCRequest& aRequest)
|
||||
{
|
||||
if (sPresentationChild) {
|
||||
PresentationRequestChild* actor = new PresentationRequestChild(aCallback);
|
||||
Unused << NS_WARN_IF(!sPresentationChild->SendPPresentationRequestConstructor(actor, aRequest));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::RegisterAvailabilityListener(
|
||||
const nsTArray<nsString>& aAvailabilityUrls,
|
||||
nsIPresentationAvailabilityListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aAvailabilityUrls.IsEmpty());
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
nsTArray<nsString> addedUrls;
|
||||
mAvailabilityManager.AddAvailabilityListener(aAvailabilityUrls,
|
||||
aListener,
|
||||
addedUrls);
|
||||
|
||||
if (sPresentationChild && !addedUrls.IsEmpty()) {
|
||||
Unused <<
|
||||
NS_WARN_IF(
|
||||
!sPresentationChild->SendRegisterAvailabilityHandler(addedUrls));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::UnregisterAvailabilityListener(
|
||||
const nsTArray<nsString>& aAvailabilityUrls,
|
||||
nsIPresentationAvailabilityListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsTArray<nsString> removedUrls;
|
||||
mAvailabilityManager.RemoveAvailabilityListener(aAvailabilityUrls,
|
||||
aListener,
|
||||
removedUrls);
|
||||
|
||||
if (sPresentationChild && !removedUrls.IsEmpty()) {
|
||||
Unused <<
|
||||
NS_WARN_IF(
|
||||
!sPresentationChild->SendUnregisterAvailabilityHandler(removedUrls));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::RegisterSessionListener(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsIPresentationSessionListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
nsCOMPtr<nsIPresentationSessionListener> listener;
|
||||
if (mSessionListeners.Get(aSessionId, getter_AddRefs(listener))) {
|
||||
mSessionListeners.Put(aSessionId, aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mSessionListeners.Put(aSessionId, aListener);
|
||||
if (sPresentationChild) {
|
||||
Unused <<
|
||||
NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler(
|
||||
nsString(aSessionId), aRole));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::UnregisterSessionListener(const nsAString& aSessionId,
|
||||
uint8_t aRole)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
UntrackSessionInfo(aSessionId, aRole);
|
||||
|
||||
mSessionListeners.Remove(aSessionId);
|
||||
if (sPresentationChild) {
|
||||
Unused <<
|
||||
NS_WARN_IF(!sPresentationChild->SendUnregisterSessionHandler(
|
||||
nsString(aSessionId), aRole));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::RegisterRespondingListener(uint64_t aWindowId,
|
||||
nsIPresentationRespondingListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mRespondingListeners.Put(aWindowId, aListener);
|
||||
if (sPresentationChild) {
|
||||
Unused <<
|
||||
NS_WARN_IF(!sPresentationChild->SendRegisterRespondingHandler(aWindowId));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::UnregisterRespondingListener(uint64_t aWindowId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mRespondingListeners.Remove(aWindowId);
|
||||
if (sPresentationChild) {
|
||||
Unused <<
|
||||
NS_WARN_IF(!sPresentationChild->SendUnregisterRespondingHandler(
|
||||
aWindowId));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationIPCService::NotifySessionTransport(const nsString& aSessionId,
|
||||
const uint8_t& aRole,
|
||||
nsIPresentationSessionTransport* aTransport)
|
||||
{
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
new PresentationContentSessionInfo(aSessionId, aRole, aTransport);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(info->Init()))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
|
||||
mSessionInfoAtController.Put(aSessionId, info);
|
||||
} else {
|
||||
mSessionInfoAtReceiver.Put(aSessionId, info);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::GetWindowIdBySessionId(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
uint64_t* aWindowId)
|
||||
{
|
||||
return GetWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::UpdateWindowIdBySessionId(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
const uint64_t aWindowId)
|
||||
{
|
||||
return UpdateWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationIPCService::NotifySessionStateChange(const nsAString& aSessionId,
|
||||
uint16_t aState,
|
||||
nsresult aReason)
|
||||
{
|
||||
nsCOMPtr<nsIPresentationSessionListener> listener;
|
||||
if (NS_WARN_IF(!mSessionListeners.Get(aSessionId, getter_AddRefs(listener)))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return listener->NotifyStateChange(aSessionId, aState, aReason);
|
||||
}
|
||||
|
||||
// Only used for OOP RTCDataChannel session transport case.
|
||||
nsresult
|
||||
PresentationIPCService::NotifyMessage(const nsAString& aSessionId,
|
||||
const nsACString& aData,
|
||||
const bool& aIsBinary)
|
||||
{
|
||||
nsCOMPtr<nsIPresentationSessionListener> listener;
|
||||
if (NS_WARN_IF(!mSessionListeners.Get(aSessionId, getter_AddRefs(listener)))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return listener->NotifyMessage(aSessionId, aData, aIsBinary);
|
||||
}
|
||||
|
||||
// Only used for OOP RTCDataChannel session transport case.
|
||||
nsresult
|
||||
PresentationIPCService::NotifyTransportClosed(const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsresult aReason)
|
||||
{
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
if (NS_WARN_IF(!info)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
Unused << NS_WARN_IF(!sPresentationChild->SendNotifyTransportClosed(nsString(aSessionId), aRole, aReason));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationIPCService::NotifySessionConnect(uint64_t aWindowId,
|
||||
const nsAString& aSessionId)
|
||||
{
|
||||
nsCOMPtr<nsIPresentationRespondingListener> listener;
|
||||
if (NS_WARN_IF(!mRespondingListeners.Get(aWindowId, getter_AddRefs(listener)))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return listener->NotifySessionConnect(aWindowId, aSessionId);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::NotifyAvailableChange(
|
||||
const nsTArray<nsString>& aAvailabilityUrls,
|
||||
bool aAvailable)
|
||||
{
|
||||
return mAvailabilityManager.DoNotifyAvailableChange(aAvailabilityUrls,
|
||||
aAvailable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::NotifyReceiverReady(
|
||||
const nsAString& aSessionId,
|
||||
uint64_t aWindowId,
|
||||
bool aIsLoading,
|
||||
nsIPresentationTransportBuilderConstructor* aBuilderConstructor)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// No actual window uses 0 as its ID.
|
||||
if (NS_WARN_IF(aWindowId == 0)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Track the responding info for an OOP receiver page.
|
||||
AddRespondingSessionId(aWindowId,
|
||||
aSessionId,
|
||||
nsIPresentationService::ROLE_RECEIVER);
|
||||
|
||||
Unused << NS_WARN_IF(!sPresentationChild->SendNotifyReceiverReady(nsString(aSessionId),
|
||||
aWindowId,
|
||||
aIsLoading));
|
||||
|
||||
// Release mCallback after using aSessionId
|
||||
// because aSessionId is held by mCallback.
|
||||
mCallback = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId,
|
||||
uint8_t aRole)
|
||||
{
|
||||
PRES_DEBUG("content %s:id[%s], role[%d]\n", __func__,
|
||||
NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
|
||||
|
||||
if (nsIPresentationService::ROLE_RECEIVER == aRole) {
|
||||
// Terminate receiver page.
|
||||
uint64_t windowId;
|
||||
if (NS_SUCCEEDED(GetWindowIdBySessionIdInternal(aSessionId,
|
||||
aRole,
|
||||
&windowId))) {
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void {
|
||||
PRES_DEBUG("Attempt to close window[%d]\n", windowId);
|
||||
|
||||
if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) {
|
||||
window->Close();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the OOP responding info (if it has never been used).
|
||||
RemoveRespondingSessionId(aSessionId, aRole);
|
||||
|
||||
if (nsIPresentationService::ROLE_CONTROLLER == aRole) {
|
||||
mSessionInfoAtController.Remove(aSessionId);
|
||||
} else {
|
||||
mSessionInfoAtReceiver.Remove(aSessionId);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PresentationIPCService::NotifyPresentationChildDestroyed()
|
||||
{
|
||||
sPresentationChild = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationIPCService::MonitorResponderLoading(const nsAString& aSessionId,
|
||||
nsIDocShell* aDocShell)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mCallback = new PresentationResponderLoadingCallback(aSessionId);
|
||||
return mCallback->Init(aDocShell);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationIPCService::CloseContentSessionTransport(const nsString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsresult aReason)
|
||||
{
|
||||
RefPtr<PresentationContentSessionInfo> info =
|
||||
GetSessionInfo(aSessionId, aRole);
|
||||
if (NS_WARN_IF(!info)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return info->Close(aReason);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue