From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- dom/workers/WorkerNavigator.cpp | 293 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 dom/workers/WorkerNavigator.cpp (limited to 'dom/workers/WorkerNavigator.cpp') diff --git a/dom/workers/WorkerNavigator.cpp b/dom/workers/WorkerNavigator.cpp new file mode 100644 index 0000000000..fc16071f74 --- /dev/null +++ b/dom/workers/WorkerNavigator.cpp @@ -0,0 +1,293 @@ +/* -*- 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/WorkerNavigator.h" + +#include + +#include "ErrorList.h" +#include "MainThreadUtils.h" +#include "RuntimeService.h" +#include "WorkerRunnable.h" +#include "WorkerScope.h" +#include "mozilla/dom/LockManager.h" +#include "mozilla/dom/MediaCapabilities.h" +#include "mozilla/dom/Navigator.h" +#include "mozilla/dom/StorageManager.h" +#include "mozilla/dom/WorkerCommon.h" +#include "mozilla/dom/WorkerNavigatorBinding.h" +#include "mozilla/dom/WorkerStatus.h" +#include "mozilla/dom/network/Connection.h" +#include "mozilla/webgpu/Instance.h" +#include "nsCOMPtr.h" +#include "nsDebug.h" +#include "nsError.h" +#include "nsIGlobalObject.h" +#include "nsLiteralString.h" +#include "nsPIDOMWindow.h" +#include "nsRFPService.h" +#include "nsString.h" + +class JSObject; +struct JSContext; + +namespace mozilla::dom { + +using namespace workerinternals; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WorkerNavigator) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WorkerNavigator) + tmp->Invalidate(); + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WorkerNavigator) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStorageManager) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaCapabilities) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebGpu) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocks) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +WorkerNavigator::WorkerNavigator(const NavigatorProperties& aProperties, + bool aOnline) + : mProperties(aProperties), mOnline(aOnline) {} + +WorkerNavigator::~WorkerNavigator() { Invalidate(); } + +/* static */ +already_AddRefed WorkerNavigator::Create(bool aOnLine) { + RuntimeService* rts = RuntimeService::GetService(); + MOZ_ASSERT(rts); + + const RuntimeService::NavigatorProperties& properties = + rts->GetNavigatorProperties(); + + RefPtr navigator = new WorkerNavigator(properties, aOnLine); + + return navigator.forget(); +} + +void WorkerNavigator::Invalidate() { + if (mStorageManager) { + mStorageManager->Shutdown(); + mStorageManager = nullptr; + } + + mConnection = nullptr; + + mMediaCapabilities = nullptr; + + mWebGpu = nullptr; + + mLocks = nullptr; +} + +JSObject* WorkerNavigator::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return WorkerNavigator_Binding::Wrap(aCx, this, aGivenProto); +} + +void WorkerNavigator::SetLanguages(const nsTArray& aLanguages) { + WorkerNavigator_Binding::ClearCachedLanguagesValue(this); + mProperties.mLanguages = aLanguages.Clone(); +} + +void WorkerNavigator::GetAppName(nsString& aAppName, + CallerType aCallerType) const { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + if (aCallerType != CallerType::System) { + if (workerPrivate->GlobalScope()->ShouldResistFingerprinting( + RFPTarget::NavigatorAppName)) { + // See nsRFPService.h for spoofed value. + aAppName.AssignLiteral(SPOOFED_APPNAME); + return; + } + + if (!mProperties.mAppNameOverridden.IsEmpty()) { + aAppName = mProperties.mAppNameOverridden; + return; + } + } + + aAppName = mProperties.mAppName; +} + +void WorkerNavigator::GetAppVersion(nsString& aAppVersion, + CallerType aCallerType, + ErrorResult& aRv) const { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + if (aCallerType != CallerType::System) { + if (workerPrivate->GlobalScope()->ShouldResistFingerprinting( + RFPTarget::NavigatorAppVersion)) { + // See nsRFPService.h for spoofed value. + aAppVersion.AssignLiteral(SPOOFED_APPVERSION); + return; + } + + if (!mProperties.mAppVersionOverridden.IsEmpty()) { + aAppVersion = mProperties.mAppVersionOverridden; + return; + } + } + + aAppVersion = mProperties.mAppVersion; +} + +void WorkerNavigator::GetPlatform(nsString& aPlatform, CallerType aCallerType, + ErrorResult& aRv) const { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + if (aCallerType != CallerType::System) { + if (workerPrivate->GlobalScope()->ShouldResistFingerprinting( + RFPTarget::NavigatorPlatform)) { + // See nsRFPService.h for spoofed value. + aPlatform.AssignLiteral(SPOOFED_PLATFORM); + return; + } + + if (!mProperties.mPlatformOverridden.IsEmpty()) { + aPlatform = mProperties.mPlatformOverridden; + return; + } + } + + aPlatform = mProperties.mPlatform; +} + +namespace { + +/* + * This Worker Runnable needs to check RFP; but our standard way of doing so + * relies on accessing GlobalScope() - which can only be accessed on the worker + * thread. So we need to pass it in. + */ +class GetUserAgentRunnable final : public WorkerMainThreadRunnable { + nsString& mUA; + bool mShouldResistFingerprinting; + + public: + GetUserAgentRunnable(WorkerPrivate* aWorkerPrivate, nsString& aUA, + bool aShouldResistFingerprinting) + : WorkerMainThreadRunnable(aWorkerPrivate, "UserAgent getter"_ns), + mUA(aUA), + mShouldResistFingerprinting(aShouldResistFingerprinting) { + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + } + + virtual bool MainThreadRun() override { + AssertIsOnMainThread(); + + nsCOMPtr window = mWorkerPrivate->GetWindow(); + + nsresult rv = + dom::Navigator::GetUserAgent(window, mWorkerPrivate->GetDocument(), + Some(mShouldResistFingerprinting), mUA); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to retrieve user-agent from the worker thread."); + } + + return true; + } +}; + +} // namespace + +void WorkerNavigator::GetUserAgent(nsString& aUserAgent, CallerType aCallerType, + ErrorResult& aRv) const { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + RefPtr runnable = new GetUserAgentRunnable( + workerPrivate, aUserAgent, + workerPrivate->GlobalScope()->ShouldResistFingerprinting( + RFPTarget::NavigatorUserAgent)); + + runnable->Dispatch(Canceling, aRv); +} + +uint64_t WorkerNavigator::HardwareConcurrency() const { + RuntimeService* rts = RuntimeService::GetService(); + MOZ_ASSERT(rts); + + WorkerPrivate* aWorkerPrivate = GetCurrentThreadWorkerPrivate(); + bool rfp = aWorkerPrivate->GlobalScope()->ShouldResistFingerprinting( + RFPTarget::NavigatorHWConcurrency); + + return rts->ClampedHardwareConcurrency(rfp); +} + +StorageManager* WorkerNavigator::Storage() { + if (!mStorageManager) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + RefPtr global = workerPrivate->GlobalScope(); + MOZ_ASSERT(global); + + mStorageManager = new StorageManager(global); + } + + return mStorageManager; +} + +network::Connection* WorkerNavigator::GetConnection(ErrorResult& aRv) { + if (!mConnection) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + mConnection = network::Connection::CreateForWorker(workerPrivate, aRv); + } + + return mConnection; +} + +dom::MediaCapabilities* WorkerNavigator::MediaCapabilities() { + if (!mMediaCapabilities) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + nsIGlobalObject* global = workerPrivate->GlobalScope(); + MOZ_ASSERT(global); + + mMediaCapabilities = new dom::MediaCapabilities(global); + } + return mMediaCapabilities; +} + +webgpu::Instance* WorkerNavigator::Gpu() { + if (!mWebGpu) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + nsIGlobalObject* global = workerPrivate->GlobalScope(); + MOZ_ASSERT(global); + + mWebGpu = webgpu::Instance::Create(global); + } + return mWebGpu; +} + +dom::LockManager* WorkerNavigator::Locks() { + if (!mLocks) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + nsIGlobalObject* global = workerPrivate->GlobalScope(); + MOZ_ASSERT(global); + + mLocks = new dom::LockManager(global); + } + return mLocks; +} + +} // namespace mozilla::dom -- cgit v1.2.3