diff options
Diffstat (limited to 'dom/workers/WorkerNavigator.cpp')
-rw-r--r-- | dom/workers/WorkerNavigator.cpp | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/dom/workers/WorkerNavigator.cpp b/dom/workers/WorkerNavigator.cpp new file mode 100644 index 000000000..682c7a22c --- /dev/null +++ b/dom/workers/WorkerNavigator.cpp @@ -0,0 +1,184 @@ +/* -*- 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 "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/PromiseWorkerProxy.h" +#include "mozilla/dom/StorageManager.h" +#include "mozilla/dom/WorkerNavigator.h" +#include "mozilla/dom/WorkerNavigatorBinding.h" + +#include "nsProxyRelease.h" +#include "RuntimeService.h" + +#include "nsIDocument.h" + +#include "WorkerPrivate.h" +#include "WorkerRunnable.h" +#include "WorkerScope.h" + +#include "mozilla/dom/Navigator.h" + +namespace mozilla { +namespace dom { + +using namespace mozilla::dom::workers; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WorkerNavigator, mStorageManager); +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WorkerNavigator, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WorkerNavigator, Release) + +/* static */ already_AddRefed<WorkerNavigator> +WorkerNavigator::Create(bool aOnLine) +{ + RuntimeService* rts = RuntimeService::GetService(); + MOZ_ASSERT(rts); + + const RuntimeService::NavigatorProperties& properties = + rts->GetNavigatorProperties(); + + RefPtr<WorkerNavigator> navigator = + new WorkerNavigator(properties, aOnLine); + + return navigator.forget(); +} + +JSObject* +WorkerNavigator::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) +{ + return WorkerNavigatorBinding::Wrap(aCx, this, aGivenProto); +} + +void +WorkerNavigator::SetLanguages(const nsTArray<nsString>& aLanguages) +{ + WorkerNavigatorBinding::ClearCachedLanguagesValue(this); + mProperties.mLanguages = aLanguages; +} + +void +WorkerNavigator::GetAppName(nsString& aAppName) const +{ + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + if (!mProperties.mAppNameOverridden.IsEmpty() && + !workerPrivate->UsesSystemPrincipal()) { + aAppName = mProperties.mAppNameOverridden; + } else { + aAppName = mProperties.mAppName; + } +} + +void +WorkerNavigator::GetAppVersion(nsString& aAppVersion) const +{ + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + if (!mProperties.mAppVersionOverridden.IsEmpty() && + !workerPrivate->UsesSystemPrincipal()) { + aAppVersion = mProperties.mAppVersionOverridden; + } else { + aAppVersion = mProperties.mAppVersion; + } +} + +void +WorkerNavigator::GetPlatform(nsString& aPlatform) const +{ + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + if (!mProperties.mPlatformOverridden.IsEmpty() && + !workerPrivate->UsesSystemPrincipal()) { + aPlatform = mProperties.mPlatformOverridden; + } else { + aPlatform = mProperties.mPlatform; + } +} + +namespace { + +class GetUserAgentRunnable final : public WorkerMainThreadRunnable +{ + nsString& mUA; + +public: + GetUserAgentRunnable(WorkerPrivate* aWorkerPrivate, nsString& aUA) + : WorkerMainThreadRunnable(aWorkerPrivate, + NS_LITERAL_CSTRING("UserAgent getter")) + , mUA(aUA) + { + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + } + + virtual bool MainThreadRun() override + { + AssertIsOnMainThread(); + + nsCOMPtr<nsPIDOMWindowInner> window = mWorkerPrivate->GetWindow(); + nsCOMPtr<nsIURI> uri; + if (window && window->GetDocShell()) { + nsIDocument* doc = window->GetExtantDoc(); + if (doc) { + doc->NodePrincipal()->GetURI(getter_AddRefs(uri)); + } + } + + bool isCallerChrome = mWorkerPrivate->UsesSystemPrincipal(); + nsresult rv = dom::Navigator::GetUserAgent(window, uri, + isCallerChrome, mUA); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to retrieve user-agent from the worker thread."); + } + + return true; + } +}; + +} // namespace + +void +WorkerNavigator::GetUserAgent(nsString& aUserAgent, ErrorResult& aRv) const +{ + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + RefPtr<GetUserAgentRunnable> runnable = + new GetUserAgentRunnable(workerPrivate, aUserAgent); + + runnable->Dispatch(aRv); +} + +uint64_t +WorkerNavigator::HardwareConcurrency() const +{ + RuntimeService* rts = RuntimeService::GetService(); + MOZ_ASSERT(rts); + + return rts->ClampedHardwareConcurrency(); +} + +StorageManager* +WorkerNavigator::Storage() +{ + if (!mStorageManager) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + RefPtr<nsIGlobalObject> global = workerPrivate->GlobalScope(); + MOZ_ASSERT(global); + + mStorageManager = new StorageManager(global); + } + + return mStorageManager; +} + +} // namespace dom +} // namespace mozilla |