SharedWorkerChild.cpp (5174B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "SharedWorkerChild.h" 8 9 #include "mozilla/dom/ErrorEvent.h" 10 #include "mozilla/dom/ErrorEventBinding.h" 11 #include "mozilla/dom/Exceptions.h" 12 #include "mozilla/dom/RootedDictionary.h" 13 #include "mozilla/dom/ScriptSettings.h" 14 #include "mozilla/dom/SecurityPolicyViolationEvent.h" 15 #include "mozilla/dom/SecurityPolicyViolationEventBinding.h" 16 #include "mozilla/dom/SharedWorker.h" 17 #include "mozilla/dom/WebTransport.h" 18 #include "mozilla/dom/WindowGlobalChild.h" 19 #include "mozilla/dom/WorkerError.h" 20 #include "mozilla/dom/locks/LockManagerChild.h" 21 #include "nsGlobalWindowInner.h" 22 23 namespace mozilla { 24 25 using namespace ipc; 26 27 namespace dom { 28 29 SharedWorkerChild::SharedWorkerChild() : mParent(nullptr), mActive(true) {} 30 31 SharedWorkerChild::~SharedWorkerChild() = default; 32 33 void SharedWorkerChild::ActorDestroy(ActorDestroyReason aWhy) { 34 mActive = false; 35 } 36 37 void SharedWorkerChild::SendClose() { 38 if (mActive) { 39 // This is the last message. 40 mActive = false; 41 PSharedWorkerChild::SendClose(); 42 } 43 } 44 45 void SharedWorkerChild::SendSuspend() { 46 if (mActive) { 47 PSharedWorkerChild::SendSuspend(); 48 } 49 } 50 51 void SharedWorkerChild::SendResume() { 52 if (mActive) { 53 PSharedWorkerChild::SendResume(); 54 } 55 } 56 57 void SharedWorkerChild::SendFreeze() { 58 if (mActive) { 59 PSharedWorkerChild::SendFreeze(); 60 } 61 } 62 63 void SharedWorkerChild::SendThaw() { 64 if (mActive) { 65 PSharedWorkerChild::SendThaw(); 66 } 67 } 68 69 IPCResult SharedWorkerChild::RecvError(const ErrorValue& aValue) { 70 if (!mParent) { 71 return IPC_OK(); 72 } 73 74 if (aValue.type() == ErrorValue::Tnsresult) { 75 mParent->ErrorPropagation(aValue.get_nsresult()); 76 return IPC_OK(); 77 } 78 79 nsPIDOMWindowInner* window = mParent->GetOwnerWindow(); 80 uint64_t innerWindowId = window ? window->WindowID() : 0; 81 82 if (aValue.type() == ErrorValue::TCSPViolation) { 83 SecurityPolicyViolationEventInit violationEventInit; 84 if (NS_WARN_IF( 85 !violationEventInit.Init(aValue.get_CSPViolation().json()))) { 86 return IPC_OK(); 87 } 88 89 if (NS_WARN_IF(!window)) { 90 return IPC_OK(); 91 } 92 93 RefPtr<EventTarget> eventTarget = window->GetExtantDoc(); 94 if (NS_WARN_IF(!eventTarget)) { 95 return IPC_OK(); 96 } 97 98 RefPtr<Event> event = SecurityPolicyViolationEvent::Constructor( 99 eventTarget, u"securitypolicyviolation"_ns, violationEventInit); 100 event->SetTrusted(true); 101 102 eventTarget->DispatchEvent(*event); 103 return IPC_OK(); 104 } 105 106 if (aValue.type() == ErrorValue::TErrorMismatchOptions) { 107 WorkerErrorReport::LogErrorToConsole( 108 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); 109 } 110 111 if (aValue.type() == ErrorValue::TErrorData && 112 aValue.get_ErrorData().isWarning()) { 113 // Don't fire any events for warnings. Just log to console. 114 WorkerErrorReport::LogErrorToConsole(aValue.get_ErrorData(), innerWindowId); 115 return IPC_OK(); 116 } 117 118 AutoJSAPI jsapi; 119 jsapi.Init(); 120 121 RefPtr<Event> event; 122 if (aValue.type() == ErrorValue::TErrorData) { 123 const ErrorData& errorData = aValue.get_ErrorData(); 124 RootedDictionary<ErrorEventInit> errorInit(jsapi.cx()); 125 errorInit.mBubbles = false; 126 errorInit.mCancelable = true; 127 errorInit.mMessage = errorData.message(); 128 errorInit.mFilename = errorData.filename(); 129 errorInit.mLineno = errorData.lineNumber(); 130 errorInit.mColno = errorData.columnNumber(); 131 132 event = ErrorEvent::Constructor(mParent, u"error"_ns, errorInit); 133 } else { 134 event = Event::Constructor(mParent, u"error"_ns, EventInit()); 135 } 136 event->SetTrusted(true); 137 138 ErrorResult res; 139 bool defaultActionEnabled = 140 mParent->DispatchEvent(*event, CallerType::System, res); 141 if (res.Failed()) { 142 ThrowAndReport(window, res.StealNSResult()); 143 return IPC_OK(); 144 } 145 146 if (aValue.type() != ErrorValue::TErrorData) { 147 MOZ_ASSERT(aValue.type() == ErrorValue::Tvoid_t || 148 aValue.type() == ErrorValue::TErrorMismatchOptions); 149 return IPC_OK(); 150 } 151 152 if (defaultActionEnabled) { 153 WorkerErrorReport::LogErrorToConsole(aValue.get_ErrorData(), innerWindowId); 154 } 155 156 return IPC_OK(); 157 } 158 159 IPCResult SharedWorkerChild::RecvNotifyLock(bool aCreated) { 160 if (!mParent) { 161 return IPC_OK(); 162 } 163 164 locks::LockManagerChild::NotifyBFCacheOnMainThread(mParent->GetOwnerWindow(), 165 aCreated); 166 167 return IPC_OK(); 168 } 169 170 IPCResult SharedWorkerChild::RecvNotifyWebTransport(bool aCreated) { 171 if (!mParent) { 172 return IPC_OK(); 173 } 174 175 WebTransport::NotifyBFCacheOnMainThread(mParent->GetOwnerWindow(), aCreated); 176 177 return IPC_OK(); 178 } 179 180 IPCResult SharedWorkerChild::RecvTerminate() { 181 if (mParent) { 182 mParent->Close(); 183 } 184 185 return IPC_OK(); 186 } 187 188 } // namespace dom 189 } // namespace mozilla