dom/workers/WorkerNavigator.cpp
author Gurzau Raul <rgurzau@mozilla.com>
Wed, 13 Dec 2017 23:41:49 +0200
changeset 396289 ccd7b237c4337a00e45bf18ac2d0218c61e1134d
parent 396284 4b52904694f40be316835a479e70c9a78982eafd
child 398235 1cf5ddac1e2078f55aab0ece9d2ce52443f5a29a
permissions -rw-r--r--
Backed out 22 changesets (bug 1419771) for build bustage build/src/dom/base/FuzzingFunctions.cpp on a CLOSED TREE Backed out changeset b2b7b46c8ad0 (bug 1419771) Backed out changeset 0206657d2ea2 (bug 1419771) Backed out changeset f0f4b98a07b6 (bug 1419771) Backed out changeset 4b52904694f4 (bug 1419771) Backed out changeset 9f40cc12d6c6 (bug 1419771) Backed out changeset f500a61f564c (bug 1419771) Backed out changeset 0bd9d964df8a (bug 1419771) Backed out changeset 1397a6bbb446 (bug 1419771) Backed out changeset 7e77a00fa8b5 (bug 1419771) Backed out changeset 5f6df771459a (bug 1419771) Backed out changeset 7624e70b2965 (bug 1419771) Backed out changeset b9d674bdc723 (bug 1419771) Backed out changeset 5e44aeda4196 (bug 1419771) Backed out changeset 601b49f51b41 (bug 1419771) Backed out changeset d12dc5557982 (bug 1419771) Backed out changeset 6c863ab2e986 (bug 1419771) Backed out changeset 0866d79873ab (bug 1419771) Backed out changeset 8ecc91474621 (bug 1419771) Backed out changeset 19b14deed8fe (bug 1419771) Backed out changeset 000c8d5fbc03 (bug 1419771) Backed out changeset 2e263a2519c5 (bug 1419771) Backed out changeset b628d9298be8 (bug 1419771)

/* -*- 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 "mozilla/dom/network/Connection.h"

#include "nsProxyRelease.h"
#include "nsRFPService.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,
                                      mConnection);

NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WorkerNavigator, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WorkerNavigator, Release)

WorkerNavigator::WorkerNavigator(const NavigatorProperties& aProperties,
                                 bool aOnline)
  : mProperties(aProperties)
  , mOnline(aOnline)
{
}

WorkerNavigator::~WorkerNavigator()
{
}

/* 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, CallerType aCallerType) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  if ((!mProperties.mAppNameOverridden.IsEmpty() ||
       workerPrivate->ResistFingerprintingEnabled()) &&
      !workerPrivate->UsesSystemPrincipal()) {
    // We will spoof this value when 'privacy.resistFingerprinting' is true.
    // See nsRFPService.h for spoofed value.
    aAppName = workerPrivate->ResistFingerprintingEnabled() ?
      NS_LITERAL_STRING(SPOOFED_APPNAME) : mProperties.mAppNameOverridden;
  } else {
    aAppName = mProperties.mAppName;
  }
}

void
WorkerNavigator::GetAppVersion(nsString& aAppVersion, CallerType aCallerType,
                               ErrorResult& aRv) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  if ((!mProperties.mAppVersionOverridden.IsEmpty() ||
       workerPrivate->ResistFingerprintingEnabled()) &&
      !workerPrivate->UsesSystemPrincipal()) {
    // We will spoof this value when 'privacy.resistFingerprinting' is true.
    // See nsRFPService.h for spoofed value.
    aAppVersion = workerPrivate->ResistFingerprintingEnabled() ?
      NS_LITERAL_STRING(SPOOFED_APPVERSION) : mProperties.mAppVersionOverridden;
  } else {
    aAppVersion = mProperties.mAppVersion;
  }
}

void
WorkerNavigator::GetPlatform(nsString& aPlatform, CallerType aCallerType,
                             ErrorResult& aRv) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  if ((!mProperties.mPlatformOverridden.IsEmpty() ||
       workerPrivate->ResistFingerprintingEnabled()) &&
      !workerPrivate->UsesSystemPrincipal()) {
    // We will spoof this value when 'privacy.resistFingerprinting' is true.
    // See nsRFPService.h for spoofed value.
    aPlatform = workerPrivate->ResistFingerprintingEnabled() ?
      NS_LITERAL_STRING(SPOOFED_PLATFORM) : 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();

    bool isCallerChrome = mWorkerPrivate->UsesSystemPrincipal();
    nsresult rv = dom::Navigator::GetUserAgent(window, 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, CallerType aCallerType,
                              ErrorResult& aRv) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  RefPtr<GetUserAgentRunnable> runnable =
    new GetUserAgentRunnable(workerPrivate, aUserAgent);

  runnable->Dispatch(Terminating, 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;
}

network::Connection*
WorkerNavigator::GetConnection(ErrorResult& aRv)
{
  if (!mConnection) {
    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
    MOZ_ASSERT(workerPrivate);

    mConnection = network::Connection::CreateForWorker(workerPrivate, aRv);
  }

  return mConnection;
}


} // namespace dom
} // namespace mozilla