1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=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/. */
7 #include "WorkerScope.h"
10 #include "Navigator.h"
11 #include "ScriptLoader.h"
12 #include "WorkerPrivate.h"
15 #include "mozilla/dom/FunctionBinding.h"
16 #include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
17 #include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
20 #include <android/log.h>
23 #include "RuntimeService.h" // For WorkersDumpEnabled().
25 #define UNWRAP_WORKER_OBJECT(Interface, obj, value) \
26 UnwrapObject<prototypes::id::Interface##_workers, \
27 mozilla::dom::Interface##Binding_workers::NativeType>(obj, value)
29 using namespace mozilla::dom
;
30 USING_WORKERS_NAMESPACE
32 BEGIN_WORKERS_NAMESPACE
34 WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate
* aWorkerPrivate
)
35 : mWorkerPrivate(aWorkerPrivate
)
37 mWorkerPrivate
->AssertIsOnWorkerThread();
42 WorkerGlobalScope::~WorkerGlobalScope()
44 // Matches the HoldJSObjects in CreateGlobal.
45 mozilla::DropJSObjects(this);
48 NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerGlobalScope
)
50 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerGlobalScope
,
51 nsDOMEventTargetHelper
)
52 tmp
->mWorkerPrivate
->AssertIsOnWorkerThread();
53 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
55 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope
,
56 nsDOMEventTargetHelper
)
57 tmp
->mWorkerPrivate
->AssertIsOnWorkerThread();
58 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
60 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerGlobalScope
,
61 nsDOMEventTargetHelper
)
62 tmp
->mWorkerPrivate
->AssertIsOnWorkerThread();
64 tmp
->mWorkerPrivate
->TraceTimeouts(aCallbacks
, aClosure
);
65 NS_IMPL_CYCLE_COLLECTION_TRACE_END
67 NS_IMPL_ADDREF_INHERITED(WorkerGlobalScope
, nsDOMEventTargetHelper
)
68 NS_IMPL_RELEASE_INHERITED(WorkerGlobalScope
, nsDOMEventTargetHelper
)
70 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerGlobalScope
)
71 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject
)
72 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper
)
75 WorkerGlobalScope::WrapObject(JSContext
* aCx
, JS::Handle
<JSObject
*> aScope
)
77 MOZ_CRASH("We should never get here!");
80 already_AddRefed
<WorkerLocation
>
81 WorkerGlobalScope::Location()
83 mWorkerPrivate
->AssertIsOnWorkerThread();
86 WorkerPrivate::LocationInfo
& info
= mWorkerPrivate
->GetLocationInfo();
88 mLocation
= WorkerLocation::Create(info
);
89 MOZ_ASSERT(mLocation
);
92 nsRefPtr
<WorkerLocation
> location
= mLocation
;
93 return location
.forget();
96 already_AddRefed
<WorkerNavigator
>
97 WorkerGlobalScope::Navigator()
99 mWorkerPrivate
->AssertIsOnWorkerThread();
102 mNavigator
= WorkerNavigator::Create();
103 MOZ_ASSERT(mNavigator
);
106 nsRefPtr
<WorkerNavigator
> navigator
= mNavigator
;
107 return navigator
.forget();
111 WorkerGlobalScope::Close(JSContext
* aCx
)
113 mWorkerPrivate
->AssertIsOnWorkerThread();
115 mWorkerPrivate
->CloseInternal(aCx
);
118 OnErrorEventHandlerNonNull
*
119 WorkerGlobalScope::GetOnerror()
121 mWorkerPrivate
->AssertIsOnWorkerThread();
123 nsEventListenerManager
*elm
= GetExistingListenerManager();
124 return elm
? elm
->GetOnErrorEventHandler() : nullptr;
128 WorkerGlobalScope::SetOnerror(OnErrorEventHandlerNonNull
* aHandler
)
130 mWorkerPrivate
->AssertIsOnWorkerThread();
132 nsEventListenerManager
*elm
= GetOrCreateListenerManager();
134 elm
->SetEventHandler(aHandler
);
139 WorkerGlobalScope::ImportScripts(JSContext
* aCx
,
140 const Sequence
<nsString
>& aScriptURLs
,
143 mWorkerPrivate
->AssertIsOnWorkerThread();
144 scriptloader::Load(aCx
, mWorkerPrivate
, aScriptURLs
, aRv
);
148 WorkerGlobalScope::SetTimeout(JSContext
* aCx
,
150 const int32_t aTimeout
,
151 const Sequence
<JS::Value
>& aArguments
,
154 mWorkerPrivate
->AssertIsOnWorkerThread();
155 return mWorkerPrivate
->SetTimeout(aCx
, &aHandler
, EmptyString(), aTimeout
,
156 aArguments
, false, aRv
);
160 WorkerGlobalScope::SetTimeout(const nsAString
& aHandler
,
161 const int32_t aTimeout
,
164 mWorkerPrivate
->AssertIsOnWorkerThread();
165 Sequence
<JS::Value
> dummy
;
166 return mWorkerPrivate
->SetTimeout(GetCurrentThreadJSContext(), nullptr,
167 aHandler
, aTimeout
, dummy
, false, aRv
);
171 WorkerGlobalScope::ClearTimeout(int32_t aHandle
, ErrorResult
& aRv
)
173 mWorkerPrivate
->AssertIsOnWorkerThread();
174 mWorkerPrivate
->ClearTimeout(aHandle
);
178 WorkerGlobalScope::SetInterval(JSContext
* aCx
,
180 const Optional
<int32_t>& aTimeout
,
181 const Sequence
<JS::Value
>& aArguments
,
184 mWorkerPrivate
->AssertIsOnWorkerThread();
186 int32_t timeout
= aTimeout
.WasPassed() ? aTimeout
.Value() : 0;
188 return mWorkerPrivate
->SetTimeout(aCx
, &aHandler
, EmptyString(), timeout
,
189 aArguments
, !!timeout
, aRv
);
193 WorkerGlobalScope::SetInterval(const nsAString
& aHandler
,
194 const Optional
<int32_t>& aTimeout
,
197 mWorkerPrivate
->AssertIsOnWorkerThread();
199 Sequence
<JS::Value
> dummy
;
201 int32_t timeout
= aTimeout
.WasPassed() ? aTimeout
.Value() : 0;
203 return mWorkerPrivate
->SetTimeout(GetCurrentThreadJSContext(), nullptr,
204 aHandler
, timeout
, dummy
, !!timeout
, aRv
);
208 WorkerGlobalScope::ClearInterval(int32_t aHandle
, ErrorResult
& aRv
)
210 mWorkerPrivate
->AssertIsOnWorkerThread();
211 mWorkerPrivate
->ClearTimeout(aHandle
);
215 WorkerGlobalScope::Atob(const nsAString
& aAtob
, nsAString
& aOutput
, ErrorResult
& aRv
) const
217 mWorkerPrivate
->AssertIsOnWorkerThread();
218 aRv
= nsContentUtils::Atob(aAtob
, aOutput
);
222 WorkerGlobalScope::Btoa(const nsAString
& aBtoa
, nsAString
& aOutput
, ErrorResult
& aRv
) const
224 mWorkerPrivate
->AssertIsOnWorkerThread();
225 aRv
= nsContentUtils::Btoa(aBtoa
, aOutput
);
229 WorkerGlobalScope::Dump(const Optional
<nsAString
>& aString
) const
231 mWorkerPrivate
->AssertIsOnWorkerThread();
233 if (!aString
.WasPassed()) {
237 if (!mWorkerPrivate
->DumpEnabled()) {
241 NS_ConvertUTF16toUTF8
str(aString
.Value());
244 __android_log_print(ANDROID_LOG_INFO
, "Gecko", "%s", str
.get());
246 fputs(str
.get(), stdout
);
250 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate
* aWorkerPrivate
)
251 : WorkerGlobalScope(aWorkerPrivate
)
256 DedicatedWorkerGlobalScope::Visible(JSContext
* aCx
, JSObject
* aObj
)
258 DedicatedWorkerGlobalScope
* self
= nullptr;
259 nsresult rv
= UNWRAP_WORKER_OBJECT(DedicatedWorkerGlobalScope
, aObj
, self
);
260 return NS_SUCCEEDED(rv
) && self
;
264 DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext
* aCx
,
265 JS::CompartmentOptions
& aOptions
,
266 JSPrincipals
* aPrincipal
)
268 mWorkerPrivate
->AssertIsOnWorkerThread();
269 MOZ_ASSERT(!mWorkerPrivate
->IsSharedWorker());
271 // We're wrapping the global, so the scope is undefined.
272 JS::Rooted
<JSObject
*> scope(aCx
);
274 return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx
, scope
, this,
280 DedicatedWorkerGlobalScope::PostMessage(JSContext
* aCx
,
281 JS::Handle
<JS::Value
> aMessage
,
282 const Optional
<Sequence
<JS::Value
>>& aTransferable
,
285 mWorkerPrivate
->AssertIsOnWorkerThread();
286 mWorkerPrivate
->PostMessageToParent(aCx
, aMessage
, aTransferable
, aRv
);
289 SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate
* aWorkerPrivate
,
290 const nsString
& aName
)
291 : WorkerGlobalScope(aWorkerPrivate
), mName(aName
)
296 SharedWorkerGlobalScope::Visible(JSContext
* aCx
, JSObject
* aObj
)
298 SharedWorkerGlobalScope
* self
= nullptr;
299 nsresult rv
= UNWRAP_WORKER_OBJECT(SharedWorkerGlobalScope
, aObj
, self
);
300 return NS_SUCCEEDED(rv
) && self
;
304 SharedWorkerGlobalScope::WrapGlobalObject(JSContext
* aCx
,
305 JS::CompartmentOptions
& aOptions
,
306 JSPrincipals
* aPrincipal
)
308 mWorkerPrivate
->AssertIsOnWorkerThread();
309 MOZ_ASSERT(mWorkerPrivate
->IsSharedWorker());
311 // We're wrapping the global, so the scope is undefined.
312 JS::Rooted
<JSObject
*> scope(aCx
);
314 return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx
, scope
, this, this,
315 aOptions
, aPrincipal
);
319 GetterOnlyJSNative(JSContext
* aCx
, unsigned aArgc
, JS::Value
* aVp
)
321 JS_ReportErrorNumber(aCx
, js_GetErrorMessage
, nullptr, JSMSG_GETTER_ONLY
);
325 END_WORKERS_NAMESPACE