dom/workers/WorkerScope.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "WorkerScope.h"
michael@0 8
michael@0 9 #include "jsapi.h"
michael@0 10 #include "mozilla/EventListenerManager.h"
michael@0 11 #include "mozilla/dom/FunctionBinding.h"
michael@0 12 #include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
michael@0 13 #include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
michael@0 14 #include "mozilla/dom/Console.h"
michael@0 15
michael@0 16 #ifdef ANDROID
michael@0 17 #include <android/log.h>
michael@0 18 #endif
michael@0 19
michael@0 20 #include "Location.h"
michael@0 21 #include "Navigator.h"
michael@0 22 #include "Principal.h"
michael@0 23 #include "RuntimeService.h"
michael@0 24 #include "ScriptLoader.h"
michael@0 25 #include "WorkerPrivate.h"
michael@0 26
michael@0 27 #define UNWRAP_WORKER_OBJECT(Interface, obj, value) \
michael@0 28 UnwrapObject<prototypes::id::Interface##_workers, \
michael@0 29 mozilla::dom::Interface##Binding_workers::NativeType>(obj, value)
michael@0 30
michael@0 31 using namespace mozilla;
michael@0 32 using namespace mozilla::dom;
michael@0 33 USING_WORKERS_NAMESPACE
michael@0 34
michael@0 35 BEGIN_WORKERS_NAMESPACE
michael@0 36
michael@0 37 WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
michael@0 38 : mWorkerPrivate(aWorkerPrivate)
michael@0 39 {
michael@0 40 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 41
michael@0 42 SetIsDOMBinding();
michael@0 43 }
michael@0 44
michael@0 45 WorkerGlobalScope::~WorkerGlobalScope()
michael@0 46 {
michael@0 47 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 48 }
michael@0 49
michael@0 50 NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerGlobalScope)
michael@0 51
michael@0 52 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerGlobalScope,
michael@0 53 DOMEventTargetHelper)
michael@0 54 tmp->mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 55 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
michael@0 56 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)
michael@0 57 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 58
michael@0 59 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
michael@0 60 DOMEventTargetHelper)
michael@0 61 tmp->mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 62 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
michael@0 63 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
michael@0 64 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 65
michael@0 66 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerGlobalScope,
michael@0 67 DOMEventTargetHelper)
michael@0 68 tmp->mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 69
michael@0 70 tmp->mWorkerPrivate->TraceTimeouts(aCallbacks, aClosure);
michael@0 71 NS_IMPL_CYCLE_COLLECTION_TRACE_END
michael@0 72
michael@0 73 NS_IMPL_ADDREF_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
michael@0 74 NS_IMPL_RELEASE_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
michael@0 75
michael@0 76 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerGlobalScope)
michael@0 77 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
michael@0 78 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
michael@0 79
michael@0 80 JSObject*
michael@0 81 WorkerGlobalScope::WrapObject(JSContext* aCx)
michael@0 82 {
michael@0 83 MOZ_CRASH("We should never get here!");
michael@0 84 }
michael@0 85
michael@0 86 already_AddRefed<Console>
michael@0 87 WorkerGlobalScope::GetConsole()
michael@0 88 {
michael@0 89 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 90
michael@0 91 if (!mConsole) {
michael@0 92 mConsole = new Console(nullptr);
michael@0 93 MOZ_ASSERT(mConsole);
michael@0 94 }
michael@0 95
michael@0 96 return mConsole.forget();
michael@0 97 }
michael@0 98
michael@0 99 already_AddRefed<WorkerLocation>
michael@0 100 WorkerGlobalScope::Location()
michael@0 101 {
michael@0 102 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 103
michael@0 104 if (!mLocation) {
michael@0 105 WorkerPrivate::LocationInfo& info = mWorkerPrivate->GetLocationInfo();
michael@0 106
michael@0 107 mLocation = WorkerLocation::Create(info);
michael@0 108 MOZ_ASSERT(mLocation);
michael@0 109 }
michael@0 110
michael@0 111 nsRefPtr<WorkerLocation> location = mLocation;
michael@0 112 return location.forget();
michael@0 113 }
michael@0 114
michael@0 115 already_AddRefed<WorkerNavigator>
michael@0 116 WorkerGlobalScope::Navigator()
michael@0 117 {
michael@0 118 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 119
michael@0 120 if (!mNavigator) {
michael@0 121 mNavigator = WorkerNavigator::Create(mWorkerPrivate->OnLine());
michael@0 122 MOZ_ASSERT(mNavigator);
michael@0 123 }
michael@0 124
michael@0 125 nsRefPtr<WorkerNavigator> navigator = mNavigator;
michael@0 126 return navigator.forget();
michael@0 127 }
michael@0 128
michael@0 129 already_AddRefed<WorkerNavigator>
michael@0 130 WorkerGlobalScope::GetExistingNavigator() const
michael@0 131 {
michael@0 132 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 133
michael@0 134 nsRefPtr<WorkerNavigator> navigator = mNavigator;
michael@0 135 return navigator.forget();
michael@0 136 }
michael@0 137
michael@0 138 void
michael@0 139 WorkerGlobalScope::Close(JSContext* aCx)
michael@0 140 {
michael@0 141 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 142
michael@0 143 mWorkerPrivate->CloseInternal(aCx);
michael@0 144 }
michael@0 145
michael@0 146 OnErrorEventHandlerNonNull*
michael@0 147 WorkerGlobalScope::GetOnerror()
michael@0 148 {
michael@0 149 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 150
michael@0 151 EventListenerManager* elm = GetExistingListenerManager();
michael@0 152 return elm ? elm->GetOnErrorEventHandler() : nullptr;
michael@0 153 }
michael@0 154
michael@0 155 void
michael@0 156 WorkerGlobalScope::SetOnerror(OnErrorEventHandlerNonNull* aHandler)
michael@0 157 {
michael@0 158 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 159
michael@0 160 EventListenerManager* elm = GetOrCreateListenerManager();
michael@0 161 if (elm) {
michael@0 162 elm->SetEventHandler(aHandler);
michael@0 163 }
michael@0 164 }
michael@0 165
michael@0 166 void
michael@0 167 WorkerGlobalScope::ImportScripts(JSContext* aCx,
michael@0 168 const Sequence<nsString>& aScriptURLs,
michael@0 169 ErrorResult& aRv)
michael@0 170 {
michael@0 171 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 172 scriptloader::Load(aCx, mWorkerPrivate, aScriptURLs, aRv);
michael@0 173 }
michael@0 174
michael@0 175 int32_t
michael@0 176 WorkerGlobalScope::SetTimeout(JSContext* aCx,
michael@0 177 Function& aHandler,
michael@0 178 const int32_t aTimeout,
michael@0 179 const Sequence<JS::Value>& aArguments,
michael@0 180 ErrorResult& aRv)
michael@0 181 {
michael@0 182 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 183 return mWorkerPrivate->SetTimeout(aCx, &aHandler, EmptyString(), aTimeout,
michael@0 184 aArguments, false, aRv);
michael@0 185 }
michael@0 186
michael@0 187 int32_t
michael@0 188 WorkerGlobalScope::SetTimeout(JSContext* /* unused */,
michael@0 189 const nsAString& aHandler,
michael@0 190 const int32_t aTimeout,
michael@0 191 const Sequence<JS::Value>& /* unused */,
michael@0 192 ErrorResult& aRv)
michael@0 193 {
michael@0 194 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 195 Sequence<JS::Value> dummy;
michael@0 196 return mWorkerPrivate->SetTimeout(GetCurrentThreadJSContext(), nullptr,
michael@0 197 aHandler, aTimeout, dummy, false, aRv);
michael@0 198 }
michael@0 199
michael@0 200 void
michael@0 201 WorkerGlobalScope::ClearTimeout(int32_t aHandle, ErrorResult& aRv)
michael@0 202 {
michael@0 203 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 204 mWorkerPrivate->ClearTimeout(aHandle);
michael@0 205 }
michael@0 206
michael@0 207 int32_t
michael@0 208 WorkerGlobalScope::SetInterval(JSContext* aCx,
michael@0 209 Function& aHandler,
michael@0 210 const Optional<int32_t>& aTimeout,
michael@0 211 const Sequence<JS::Value>& aArguments,
michael@0 212 ErrorResult& aRv)
michael@0 213 {
michael@0 214 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 215
michael@0 216 int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
michael@0 217
michael@0 218 return mWorkerPrivate->SetTimeout(aCx, &aHandler, EmptyString(), timeout,
michael@0 219 aArguments, !!timeout, aRv);
michael@0 220 }
michael@0 221
michael@0 222 int32_t
michael@0 223 WorkerGlobalScope::SetInterval(JSContext* /* unused */,
michael@0 224 const nsAString& aHandler,
michael@0 225 const Optional<int32_t>& aTimeout,
michael@0 226 const Sequence<JS::Value>& /* unused */,
michael@0 227 ErrorResult& aRv)
michael@0 228 {
michael@0 229 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 230
michael@0 231 Sequence<JS::Value> dummy;
michael@0 232
michael@0 233 int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
michael@0 234
michael@0 235 return mWorkerPrivate->SetTimeout(GetCurrentThreadJSContext(), nullptr,
michael@0 236 aHandler, timeout, dummy, !!timeout, aRv);
michael@0 237 }
michael@0 238
michael@0 239 void
michael@0 240 WorkerGlobalScope::ClearInterval(int32_t aHandle, ErrorResult& aRv)
michael@0 241 {
michael@0 242 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 243 mWorkerPrivate->ClearTimeout(aHandle);
michael@0 244 }
michael@0 245
michael@0 246 void
michael@0 247 WorkerGlobalScope::Atob(const nsAString& aAtob, nsAString& aOutput, ErrorResult& aRv) const
michael@0 248 {
michael@0 249 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 250 aRv = nsContentUtils::Atob(aAtob, aOutput);
michael@0 251 }
michael@0 252
michael@0 253 void
michael@0 254 WorkerGlobalScope::Btoa(const nsAString& aBtoa, nsAString& aOutput, ErrorResult& aRv) const
michael@0 255 {
michael@0 256 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 257 aRv = nsContentUtils::Btoa(aBtoa, aOutput);
michael@0 258 }
michael@0 259
michael@0 260 void
michael@0 261 WorkerGlobalScope::Dump(const Optional<nsAString>& aString) const
michael@0 262 {
michael@0 263 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 264
michael@0 265 if (!aString.WasPassed()) {
michael@0 266 return;
michael@0 267 }
michael@0 268
michael@0 269 if (!mWorkerPrivate->DumpEnabled()) {
michael@0 270 return;
michael@0 271 }
michael@0 272
michael@0 273 NS_ConvertUTF16toUTF8 str(aString.Value());
michael@0 274
michael@0 275 #ifdef ANDROID
michael@0 276 __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
michael@0 277 #endif
michael@0 278 fputs(str.get(), stdout);
michael@0 279 fflush(stdout);
michael@0 280 }
michael@0 281
michael@0 282 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
michael@0 283 : WorkerGlobalScope(aWorkerPrivate)
michael@0 284 {
michael@0 285 }
michael@0 286
michael@0 287 /* static */ bool
michael@0 288 DedicatedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
michael@0 289 {
michael@0 290 DedicatedWorkerGlobalScope* self = nullptr;
michael@0 291 nsresult rv = UNWRAP_WORKER_OBJECT(DedicatedWorkerGlobalScope, aObj, self);
michael@0 292 return NS_SUCCEEDED(rv) && self;
michael@0 293 }
michael@0 294
michael@0 295 JSObject*
michael@0 296 DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
michael@0 297 {
michael@0 298 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 299 MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
michael@0 300
michael@0 301 JS::CompartmentOptions options;
michael@0 302 mWorkerPrivate->CopyJSCompartmentOptions(options);
michael@0 303
michael@0 304 // We're wrapping the global, so the scope is undefined.
michael@0 305 JS::Rooted<JSObject*> scope(aCx);
michael@0 306
michael@0 307 return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
michael@0 308 options,
michael@0 309 GetWorkerPrincipal());
michael@0 310 }
michael@0 311
michael@0 312 void
michael@0 313 DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
michael@0 314 JS::Handle<JS::Value> aMessage,
michael@0 315 const Optional<Sequence<JS::Value>>& aTransferable,
michael@0 316 ErrorResult& aRv)
michael@0 317 {
michael@0 318 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 319 mWorkerPrivate->PostMessageToParent(aCx, aMessage, aTransferable, aRv);
michael@0 320 }
michael@0 321
michael@0 322 SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
michael@0 323 const nsCString& aName)
michael@0 324 : WorkerGlobalScope(aWorkerPrivate), mName(aName)
michael@0 325 {
michael@0 326 }
michael@0 327
michael@0 328 /* static */ bool
michael@0 329 SharedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
michael@0 330 {
michael@0 331 SharedWorkerGlobalScope* self = nullptr;
michael@0 332 nsresult rv = UNWRAP_WORKER_OBJECT(SharedWorkerGlobalScope, aObj, self);
michael@0 333 return NS_SUCCEEDED(rv) && self;
michael@0 334 }
michael@0 335
michael@0 336 JSObject*
michael@0 337 SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
michael@0 338 {
michael@0 339 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 340 MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
michael@0 341
michael@0 342 JS::CompartmentOptions options;
michael@0 343 mWorkerPrivate->CopyJSCompartmentOptions(options);
michael@0 344
michael@0 345 // We're wrapping the global, so the scope is undefined.
michael@0 346 JS::Rooted<JSObject*> scope(aCx);
michael@0 347
michael@0 348 return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
michael@0 349 GetWorkerPrincipal());
michael@0 350 }
michael@0 351
michael@0 352 bool
michael@0 353 GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
michael@0 354 {
michael@0 355 JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr, JSMSG_GETTER_ONLY);
michael@0 356 return false;
michael@0 357 }
michael@0 358
michael@0 359 END_WORKERS_NAMESPACE

mercurial