188 lines
5.1 KiB
C++
188 lines
5.1 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 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/. */
|
|
|
|
#include "SharedWorkerChild.h"
|
|
#include "mozilla/dom/ErrorEvent.h"
|
|
#include "mozilla/dom/ErrorEventBinding.h"
|
|
#include "mozilla/dom/Exceptions.h"
|
|
#include "mozilla/dom/RootedDictionary.h"
|
|
#include "mozilla/dom/SecurityPolicyViolationEvent.h"
|
|
#include "mozilla/dom/SecurityPolicyViolationEventBinding.h"
|
|
#include "mozilla/dom/ScriptSettings.h"
|
|
#include "mozilla/dom/SharedWorker.h"
|
|
#include "mozilla/dom/WebTransport.h"
|
|
#include "mozilla/dom/WindowGlobalChild.h"
|
|
#include "mozilla/dom/WorkerError.h"
|
|
#include "mozilla/dom/locks/LockManagerChild.h"
|
|
#include "nsGlobalWindowInner.h"
|
|
|
|
namespace mozilla {
|
|
|
|
using namespace ipc;
|
|
|
|
namespace dom {
|
|
|
|
SharedWorkerChild::SharedWorkerChild() : mParent(nullptr), mActive(true) {}
|
|
|
|
SharedWorkerChild::~SharedWorkerChild() = default;
|
|
|
|
void SharedWorkerChild::ActorDestroy(ActorDestroyReason aWhy) {
|
|
mActive = false;
|
|
}
|
|
|
|
void SharedWorkerChild::SendClose() {
|
|
if (mActive) {
|
|
// This is the last message.
|
|
mActive = false;
|
|
PSharedWorkerChild::SendClose();
|
|
}
|
|
}
|
|
|
|
void SharedWorkerChild::SendSuspend() {
|
|
if (mActive) {
|
|
PSharedWorkerChild::SendSuspend();
|
|
}
|
|
}
|
|
|
|
void SharedWorkerChild::SendResume() {
|
|
if (mActive) {
|
|
PSharedWorkerChild::SendResume();
|
|
}
|
|
}
|
|
|
|
void SharedWorkerChild::SendFreeze() {
|
|
if (mActive) {
|
|
PSharedWorkerChild::SendFreeze();
|
|
}
|
|
}
|
|
|
|
void SharedWorkerChild::SendThaw() {
|
|
if (mActive) {
|
|
PSharedWorkerChild::SendThaw();
|
|
}
|
|
}
|
|
|
|
IPCResult SharedWorkerChild::RecvError(const ErrorValue& aValue) {
|
|
if (!mParent) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
if (aValue.type() == ErrorValue::Tnsresult) {
|
|
mParent->ErrorPropagation(aValue.get_nsresult());
|
|
return IPC_OK();
|
|
}
|
|
|
|
nsPIDOMWindowInner* window = mParent->GetOwnerWindow();
|
|
uint64_t innerWindowId = window ? window->WindowID() : 0;
|
|
|
|
if (aValue.type() == ErrorValue::TCSPViolation) {
|
|
SecurityPolicyViolationEventInit violationEventInit;
|
|
if (NS_WARN_IF(
|
|
!violationEventInit.Init(aValue.get_CSPViolation().json()))) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
if (NS_WARN_IF(!window)) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
RefPtr<EventTarget> eventTarget = window->GetExtantDoc();
|
|
if (NS_WARN_IF(!eventTarget)) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
RefPtr<Event> event = SecurityPolicyViolationEvent::Constructor(
|
|
eventTarget, u"securitypolicyviolation"_ns, violationEventInit);
|
|
event->SetTrusted(true);
|
|
|
|
eventTarget->DispatchEvent(*event);
|
|
return IPC_OK();
|
|
}
|
|
|
|
if (aValue.type() == ErrorValue::TErrorMismatchOptions) {
|
|
WorkerErrorReport::LogErrorToConsole(
|
|
u"Failed to connect an existing shared worker because the type or credentials given on the SharedWorker constructor do not match the existing shared worker's type or credentials"_ns);
|
|
}
|
|
|
|
if (aValue.type() == ErrorValue::TErrorData &&
|
|
aValue.get_ErrorData().isWarning()) {
|
|
// Don't fire any events for warnings. Just log to console.
|
|
WorkerErrorReport::LogErrorToConsole(aValue.get_ErrorData(), innerWindowId);
|
|
return IPC_OK();
|
|
}
|
|
|
|
AutoJSAPI jsapi;
|
|
jsapi.Init();
|
|
|
|
RefPtr<Event> event;
|
|
if (aValue.type() == ErrorValue::TErrorData) {
|
|
const ErrorData& errorData = aValue.get_ErrorData();
|
|
RootedDictionary<ErrorEventInit> errorInit(jsapi.cx());
|
|
errorInit.mBubbles = false;
|
|
errorInit.mCancelable = true;
|
|
errorInit.mMessage = errorData.message();
|
|
errorInit.mFilename = errorData.filename();
|
|
errorInit.mLineno = errorData.lineNumber();
|
|
errorInit.mColno = errorData.columnNumber();
|
|
|
|
event = ErrorEvent::Constructor(mParent, u"error"_ns, errorInit);
|
|
} else {
|
|
event = Event::Constructor(mParent, u"error"_ns, EventInit());
|
|
}
|
|
event->SetTrusted(true);
|
|
|
|
ErrorResult res;
|
|
bool defaultActionEnabled =
|
|
mParent->DispatchEvent(*event, CallerType::System, res);
|
|
if (res.Failed()) {
|
|
ThrowAndReport(window, res.StealNSResult());
|
|
return IPC_OK();
|
|
}
|
|
|
|
if (aValue.type() != ErrorValue::TErrorData) {
|
|
MOZ_ASSERT(aValue.type() == ErrorValue::Tvoid_t ||
|
|
aValue.type() == ErrorValue::TErrorMismatchOptions);
|
|
return IPC_OK();
|
|
}
|
|
|
|
if (defaultActionEnabled) {
|
|
WorkerErrorReport::LogErrorToConsole(aValue.get_ErrorData(), innerWindowId);
|
|
}
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
IPCResult SharedWorkerChild::RecvNotifyLock(bool aCreated) {
|
|
if (!mParent) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
locks::LockManagerChild::NotifyBFCacheOnMainThread(mParent->GetOwnerWindow(),
|
|
aCreated);
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
IPCResult SharedWorkerChild::RecvNotifyWebTransport(bool aCreated) {
|
|
if (!mParent) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
WebTransport::NotifyBFCacheOnMainThread(mParent->GetOwnerWindow(), aCreated);
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
IPCResult SharedWorkerChild::RecvTerminate() {
|
|
if (mParent) {
|
|
mParent->Close();
|
|
}
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|