зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1323172 - Expose NetworkInformation interface to workers, r=bkelly
This commit is contained in:
Родитель
4a9a623faf
Коммит
130d95f581
|
@ -1727,7 +1727,7 @@ Navigator::GetConnection(ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
mConnection = new network::Connection(mWindow);
|
||||
mConnection = network::Connection::CreateForWindow(mWindow);
|
||||
}
|
||||
|
||||
return mConnection;
|
||||
|
|
|
@ -104,3 +104,4 @@ MSG_DEF(MSG_CACHE_STREAM_CLOSED, 0, JSEXN_TYPEERR, "Response body is a cache fil
|
|||
MSG_DEF(MSG_TIME_VALUE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "{0} is outside the supported range for time values.")
|
||||
MSG_DEF(MSG_ONLY_IF_CACHED_WITHOUT_SAME_ORIGIN, 1, JSEXN_TYPEERR, "Request mode '{0}' was used, but request cache mode 'only-if-cached' can only be used with request mode 'same-origin'.")
|
||||
MSG_DEF(MSG_THRESHOLD_RANGE_ERROR, 0, JSEXN_RANGEERR, "Threshold values must all be in the range [0, 1].")
|
||||
MSG_DEF(MSG_WORKER_THREAD_SHUTTING_DOWN, 0, JSEXN_TYPEERR, "The Worker thread is shutting down.")
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
* 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 <limits>
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/dom/network/Connection.h"
|
||||
#include "Connection.h"
|
||||
#include "ConnectionMainThread.h"
|
||||
#include "ConnectionWorker.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "Constants.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
/**
|
||||
* We have to use macros here because our leak analysis tool things we are
|
||||
|
@ -19,6 +19,9 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using namespace workers;
|
||||
|
||||
namespace network {
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE_INHERITED(Connection, DOMEventTargetHelper,
|
||||
|
@ -34,63 +37,100 @@ Connection::Connection(nsPIDOMWindowInner* aWindow)
|
|||
, mType(static_cast<ConnectionType>(kDefaultType))
|
||||
, mIsWifi(kDefaultIsWifi)
|
||||
, mDHCPGateway(kDefaultDHCPGateway)
|
||||
, mBeenShutDown(false)
|
||||
{
|
||||
hal::RegisterNetworkObserver(this);
|
||||
}
|
||||
|
||||
hal::NetworkInformation networkInfo;
|
||||
hal::GetCurrentNetworkInformation(&networkInfo);
|
||||
|
||||
UpdateFromNetworkInfo(networkInfo);
|
||||
Connection::~Connection()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Connection);
|
||||
MOZ_ASSERT(mBeenShutDown);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::Shutdown()
|
||||
{
|
||||
hal::UnregisterNetworkObserver(this);
|
||||
NS_ASSERT_OWNINGTHREAD(Connection);
|
||||
|
||||
if (mBeenShutDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBeenShutDown = true;
|
||||
ShutdownInternal();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::GetIsWifi(bool *aIsWifi)
|
||||
Connection::GetIsWifi(bool* aIsWifi)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsWifi);
|
||||
NS_ASSERT_OWNINGTHREAD(Connection);
|
||||
|
||||
*aIsWifi = mIsWifi;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::GetDhcpGateway(uint32_t *aGW)
|
||||
Connection::GetDhcpGateway(uint32_t* aGW)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aGW);
|
||||
NS_ASSERT_OWNINGTHREAD(Connection);
|
||||
|
||||
*aGW = mDHCPGateway;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Connection::UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo)
|
||||
{
|
||||
mType = static_cast<ConnectionType>(aNetworkInfo.type());
|
||||
mIsWifi = aNetworkInfo.isWifi();
|
||||
mDHCPGateway = aNetworkInfo.dhcpGateway();
|
||||
}
|
||||
|
||||
void
|
||||
Connection::Notify(const hal::NetworkInformation& aNetworkInfo)
|
||||
{
|
||||
ConnectionType previousType = mType;
|
||||
|
||||
UpdateFromNetworkInfo(aNetworkInfo);
|
||||
|
||||
if (previousType == mType) {
|
||||
return;
|
||||
}
|
||||
|
||||
DispatchTrustedEvent(CHANGE_EVENT_NAME);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Connection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return NetworkInformationBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::Update(ConnectionType aType, bool aIsWifi, bool aDHCPGateway,
|
||||
bool aNotify)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Connection);
|
||||
|
||||
ConnectionType previousType = mType;
|
||||
|
||||
mType = aType;
|
||||
mIsWifi = aIsWifi;
|
||||
mDHCPGateway = aDHCPGateway;
|
||||
|
||||
if (aNotify && previousType != aType) {
|
||||
DispatchTrustedEvent(CHANGE_EVENT_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Connection::IsEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
return Preferences::GetBool("dom.netinfo.enabled");
|
||||
}
|
||||
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
return workerPrivate->NetworkInformationEnabled();
|
||||
}
|
||||
|
||||
/* static */ Connection*
|
||||
Connection::CreateForWindow(nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
return new ConnectionMainThread(aWindow);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Connection>
|
||||
Connection::CreateForWorker(workers::WorkerPrivate* aWorkerPrivate,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
return ConnectionWorker::Create(aWorkerPrivate, aRv);
|
||||
}
|
||||
|
||||
} // namespace network
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,15 +7,17 @@
|
|||
#ifndef mozilla_dom_network_Connection_h
|
||||
#define mozilla_dom_network_Connection_h
|
||||
|
||||
#include "Types.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/Observer.h"
|
||||
#include "mozilla/dom/NetworkInformationBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsINetworkProperties.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace workers {
|
||||
class WorkerPrivate;
|
||||
} // namespace workers
|
||||
|
||||
namespace hal {
|
||||
class NetworkInformation;
|
||||
} // namespace hal
|
||||
|
@ -23,40 +25,46 @@ class NetworkInformation;
|
|||
namespace dom {
|
||||
namespace network {
|
||||
|
||||
class Connection final : public DOMEventTargetHelper
|
||||
, public NetworkObserver
|
||||
, public nsINetworkProperties
|
||||
class Connection : public DOMEventTargetHelper
|
||||
, public nsINetworkProperties
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINETWORKPROPERTIES
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
|
||||
|
||||
explicit Connection(nsPIDOMWindowInner* aWindow);
|
||||
static bool IsEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
static Connection*
|
||||
CreateForWindow(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
static already_AddRefed<Connection>
|
||||
CreateForWorker(workers::WorkerPrivate* aWorkerPrivate,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
// For IObserver
|
||||
void Notify(const hal::NetworkInformation& aNetworkInfo) override;
|
||||
|
||||
// WebIDL
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
ConnectionType Type() const { return mType; }
|
||||
|
||||
IMPL_EVENT_HANDLER(typechange)
|
||||
|
||||
protected:
|
||||
Connection(nsPIDOMWindowInner* aWindow);
|
||||
virtual ~Connection();
|
||||
|
||||
void Update(ConnectionType aType, bool aIsWifi, bool aDHCPGateway,
|
||||
bool aNotify);
|
||||
|
||||
virtual void ShutdownInternal() = 0;
|
||||
|
||||
private:
|
||||
~Connection() {}
|
||||
|
||||
/**
|
||||
* Update the connection information stored in the object using a
|
||||
* NetworkInformation object.
|
||||
*/
|
||||
void UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo);
|
||||
|
||||
/**
|
||||
* The type of current connection.
|
||||
*/
|
||||
|
@ -71,6 +79,8 @@ private:
|
|||
* DHCP Gateway information for IPV4, in network byte order. 0 if unassigned.
|
||||
*/
|
||||
uint32_t mDHCPGateway;
|
||||
|
||||
bool mBeenShutDown;
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- 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 <limits>
|
||||
#include "mozilla/Hal.h"
|
||||
#include "ConnectionMainThread.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace network {
|
||||
|
||||
ConnectionMainThread::ConnectionMainThread(nsPIDOMWindowInner* aWindow)
|
||||
: Connection(aWindow)
|
||||
{
|
||||
hal::RegisterNetworkObserver(this);
|
||||
|
||||
hal::NetworkInformation networkInfo;
|
||||
hal::GetCurrentNetworkInformation(&networkInfo);
|
||||
|
||||
UpdateFromNetworkInfo(networkInfo, false);
|
||||
}
|
||||
|
||||
ConnectionMainThread::~ConnectionMainThread()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionMainThread::ShutdownInternal()
|
||||
{
|
||||
hal::UnregisterNetworkObserver(this);
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionMainThread::UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo,
|
||||
bool aNotify)
|
||||
{
|
||||
Update(static_cast<ConnectionType>(aNetworkInfo.type()),
|
||||
aNetworkInfo.isWifi(), aNetworkInfo.dhcpGateway(), aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionMainThread::Notify(const hal::NetworkInformation& aNetworkInfo)
|
||||
{
|
||||
UpdateFromNetworkInfo(aNetworkInfo, true);
|
||||
}
|
||||
|
||||
} // namespace network
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_network_ConnectionMainThread_h
|
||||
#define mozilla_dom_network_ConnectionMainThread_h
|
||||
|
||||
#include "Connection.h"
|
||||
#include "mozilla/Observer.h"
|
||||
#include "Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace network {
|
||||
|
||||
class ConnectionMainThread final : public Connection
|
||||
, public NetworkObserver
|
||||
{
|
||||
public:
|
||||
explicit ConnectionMainThread(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
// For IObserver
|
||||
void Notify(const hal::NetworkInformation& aNetworkInfo) override;
|
||||
|
||||
private:
|
||||
~ConnectionMainThread();
|
||||
|
||||
virtual void ShutdownInternal() override;
|
||||
|
||||
/**
|
||||
* Update the connection information stored in the object using a
|
||||
* NetworkInformation object.
|
||||
*/
|
||||
void UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo,
|
||||
bool aNotify);
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_network_ConnectionMainThread_h
|
|
@ -0,0 +1,249 @@
|
|||
/* -*- 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 <limits>
|
||||
#include "mozilla/Hal.h"
|
||||
#include "ConnectionWorker.h"
|
||||
#include "WorkerRunnable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace network {
|
||||
|
||||
class ConnectionProxy final : public NetworkObserver
|
||||
, public WorkerHolder
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ConnectionProxy)
|
||||
|
||||
static already_AddRefed<ConnectionProxy>
|
||||
Create(WorkerPrivate* aWorkerPrivate, ConnectionWorker* aConnection)
|
||||
{
|
||||
RefPtr<ConnectionProxy> proxy =
|
||||
new ConnectionProxy(aWorkerPrivate, aConnection);
|
||||
if (!proxy->HoldWorker(aWorkerPrivate, Closing)) {
|
||||
proxy->mConnection = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return proxy.forget();
|
||||
}
|
||||
|
||||
// For IObserver - main-thread only.
|
||||
void Notify(const hal::NetworkInformation& aNetworkInfo) override;
|
||||
|
||||
// Worker notification
|
||||
virtual bool Notify(Status aStatus) override
|
||||
{
|
||||
Shutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Shutdown();
|
||||
|
||||
void Update(ConnectionType aType, bool aIsWifi, bool aDHCPGateway)
|
||||
{
|
||||
MOZ_ASSERT(mConnection);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
mConnection->Update(aType, aIsWifi, aDHCPGateway, true);
|
||||
}
|
||||
|
||||
private:
|
||||
ConnectionProxy(WorkerPrivate* aWorkerPrivate, ConnectionWorker* aConnection)
|
||||
: mConnection(aConnection)
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
MOZ_ASSERT(mConnection);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
~ConnectionProxy() = default;
|
||||
|
||||
// Raw pointer because the ConnectionWorker keeps alive the proxy.
|
||||
// This is touched only on the worker-thread and it's nullified when the
|
||||
// shutdown procedure starts.
|
||||
ConnectionWorker* mConnection;
|
||||
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// This class initializes the hal observer on the main-thread.
|
||||
class InitializeRunnable : public WorkerMainThreadRunnable
|
||||
{
|
||||
private:
|
||||
// raw pointer because this is a sync runnable.
|
||||
ConnectionProxy* mProxy;
|
||||
hal::NetworkInformation& mNetworkInfo;
|
||||
|
||||
public:
|
||||
InitializeRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
ConnectionProxy* aProxy,
|
||||
hal::NetworkInformation& aNetworkInfo)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate,
|
||||
NS_LITERAL_CSTRING("ConnectionWorker :: Initialize"))
|
||||
, mProxy(aProxy)
|
||||
, mNetworkInfo(aNetworkInfo)
|
||||
{
|
||||
MOZ_ASSERT(aProxy);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool
|
||||
MainThreadRun()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
hal::RegisterNetworkObserver(mProxy);
|
||||
hal::GetCurrentNetworkInformation(&mNetworkInfo);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// This class turns down the hal observer on the main-thread.
|
||||
class ShutdownRunnable : public WorkerMainThreadRunnable
|
||||
{
|
||||
private:
|
||||
// raw pointer because this is a sync runnable.
|
||||
ConnectionProxy* mProxy;
|
||||
|
||||
public:
|
||||
ShutdownRunnable(WorkerPrivate* aWorkerPrivate, ConnectionProxy* aProxy)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate,
|
||||
NS_LITERAL_CSTRING("ConnectionWorker :: Shutdown"))
|
||||
, mProxy(aProxy)
|
||||
{
|
||||
MOZ_ASSERT(aProxy);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool
|
||||
MainThreadRun()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
hal::UnregisterNetworkObserver(mProxy);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class NotifyRunnable : public WorkerRunnable
|
||||
{
|
||||
private:
|
||||
RefPtr<ConnectionProxy> mProxy;
|
||||
|
||||
const ConnectionType mConnectionType;
|
||||
const bool mIsWifi;
|
||||
const bool mDHCPGateway;
|
||||
|
||||
public:
|
||||
NotifyRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
ConnectionProxy* aProxy, ConnectionType aType,
|
||||
bool aIsWifi, bool aDHCPGateway)
|
||||
: WorkerRunnable(aWorkerPrivate)
|
||||
, mProxy(aProxy)
|
||||
, mConnectionType(aType)
|
||||
, mIsWifi(aIsWifi)
|
||||
, mDHCPGateway(aDHCPGateway)
|
||||
{
|
||||
MOZ_ASSERT(aProxy);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
mProxy->Update(mConnectionType, mIsWifi, mDHCPGateway);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static */ already_AddRefed<ConnectionWorker>
|
||||
ConnectionWorker::Create(WorkerPrivate* aWorkerPrivate, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<ConnectionWorker> c = new ConnectionWorker(aWorkerPrivate);
|
||||
c->mProxy = ConnectionProxy::Create(aWorkerPrivate, c);
|
||||
if (!c->mProxy) {
|
||||
aRv.ThrowTypeError<MSG_WORKER_THREAD_SHUTTING_DOWN>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hal::NetworkInformation networkInfo;
|
||||
RefPtr<InitializeRunnable> runnable =
|
||||
new InitializeRunnable(aWorkerPrivate, c->mProxy, networkInfo);
|
||||
|
||||
runnable->Dispatch(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
c->Update(static_cast<ConnectionType>(networkInfo.type()),
|
||||
networkInfo.isWifi(), networkInfo.dhcpGateway(), false);
|
||||
return c.forget();
|
||||
}
|
||||
|
||||
ConnectionWorker::ConnectionWorker(WorkerPrivate* aWorkerPrivate)
|
||||
: Connection(nullptr)
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
ConnectionWorker::~ConnectionWorker()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionWorker::ShutdownInternal()
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
mProxy->Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionProxy::Notify(const hal::NetworkInformation& aNetworkInfo)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<NotifyRunnable> runnable =
|
||||
new NotifyRunnable(mWorkerPrivate, this,
|
||||
static_cast<ConnectionType>(aNetworkInfo.type()),
|
||||
aNetworkInfo.isWifi(), aNetworkInfo.dhcpGateway());
|
||||
runnable->Dispatch();
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionProxy::Shutdown()
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// Already shut down.
|
||||
if (!mConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
mConnection = nullptr;
|
||||
|
||||
RefPtr<ShutdownRunnable> runnable =
|
||||
new ShutdownRunnable(mWorkerPrivate, this);
|
||||
|
||||
ErrorResult rv;
|
||||
runnable->Dispatch(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
}
|
||||
|
||||
ReleaseWorker();
|
||||
}
|
||||
|
||||
} // namespace network
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_network_ConnectionWorker_h
|
||||
#define mozilla_dom_network_ConnectionWorker_h
|
||||
|
||||
#include "Connection.h"
|
||||
#include "mozilla/Observer.h"
|
||||
#include "Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace network {
|
||||
|
||||
class ConnectionProxy;
|
||||
|
||||
class ConnectionWorker final : public Connection
|
||||
{
|
||||
friend class ConnectionProxy;
|
||||
|
||||
public:
|
||||
static already_AddRefed<ConnectionWorker>
|
||||
Create(workers::WorkerPrivate* aWorkerPrivate, ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
explicit ConnectionWorker(workers::WorkerPrivate* aWorkerPrivate);
|
||||
~ConnectionWorker();
|
||||
|
||||
virtual void ShutdownInternal() override;
|
||||
|
||||
workers::WorkerPrivate* mWorkerPrivate;
|
||||
RefPtr<ConnectionProxy> mProxy;
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_network_ConnectionWorker_h
|
|
@ -29,6 +29,8 @@ EXPORTS.mozilla.dom.network += [
|
|||
|
||||
UNIFIED_SOURCES += [
|
||||
'Connection.cpp',
|
||||
'ConnectionMainThread.cpp',
|
||||
'ConnectionWorker.cpp',
|
||||
'TCPServerSocket.cpp',
|
||||
'TCPServerSocketChild.cpp',
|
||||
'TCPServerSocketParent.cpp',
|
||||
|
@ -58,6 +60,10 @@ IPDL_SOURCES += [
|
|||
'PUDPSocket.ipdl',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../workers',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
add_task.js
|
||||
worker_network_basics.js
|
||||
|
||||
[test_network_basics.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_network_basics_worker.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_tcpsocket_default_permissions.html]
|
||||
[test_tcpsocket_enabled_no_perm.html]
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Network in workers API</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Network Information API **/
|
||||
function test() {
|
||||
let w = new Worker('worker_network_basics.js');
|
||||
w.onmessage = function(e) {
|
||||
if (e.data.type == 'status') {
|
||||
ok(e.data.status, e.data.msg);
|
||||
} else if (e.data.type == 'finish') {
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
ok(false, "Unknown message type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.netinfo.enabled", true]]}, test);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
function ok(a, msg) {
|
||||
postMessage({type: 'status', status: !!a, msg: msg});
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
ok(a === b, msg);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
postMessage({type: 'finish'});
|
||||
}
|
||||
|
||||
ok('connection' in navigator, "navigator.connection should exist");
|
||||
|
||||
ok(navigator.connection, "navigator.connection returns an object");
|
||||
|
||||
ok(navigator.connection instanceof EventTarget,
|
||||
"navigator.connection is a EventTarget object");
|
||||
|
||||
ok('type' in navigator.connection,
|
||||
"type should be a Connection attribute");
|
||||
is(navigator.connection.type, "none",
|
||||
"By default connection.type equals to none");
|
||||
finish();
|
|
@ -13,6 +13,7 @@
|
|||
* https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#navigator-interface-extension
|
||||
* http://www.w3.org/TR/beacon/#sec-beacon-method
|
||||
* https://html.spec.whatwg.org/#navigatorconcurrenthardware
|
||||
* http://wicg.github.io/netinfo/#extensions-to-the-navigator-interface
|
||||
*
|
||||
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
|
||||
* Opera Software ASA. You are granted a license to use, reproduce
|
||||
|
|
|
@ -18,7 +18,8 @@ enum ConnectionType {
|
|||
"unknown"
|
||||
};
|
||||
|
||||
[Pref="dom.netinfo.enabled"]
|
||||
[Func="mozilla::dom::network::Connection::IsEnabled",
|
||||
Exposed=(Window,Worker)]
|
||||
interface NetworkInformation : EventTarget {
|
||||
readonly attribute ConnectionType type;
|
||||
attribute EventHandler ontypechange;
|
||||
|
|
|
@ -12,3 +12,10 @@ WorkerNavigator implements NavigatorLanguage;
|
|||
WorkerNavigator implements NavigatorOnLine;
|
||||
WorkerNavigator implements NavigatorConcurrentHardware;
|
||||
WorkerNavigator implements NavigatorStorage;
|
||||
|
||||
// http://wicg.github.io/netinfo/#extensions-to-the-navigator-interface
|
||||
[Exposed=(Worker)]
|
||||
partial interface WorkerNavigator {
|
||||
[Func="mozilla::dom::network::Connection::IsEnabled", Throws]
|
||||
readonly attribute NetworkInformation connection;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#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 "RuntimeService.h"
|
||||
|
@ -27,10 +28,23 @@ namespace dom {
|
|||
|
||||
using namespace mozilla::dom::workers;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WorkerNavigator, mStorageManager);
|
||||
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)
|
||||
{
|
||||
|
@ -183,5 +197,19 @@ WorkerNavigator::Storage()
|
|||
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
|
||||
|
|
|
@ -19,26 +19,21 @@ namespace dom {
|
|||
class Promise;
|
||||
class StorageManager;
|
||||
|
||||
namespace network {
|
||||
class Connection;
|
||||
} // namespace network
|
||||
|
||||
class WorkerNavigator final : public nsWrapperCache
|
||||
{
|
||||
typedef struct workers::RuntimeService::NavigatorProperties NavigatorProperties;
|
||||
|
||||
NavigatorProperties mProperties;
|
||||
RefPtr<StorageManager> mStorageManager;
|
||||
RefPtr<network::Connection> mConnection;
|
||||
bool mOnline;
|
||||
|
||||
WorkerNavigator(const NavigatorProperties& aProperties,
|
||||
bool aOnline)
|
||||
: mProperties(aProperties)
|
||||
, mOnline(aOnline)
|
||||
{
|
||||
MOZ_COUNT_CTOR(WorkerNavigator);
|
||||
}
|
||||
|
||||
~WorkerNavigator()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WorkerNavigator);
|
||||
}
|
||||
WorkerNavigator(const NavigatorProperties& aProperties, bool aOnline);
|
||||
~WorkerNavigator();
|
||||
|
||||
public:
|
||||
|
||||
|
@ -110,6 +105,8 @@ public:
|
|||
uint64_t HardwareConcurrency() const;
|
||||
|
||||
StorageManager* Storage();
|
||||
|
||||
network::Connection* GetConnection(ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -39,6 +39,7 @@ WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
|
|||
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
|
||||
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK)
|
||||
WORKER_SIMPLE_PREF("dom.netinfo.enabled", NetworkInformationEnabled, NETWORKINFORMATION_ENABLED)
|
||||
WORKER_PREF("dom.workers.latestJSVersion", JSVersionChanged)
|
||||
WORKER_PREF("intl.accept_languages", PrefLanguagesChanged)
|
||||
WORKER_PREF("general.appname.override", AppNameOverrideChanged)
|
||||
|
|
|
@ -16,6 +16,7 @@ var supportedProps = [
|
|||
"languages",
|
||||
"hardwareConcurrency",
|
||||
{ name: "storage", nightly: true },
|
||||
{ name: "connection", nightly: true },
|
||||
];
|
||||
|
||||
self.onmessage = function(event) {
|
||||
|
|
|
@ -150,6 +150,8 @@ var interfaceNamesInGlobalScope =
|
|||
"MessageEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MessagePort",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "NetworkInformation", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Notification",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
Загрузка…
Ссылка в новой задаче