2017-10-27 01:08:41 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2015-03-19 10:48:28 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2016-05-30 09:48:00 +03:00
|
|
|
#include "PresentationConnection.h"
|
|
|
|
|
2016-08-02 20:11:00 +03:00
|
|
|
#include "ControllerConnectionCollection.h"
|
2015-04-22 11:01:38 +03:00
|
|
|
#include "mozilla/AsyncEventDispatcher.h"
|
2016-05-30 09:48:00 +03:00
|
|
|
#include "mozilla/dom/DOMException.h"
|
2016-09-18 02:42:00 +03:00
|
|
|
#include "mozilla/dom/File.h"
|
2015-08-12 14:39:31 +03:00
|
|
|
#include "mozilla/dom/MessageEvent.h"
|
2016-01-30 20:05:36 +03:00
|
|
|
#include "mozilla/dom/MessageEventBinding.h"
|
2016-10-04 01:22:34 +03:00
|
|
|
#include "mozilla/dom/PresentationConnectionCloseEvent.h"
|
2016-05-30 09:48:00 +03:00
|
|
|
#include "mozilla/ErrorNames.h"
|
2016-09-02 10:12:24 +03:00
|
|
|
#include "mozilla/DebugOnly.h"
|
2016-12-16 06:16:31 +03:00
|
|
|
#include "mozilla/IntegerPrintfMacros.h"
|
2015-10-26 19:14:47 +03:00
|
|
|
#include "nsContentUtils.h"
|
2015-03-19 10:48:28 +03:00
|
|
|
#include "nsCycleCollectionParticipant.h"
|
2015-04-22 11:01:38 +03:00
|
|
|
#include "nsIPresentationService.h"
|
2015-03-19 10:48:28 +03:00
|
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#include "nsStringStream.h"
|
2016-05-29 20:59:00 +03:00
|
|
|
#include "PresentationConnectionList.h"
|
2016-08-15 13:26:13 +03:00
|
|
|
#include "PresentationLog.h"
|
2015-03-19 10:48:28 +03:00
|
|
|
|
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationConnection)
|
2015-03-19 10:48:28 +03:00
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationConnection,
|
|
|
|
DOMEventTargetHelper)
|
2016-05-29 20:59:00 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningConnectionList)
|
2015-03-19 10:48:28 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationConnection,
|
|
|
|
DOMEventTargetHelper)
|
2015-03-19 10:48:28 +03:00
|
|
|
tmp->Shutdown();
|
2016-05-29 20:59:00 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningConnectionList)
|
2015-03-19 10:48:28 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
NS_IMPL_ADDREF_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(PresentationConnection, DOMEventTargetHelper)
|
2015-03-19 10:48:28 +03:00
|
|
|
|
2017-08-30 02:02:48 +03:00
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationConnection)
|
2015-04-22 11:01:38 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIPresentationSessionListener)
|
2016-05-30 09:48:00 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
2015-03-19 10:48:28 +03:00
|
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
PresentationConnection::PresentationConnection(
|
|
|
|
nsPIDOMWindowInner* aWindow, const nsAString& aId, const nsAString& aUrl,
|
2016-05-29 20:59:00 +03:00
|
|
|
const uint8_t aRole, PresentationConnectionList* aList)
|
2015-03-19 10:48:28 +03:00
|
|
|
: DOMEventTargetHelper(aWindow),
|
|
|
|
mId(aId),
|
2016-08-02 20:11:00 +03:00
|
|
|
mUrl(aUrl),
|
2016-05-29 20:59:00 +03:00
|
|
|
mState(PresentationConnectionState::Connecting),
|
|
|
|
mOwningConnectionList(aList),
|
2016-09-18 02:42:00 +03:00
|
|
|
mBinaryType(PresentationConnectionBinaryType::Arraybuffer) {
|
2016-04-18 03:19:00 +03:00
|
|
|
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
|
|
|
aRole == nsIPresentationService::ROLE_RECEIVER);
|
|
|
|
mRole = aRole;
|
2015-03-19 10:48:28 +03:00
|
|
|
}
|
|
|
|
|
2020-03-09 18:14:19 +03:00
|
|
|
/* virtual */ PresentationConnection::~PresentationConnection() = default;
|
2015-03-19 10:48:28 +03:00
|
|
|
|
2019-02-26 01:05:29 +03:00
|
|
|
/* static */
|
|
|
|
already_AddRefed<PresentationConnection> PresentationConnection::Create(
|
|
|
|
nsPIDOMWindowInner* aWindow, const nsAString& aId, const nsAString& aUrl,
|
|
|
|
const uint8_t aRole, PresentationConnectionList* aList) {
|
2016-04-18 03:19:00 +03:00
|
|
|
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
|
|
|
|
aRole == nsIPresentationService::ROLE_RECEIVER);
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<PresentationConnection> connection =
|
2016-08-02 20:11:00 +03:00
|
|
|
new PresentationConnection(aWindow, aId, aUrl, aRole, aList);
|
|
|
|
if (NS_WARN_IF(!connection->Init())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
|
|
|
|
ControllerConnectionCollection::GetSingleton()->AddConnection(connection,
|
|
|
|
aRole);
|
|
|
|
}
|
|
|
|
|
|
|
|
return connection.forget();
|
2015-03-19 10:48:28 +03:00
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
bool PresentationConnection::Init() {
|
2015-03-19 10:48:28 +03:00
|
|
|
if (NS_WARN_IF(mId.IsEmpty())) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-04-18 03:19:00 +03:00
|
|
|
nsresult rv = service->RegisterSessionListener(mId, mRole, this);
|
2015-04-22 11:01:38 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-03-19 10:48:28 +03:00
|
|
|
|
2016-07-13 01:18:00 +03:00
|
|
|
rv = AddIntoLoadGroup();
|
2016-05-30 09:48:00 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-03-19 10:48:28 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
void PresentationConnection::Shutdown() {
|
2016-08-15 13:26:13 +03:00
|
|
|
PRES_DEBUG("connection shutdown:id[%s], role[%d]\n",
|
|
|
|
NS_ConvertUTF16toUTF8(mId).get(), mRole);
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
DebugOnly<nsresult> rv = service->UnregisterSessionListener(mId, mRole);
|
|
|
|
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "UnregisterSessionListener failed");
|
2016-05-30 09:48:00 +03:00
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
DebugOnly<nsresult> rv2 = RemoveFromLoadGroup();
|
|
|
|
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2), "RemoveFromLoadGroup failed");
|
2016-08-02 20:11:00 +03:00
|
|
|
|
|
|
|
if (mRole == nsIPresentationService::ROLE_CONTROLLER) {
|
|
|
|
ControllerConnectionCollection::GetSingleton()->RemoveConnection(this,
|
|
|
|
mRole);
|
|
|
|
}
|
2015-03-19 10:48:28 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:05:29 +03:00
|
|
|
/* virtual */
|
|
|
|
void PresentationConnection::DisconnectFromOwner() {
|
2016-09-02 10:12:24 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(ProcessConnectionWentAway()));
|
2015-09-10 11:29:08 +03:00
|
|
|
DOMEventTargetHelper::DisconnectFromOwner();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:05:29 +03:00
|
|
|
/* virtual */
|
|
|
|
JSObject* PresentationConnection::WrapObject(
|
2015-10-12 05:36:31 +03:00
|
|
|
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
|
2018-06-26 00:20:54 +03:00
|
|
|
return PresentationConnection_Binding::Wrap(aCx, this, aGivenProto);
|
2015-03-19 10:48:28 +03:00
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
void PresentationConnection::GetId(nsAString& aId) const {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
aId = EmptyString();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-19 10:48:28 +03:00
|
|
|
aId = mId;
|
|
|
|
}
|
|
|
|
|
2016-08-02 20:11:00 +03:00
|
|
|
void PresentationConnection::GetUrl(nsAString& aUrl) const {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
aUrl = EmptyString();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-02 20:11:00 +03:00
|
|
|
aUrl = mUrl;
|
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
PresentationConnectionState PresentationConnection::State() const {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return PresentationConnectionState::Terminated;
|
|
|
|
}
|
|
|
|
|
2015-03-19 10:48:28 +03:00
|
|
|
return mState;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
PresentationConnectionBinaryType PresentationConnection::BinaryType() const {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return PresentationConnectionBinaryType::Blob;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
return mBinaryType;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PresentationConnection::SetBinaryType(
|
|
|
|
PresentationConnectionBinaryType aType) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
mBinaryType = aType;
|
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
void PresentationConnection::Send(const nsAString& aData, ErrorResult& aRv) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-19 10:48:28 +03:00
|
|
|
// Sending is not allowed if the session is not connected.
|
2015-10-12 05:36:31 +03:00
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
|
2015-03-19 10:48:28 +03:00
|
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
2016-09-18 02:42:00 +03:00
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to send message due to an internal error."));
|
2015-03-19 10:48:28 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-18 03:19:00 +03:00
|
|
|
nsresult rv = service->SendSessionMessage(mId, mRole, aData);
|
2015-04-22 11:01:38 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
2016-09-18 02:42:00 +03:00
|
|
|
const uint32_t kMaxMessageLength = 256;
|
|
|
|
nsAutoString data(Substring(aData, 0, kMaxMessageLength));
|
|
|
|
|
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to send message: \"") + data +
|
|
|
|
NS_LITERAL_STRING("\""));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PresentationConnection::Send(Blob& aData, ErrorResult& aRv) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to send message due to an internal error."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = service->SendSessionBlob(mId, mRole, &aData);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to send binary message for Blob message."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PresentationConnection::Send(const ArrayBuffer& aData, ErrorResult& aRv) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to send message due to an internal error."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-01-23 06:22:06 +03:00
|
|
|
aData.ComputeState();
|
2016-09-18 02:42:00 +03:00
|
|
|
|
|
|
|
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
|
|
|
|
|
|
|
|
uint32_t length = aData.Length();
|
|
|
|
char* data = reinterpret_cast<char*>(aData.Data());
|
|
|
|
nsDependentCSubstring msgString(data, length);
|
|
|
|
|
|
|
|
nsresult rv = service->SendSessionBinaryMsg(mId, mRole, msgString);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(NS_LITERAL_STRING(
|
|
|
|
"Unable to send binary message for ArrayBuffer message."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PresentationConnection::Send(const ArrayBufferView& aData,
|
|
|
|
ErrorResult& aRv) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to send message due to an internal error."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-01-23 06:22:06 +03:00
|
|
|
aData.ComputeState();
|
2016-09-18 02:42:00 +03:00
|
|
|
|
|
|
|
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
|
|
|
|
|
|
|
|
uint32_t length = aData.Length();
|
|
|
|
char* data = reinterpret_cast<char*>(aData.Data());
|
|
|
|
nsDependentCSubstring msgString(data, length);
|
|
|
|
|
|
|
|
nsresult rv = service->SendSessionBinaryMsg(mId, mRole, msgString);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(NS_LITERAL_STRING(
|
|
|
|
"Unable to send binary message for ArrayBufferView message."));
|
2015-04-22 11:01:38 +03:00
|
|
|
}
|
2015-03-19 10:48:28 +03:00
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
void PresentationConnection::Close(ErrorResult& aRv) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-07-13 01:18:00 +03:00
|
|
|
// It only works when the state is CONNECTED or CONNECTING.
|
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected &&
|
|
|
|
mState != PresentationConnectionState::Connecting)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
|
2015-10-08 13:11:10 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(service->CloseSession(
|
2016-07-13 01:18:00 +03:00
|
|
|
mId, mRole, nsIPresentationService::CLOSED_REASON_CLOSED)));
|
2015-10-08 13:11:10 +03:00
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
void PresentationConnection::Terminate(ErrorResult& aRv) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-06-14 10:15:07 +03:00
|
|
|
// It only works when the state is CONNECTED.
|
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
|
2015-03-19 10:48:28 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
2015-10-08 13:11:10 +03:00
|
|
|
aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
|
2015-04-22 11:01:38 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(service->TerminateSession(mId, mRole)));
|
2015-04-22 11:01:38 +03:00
|
|
|
}
|
|
|
|
|
2016-08-02 20:11:00 +03:00
|
|
|
bool PresentationConnection::Equals(uint64_t aWindowId, const nsAString& aId) {
|
|
|
|
return GetOwner() && aWindowId == GetOwner()->WindowID() && mId.Equals(aId);
|
|
|
|
}
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
NS_IMETHODIMP
|
2015-10-12 05:36:31 +03:00
|
|
|
PresentationConnection::NotifyStateChange(const nsAString& aSessionId,
|
2016-05-30 09:48:00 +03:00
|
|
|
uint16_t aState, nsresult aReason) {
|
2016-12-16 06:16:31 +03:00
|
|
|
PRES_DEBUG("connection state change:id[%s], state[%" PRIx32
|
|
|
|
"], reason[%" PRIx32 "], role[%d]\n",
|
2016-08-15 13:26:13 +03:00
|
|
|
NS_ConvertUTF16toUTF8(aSessionId).get(), aState,
|
2016-12-16 06:16:31 +03:00
|
|
|
static_cast<uint32_t>(aReason), mRole);
|
2016-08-15 13:26:13 +03:00
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
if (!aSessionId.Equals(mId)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2016-09-29 00:35:00 +03:00
|
|
|
// A terminated connection should always remain in terminated.
|
|
|
|
if (mState == PresentationConnectionState::Terminated) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
PresentationConnectionState state;
|
2015-04-22 11:01:38 +03:00
|
|
|
switch (aState) {
|
2016-05-29 20:59:00 +03:00
|
|
|
case nsIPresentationSessionListener::STATE_CONNECTING:
|
|
|
|
state = PresentationConnectionState::Connecting;
|
|
|
|
break;
|
2015-04-22 11:01:38 +03:00
|
|
|
case nsIPresentationSessionListener::STATE_CONNECTED:
|
2015-10-12 05:36:31 +03:00
|
|
|
state = PresentationConnectionState::Connected;
|
2015-04-22 11:01:38 +03:00
|
|
|
break;
|
2015-10-08 13:11:10 +03:00
|
|
|
case nsIPresentationSessionListener::STATE_CLOSED:
|
2015-10-12 05:36:31 +03:00
|
|
|
state = PresentationConnectionState::Closed;
|
2015-04-22 11:01:38 +03:00
|
|
|
break;
|
|
|
|
case nsIPresentationSessionListener::STATE_TERMINATED:
|
2015-10-12 05:36:31 +03:00
|
|
|
state = PresentationConnectionState::Terminated;
|
2015-04-22 11:01:38 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
NS_WARNING("Unknown presentation session state.");
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mState == state) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
mState = state;
|
|
|
|
|
2016-05-30 09:48:00 +03:00
|
|
|
nsresult rv = ProcessStateChanged(aReason);
|
2016-05-29 20:59:00 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mOwningConnectionList) {
|
|
|
|
mOwningConnectionList->NotifyStateChange(aSessionId, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2015-04-22 11:01:38 +03:00
|
|
|
}
|
|
|
|
|
2016-05-30 09:48:00 +03:00
|
|
|
nsresult PresentationConnection::ProcessStateChanged(nsresult aReason) {
|
|
|
|
switch (mState) {
|
2016-08-02 20:11:00 +03:00
|
|
|
case PresentationConnectionState::Connecting:
|
|
|
|
return NS_OK;
|
2016-05-30 09:48:00 +03:00
|
|
|
case PresentationConnectionState::Connected: {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-05-30 09:48:00 +03:00
|
|
|
RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
|
2018-06-25 19:23:50 +03:00
|
|
|
this, NS_LITERAL_STRING("connect"), CanBubble::eNo);
|
2016-05-30 09:48:00 +03:00
|
|
|
return asyncDispatcher->PostDOMEvent();
|
|
|
|
}
|
|
|
|
case PresentationConnectionState::Closed: {
|
|
|
|
PresentationConnectionClosedReason reason =
|
|
|
|
PresentationConnectionClosedReason::Closed;
|
|
|
|
|
|
|
|
nsString errorMsg;
|
|
|
|
if (NS_FAILED(aReason)) {
|
|
|
|
reason = PresentationConnectionClosedReason::Error;
|
|
|
|
nsCString name, message;
|
|
|
|
|
|
|
|
// If aReason is not a DOM error, use error name as message.
|
|
|
|
if (NS_FAILED(
|
|
|
|
NS_GetNameAndMessageForDOMNSResult(aReason, name, message))) {
|
|
|
|
mozilla::GetErrorName(aReason, message);
|
|
|
|
message.InsertLiteral("Internal error: ", 0);
|
|
|
|
}
|
|
|
|
CopyUTF8toUTF16(message, errorMsg);
|
|
|
|
}
|
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
Unused << NS_WARN_IF(
|
2016-10-04 01:22:34 +03:00
|
|
|
NS_FAILED(DispatchConnectionCloseEvent(reason, errorMsg)));
|
2016-07-13 01:18:00 +03:00
|
|
|
|
|
|
|
return RemoveFromLoadGroup();
|
2016-05-30 09:48:00 +03:00
|
|
|
}
|
|
|
|
case PresentationConnectionState::Terminated: {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (!nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
// Ensure onterminate event is fired.
|
|
|
|
RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
|
2018-06-25 19:23:50 +03:00
|
|
|
this, NS_LITERAL_STRING("terminate"), CanBubble::eNo);
|
2017-08-09 12:38:30 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(asyncDispatcher->PostDOMEvent()));
|
|
|
|
}
|
2016-06-14 10:15:07 +03:00
|
|
|
|
2016-05-30 09:48:00 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = service->UnregisterSessionListener(mId, mRole);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-07-13 01:18:00 +03:00
|
|
|
return RemoveFromLoadGroup();
|
2016-05-30 09:48:00 +03:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
MOZ_CRASH("Unknown presentation session state.");
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
NS_IMETHODIMP
|
2015-10-12 05:36:31 +03:00
|
|
|
PresentationConnection::NotifyMessage(const nsAString& aSessionId,
|
2016-09-18 02:42:00 +03:00
|
|
|
const nsACString& aData, bool aIsBinary) {
|
2016-08-15 13:26:13 +03:00
|
|
|
PRES_DEBUG("connection %s:id[%s], data[%s], role[%d]\n", __func__,
|
|
|
|
NS_ConvertUTF16toUTF8(aSessionId).get(),
|
|
|
|
nsPromiseFlatCString(aData).get(), mRole);
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
if (!aSessionId.Equals(mId)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No message should be expected when the session is not connected.
|
2015-10-12 05:36:31 +03:00
|
|
|
if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
|
2015-04-22 11:01:38 +03:00
|
|
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
|
|
|
}
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(DoReceiveMessage(aData, aIsBinary)))) {
|
|
|
|
AsyncCloseConnectionWithErrorMsg(
|
|
|
|
NS_LITERAL_STRING("Unable to receive a message."));
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult PresentationConnection::DoReceiveMessage(const nsACString& aData,
|
|
|
|
bool aIsBinary) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-04-22 11:01:38 +03:00
|
|
|
// Transform the data.
|
|
|
|
AutoJSAPI jsapi;
|
|
|
|
if (!jsapi.Init(GetOwner())) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
JSContext* cx = jsapi.cx();
|
|
|
|
JS::Rooted<JS::Value> jsData(cx);
|
2016-09-18 02:42:00 +03:00
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (aIsBinary) {
|
|
|
|
if (mBinaryType == PresentationConnectionBinaryType::Blob) {
|
2016-10-25 08:53:54 +03:00
|
|
|
RefPtr<Blob> blob =
|
2019-10-21 08:33:33 +03:00
|
|
|
Blob::CreateStringBlob(GetOwnerGlobal(), aData, EmptyString());
|
2019-10-21 08:33:19 +03:00
|
|
|
if (NS_WARN_IF(!blob)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2016-10-25 08:53:54 +03:00
|
|
|
|
|
|
|
if (!ToJSValue(cx, blob, &jsData)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
2016-09-18 02:42:00 +03:00
|
|
|
}
|
|
|
|
} else if (mBinaryType == PresentationConnectionBinaryType::Arraybuffer) {
|
|
|
|
JS::Rooted<JSObject*> arrayBuf(cx);
|
|
|
|
rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address());
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
jsData.setObject(*arrayBuf);
|
|
|
|
} else {
|
2017-10-25 09:30:31 +03:00
|
|
|
MOZ_CRASH("Unknown binary type!");
|
2016-09-18 02:42:00 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
NS_ConvertUTF8toUTF16 utf16Data(aData);
|
|
|
|
if (NS_WARN_IF(!ToJSValue(cx, utf16Data, &jsData))) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2015-04-22 11:01:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return DispatchMessageEvent(jsData);
|
|
|
|
}
|
|
|
|
|
2016-10-04 01:22:34 +03:00
|
|
|
nsresult PresentationConnection::DispatchConnectionCloseEvent(
|
2016-05-30 09:48:00 +03:00
|
|
|
PresentationConnectionClosedReason aReason, const nsAString& aMessage,
|
2016-09-18 02:42:00 +03:00
|
|
|
bool aDispatchNow) {
|
2017-08-09 12:38:30 +03:00
|
|
|
if (nsContentUtils::ShouldResistFingerprinting()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-05-30 09:48:00 +03:00
|
|
|
if (mState != PresentationConnectionState::Closed) {
|
|
|
|
MOZ_ASSERT(false, "The connection state should be closed.");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2016-10-04 01:22:34 +03:00
|
|
|
PresentationConnectionCloseEventInit init;
|
2016-05-30 09:48:00 +03:00
|
|
|
init.mReason = aReason;
|
|
|
|
init.mMessage = aMessage;
|
|
|
|
|
2016-10-04 01:22:34 +03:00
|
|
|
RefPtr<PresentationConnectionCloseEvent> closedEvent =
|
|
|
|
PresentationConnectionCloseEvent::Constructor(
|
2016-05-30 09:48:00 +03:00
|
|
|
this, NS_LITERAL_STRING("close"), init);
|
|
|
|
closedEvent->SetTrusted(true);
|
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
if (aDispatchNow) {
|
2018-04-05 20:42:41 +03:00
|
|
|
ErrorResult rv;
|
|
|
|
DispatchEvent(*closedEvent, rv);
|
|
|
|
return rv.StealNSResult();
|
2016-09-18 02:42:00 +03:00
|
|
|
}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
2018-04-20 19:53:17 +03:00
|
|
|
new AsyncEventDispatcher(this, closedEvent);
|
2015-04-22 11:01:38 +03:00
|
|
|
return asyncDispatcher->PostDOMEvent();
|
|
|
|
}
|
|
|
|
|
2015-10-12 05:36:31 +03:00
|
|
|
nsresult PresentationConnection::DispatchMessageEvent(
|
|
|
|
JS::Handle<JS::Value> aData) {
|
2015-04-22 11:01:38 +03:00
|
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
|
|
|
if (NS_WARN_IF(!global)) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the origin.
|
|
|
|
nsAutoString origin;
|
|
|
|
nsresult rv = nsContentUtils::GetUTFOrigin(global->PrincipalOrNull(), origin);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-10-12 16:17:10 +03:00
|
|
|
RefPtr<MessageEvent> messageEvent = new MessageEvent(this, nullptr, nullptr);
|
2015-04-22 11:01:38 +03:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
messageEvent->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"),
|
2018-06-25 19:23:50 +03:00
|
|
|
CanBubble::eNo, Cancelable::eNo, aData, origin,
|
2016-10-25 08:48:05 +03:00
|
|
|
EmptyString(), nullptr,
|
|
|
|
Sequence<OwningNonNull<MessagePort>>());
|
2015-08-12 14:39:31 +03:00
|
|
|
messageEvent->SetTrusted(true);
|
2015-04-22 11:01:38 +03:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
2018-04-20 19:53:17 +03:00
|
|
|
new AsyncEventDispatcher(this, messageEvent);
|
2015-04-22 11:01:38 +03:00
|
|
|
return asyncDispatcher->PostDOMEvent();
|
2015-03-19 10:48:28 +03:00
|
|
|
}
|
2016-05-30 09:48:00 +03:00
|
|
|
|
|
|
|
nsresult PresentationConnection::ProcessConnectionWentAway() {
|
|
|
|
if (mState != PresentationConnectionState::Connected &&
|
|
|
|
mState != PresentationConnectionState::Connecting) {
|
|
|
|
// If the state is not connected or connecting, do not need to
|
|
|
|
// close the session.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
mState = PresentationConnectionState::Terminated;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return service->CloseSession(mId, mRole,
|
|
|
|
nsIPresentationService::CLOSED_REASON_WENTAWAY);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::GetName(nsACString& aResult) {
|
|
|
|
aResult.AssignLiteral("about:presentation-connection");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::IsPending(bool* aRetval) {
|
|
|
|
*aRetval = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::GetStatus(nsresult* aStatus) {
|
|
|
|
*aStatus = NS_OK;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::Cancel(nsresult aStatus) {
|
|
|
|
nsCOMPtr<nsIRunnable> event = NewRunnableMethod(
|
2017-06-12 22:34:10 +03:00
|
|
|
"dom::PresentationConnection::ProcessConnectionWentAway", this,
|
|
|
|
&PresentationConnection::ProcessConnectionWentAway);
|
2016-05-30 09:48:00 +03:00
|
|
|
return NS_DispatchToCurrentThread(event);
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::Suspend(void) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::Resume(void) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::GetLoadGroup(nsILoadGroup** aLoadGroup) {
|
|
|
|
*aLoadGroup = nullptr;
|
|
|
|
|
2019-01-02 16:05:23 +03:00
|
|
|
nsCOMPtr<Document> doc = GetOwner() ? GetOwner()->GetExtantDoc() : nullptr;
|
2016-05-30 09:48:00 +03:00
|
|
|
if (!doc) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aLoadGroup = doc->GetDocumentLoadGroup().take();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::SetLoadGroup(nsILoadGroup* aLoadGroup) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::GetLoadFlags(nsLoadFlags* aLoadFlags) {
|
|
|
|
*aLoadFlags = nsIRequest::LOAD_BACKGROUND;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; }
|
2016-07-13 01:18:00 +03:00
|
|
|
|
2020-01-07 23:20:38 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
|
|
|
|
return GetTRRModeImpl(aTRRMode);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresentationConnection::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
|
|
|
|
return SetTRRModeImpl(aTRRMode);
|
|
|
|
}
|
|
|
|
|
2016-07-13 01:18:00 +03:00
|
|
|
nsresult PresentationConnection::AddIntoLoadGroup() {
|
|
|
|
// Avoid adding to loadgroup multiple times
|
|
|
|
if (mWeakLoadGroup) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
|
|
|
nsresult rv = GetLoadGroup(getter_AddRefs(loadGroup));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = loadGroup->AddRequest(this, nullptr);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
mWeakLoadGroup = do_GetWeakReference(loadGroup);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult PresentationConnection::RemoveFromLoadGroup() {
|
|
|
|
if (!mWeakLoadGroup) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mWeakLoadGroup);
|
|
|
|
if (loadGroup) {
|
|
|
|
mWeakLoadGroup = nullptr;
|
|
|
|
return loadGroup->RemoveRequest(this, nullptr, NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2016-09-18 02:42:00 +03:00
|
|
|
|
|
|
|
void PresentationConnection::AsyncCloseConnectionWithErrorMsg(
|
|
|
|
const nsAString& aMessage) {
|
|
|
|
if (mState == PresentationConnectionState::Terminated) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsString message = nsString(aMessage);
|
2017-02-04 00:55:22 +03:00
|
|
|
RefPtr<PresentationConnection> self = this;
|
2017-06-12 22:34:10 +03:00
|
|
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
|
|
|
"dom::PresentationConnection::AsyncCloseConnectionWithErrorMsg",
|
|
|
|
[self, message]() -> void {
|
2016-09-18 02:42:00 +03:00
|
|
|
// Set |mState| to |PresentationConnectionState::Closed| here to avoid
|
|
|
|
// calling |ProcessStateChanged|.
|
2017-02-04 00:55:22 +03:00
|
|
|
self->mState = PresentationConnectionState::Closed;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
// Make sure dispatching the event and closing the connection are
|
|
|
|
// invoked at the same time by setting |aDispatchNow| to true.
|
2017-02-04 00:55:22 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(self->DispatchConnectionCloseEvent(
|
|
|
|
PresentationConnectionClosedReason::Error, message, true)));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-09-18 02:42:00 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
|
|
|
if (NS_WARN_IF(!service)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(service->CloseSession(
|
2017-02-04 00:55:22 +03:00
|
|
|
self->mId, self->mRole,
|
2016-09-18 02:42:00 +03:00
|
|
|
nsIPresentationService::CLOSED_REASON_ERROR)));
|
|
|
|
});
|
|
|
|
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(r)));
|
|
|
|
}
|