summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoradamk@chromium.org <adamk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-04 22:42:08 +0000
committeradamk@chromium.org <adamk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-04 22:42:08 +0000
commit232a58169700ed7abde79d9858c288eb21409e60 (patch)
treea1424f86d252cd3859c060954882a9a1809a5121 /net
parentcdc5489ddff18b5ff13296abc1c8869e3cd7db28 (diff)
downloadchromium_src-232a58169700ed7abde79d9858c288eb21409e60.zip
chromium_src-232a58169700ed7abde79d9858c288eb21409e60.tar.gz
chromium_src-232a58169700ed7abde79d9858c288eb21409e60.tar.bz2
Plumb through NetworkChangeNotifier::IsOffline() to WebKit, enabling
navigator.onLine and online/offline events. Only works on Windows at the moment, as IsCurrentlyOffline() is supported only by NetworkChangeNotifierWin. Most of the changes are due to the need to support two different kinds of NetworkChangeNotifier observers. Both observers currently happen to trigger on the same event, but that could change, e.g., if we store the previous online state and only notify on a change. Thus the need for two different observer interfaces, and associated Add/Remove methods. BUG=7469 TEST=Load https://bug336359.bugzilla.mozilla.org/attachment.cgi?id=220609, unplug network cable, reload, see that page changes to note offline status Review URL: http://codereview.chromium.org/6526059 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76985 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/dnsrr_resolver.h4
-rw-r--r--net/base/host_resolver_impl.cc4
-rw-r--r--net/base/host_resolver_impl.h4
-rw-r--r--net/base/network_change_notifier.cc47
-rw-r--r--net/base/network_change_notifier.h36
-rw-r--r--net/base/network_change_notifier_win.cc14
-rw-r--r--net/base/network_change_notifier_win.h6
-rw-r--r--net/proxy/proxy_service.cc4
-rw-r--r--net/proxy/proxy_service.h4
-rw-r--r--net/socket/client_socket_pool_base.cc4
-rw-r--r--net/socket/client_socket_pool_base.h4
-rw-r--r--net/spdy/spdy_session_pool.cc4
-rw-r--r--net/spdy/spdy_session_pool.h4
13 files changed, 104 insertions, 35 deletions
diff --git a/net/base/dnsrr_resolver.h b/net/base/dnsrr_resolver.h
index 3280774..a9ff84b 100644
--- a/net/base/dnsrr_resolver.h
+++ b/net/base/dnsrr_resolver.h
@@ -67,7 +67,7 @@ class RRResolverJob;
//
// A DnsRRResolver must be used from the MessageLoop which created it.
class DnsRRResolver : public base::NonThreadSafe,
- public NetworkChangeNotifier::Observer {
+ public NetworkChangeNotifier::IPAddressObserver {
public:
typedef intptr_t Handle;
@@ -105,7 +105,7 @@ class DnsRRResolver : public base::NonThreadSafe,
// must not have already been called.
void CancelResolve(Handle handle);
- // Implementation of NetworkChangeNotifier::Observer
+ // Implementation of NetworkChangeNotifier::IPAddressObserver
virtual void OnIPAddressChanged();
private:
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index b22eee8..894443c 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -925,7 +925,7 @@ HostResolverImpl::HostResolverImpl(
if (HaveOnlyLoopbackAddresses())
additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
#endif
- NetworkChangeNotifier::AddObserver(this);
+ NetworkChangeNotifier::AddIPAddressObserver(this);
}
HostResolverImpl::~HostResolverImpl() {
@@ -939,7 +939,7 @@ HostResolverImpl::~HostResolverImpl() {
if (cur_completing_job_)
cur_completing_job_->Cancel();
- NetworkChangeNotifier::RemoveObserver(this);
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
// Delete the job pools.
for (size_t i = 0u; i < arraysize(job_pools_); ++i)
diff --git a/net/base/host_resolver_impl.h b/net/base/host_resolver_impl.h
index a571bb7..89d4f46 100644
--- a/net/base/host_resolver_impl.h
+++ b/net/base/host_resolver_impl.h
@@ -51,7 +51,7 @@ namespace net {
class HostResolverImpl : public HostResolver,
public base::NonThreadSafe,
- public NetworkChangeNotifier::Observer {
+ public NetworkChangeNotifier::IPAddressObserver {
public:
// The index into |job_pools_| for the various job pools. Pools with a higher
// index have lower priority.
@@ -223,7 +223,7 @@ class HostResolverImpl : public HostResolver,
// Aborts all in progress jobs (but might start new ones).
void AbortAllInProgressJobs();
- // NetworkChangeNotifier::Observer methods:
+ // NetworkChangeNotifier::IPAddressObserver methods:
virtual void OnIPAddressChanged();
// Cache of host resolution results.
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index 8c61ac6..596ce8e 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -58,29 +58,56 @@ NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() {
return new MockNetworkChangeNotifier();
}
-void NetworkChangeNotifier::AddObserver(Observer* observer) {
+void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) {
if (g_network_change_notifier)
- g_network_change_notifier->observer_list_->AddObserver(observer);
+ g_network_change_notifier->ip_address_observer_list_->AddObserver(observer);
}
-void NetworkChangeNotifier::RemoveObserver(Observer* observer) {
- if (g_network_change_notifier)
- g_network_change_notifier->observer_list_->RemoveObserver(observer);
+void NetworkChangeNotifier::AddOnlineStateObserver(
+ OnlineStateObserver* observer) {
+ if (g_network_change_notifier) {
+ g_network_change_notifier->online_state_observer_list_->AddObserver(
+ observer);
+ }
+}
+
+void NetworkChangeNotifier::RemoveIPAddressObserver(
+ IPAddressObserver* observer) {
+ if (g_network_change_notifier) {
+ g_network_change_notifier->ip_address_observer_list_->RemoveObserver(
+ observer);
+ }
+}
+
+void NetworkChangeNotifier::RemoveOnlineStateObserver(
+ OnlineStateObserver* observer) {
+ if (g_network_change_notifier) {
+ g_network_change_notifier->online_state_observer_list_->RemoveObserver(
+ observer);
+ }
}
NetworkChangeNotifier::NetworkChangeNotifier()
- : observer_list_(
- new ObserverListThreadSafe<Observer>(
- ObserverListBase<Observer>::NOTIFY_EXISTING_ONLY)) {
+ : ip_address_observer_list_(
+ new ObserverListThreadSafe<IPAddressObserver>(
+ ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)),
+ online_state_observer_list_(
+ new ObserverListThreadSafe<OnlineStateObserver>(
+ ObserverListBase<OnlineStateObserver>::NOTIFY_EXISTING_ONLY)) {
DCHECK(!g_network_change_notifier);
g_network_change_notifier = this;
}
void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() {
if (g_network_change_notifier) {
- g_network_change_notifier->observer_list_->Notify(
- &Observer::OnIPAddressChanged);
+ g_network_change_notifier->ip_address_observer_list_->Notify(
+ &IPAddressObserver::OnIPAddressChanged);
}
}
+void NetworkChangeNotifier::NotifyObserversOfOnlineStateChange() {
+ online_state_observer_list_->Notify(
+ &OnlineStateObserver::OnOnlineStateChanged, !IsOffline());
+}
+
} // namespace net
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h
index 770b321..4550eed 100644
--- a/net/base/network_change_notifier.h
+++ b/net/base/network_change_notifier.h
@@ -16,19 +16,35 @@ namespace net {
// and will be called back on the thread from which they registered.
class NetworkChangeNotifier {
public:
- class Observer {
+ class IPAddressObserver {
public:
- virtual ~Observer() {}
+ virtual ~IPAddressObserver() {}
// Will be called when the IP address of the primary interface changes.
// This includes when the primary interface itself changes.
virtual void OnIPAddressChanged() = 0;
protected:
- Observer() {}
+ IPAddressObserver() {}
private:
- DISALLOW_COPY_AND_ASSIGN(Observer);
+ DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
+ };
+
+ class OnlineStateObserver {
+ public:
+ virtual ~OnlineStateObserver() {}
+
+ // Will be called when the online state of the system may have changed.
+ // See NetworkChangeNotifier::IsOffline() for important caveats about
+ // the unreliability of this signal.
+ virtual void OnOnlineStateChanged(bool online) = 0;
+
+ protected:
+ OnlineStateObserver() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OnlineStateObserver);
};
virtual ~NetworkChangeNotifier();
@@ -64,7 +80,8 @@ class NetworkChangeNotifier {
// called back with notifications. This is safe to call if Create() has not
// been called (as long as it doesn't race the Create() call on another
// thread), in which case it will simply do nothing.
- static void AddObserver(Observer* observer);
+ static void AddIPAddressObserver(IPAddressObserver* observer);
+ static void AddOnlineStateObserver(OnlineStateObserver* observer);
// Unregisters |observer| from receiving notifications. This must be called
// on the same thread on which AddObserver() was called. Like AddObserver(),
@@ -73,7 +90,8 @@ class NetworkChangeNotifier {
// nothing. Technically, it's also safe to call after the notifier object has
// been destroyed, if the call doesn't race the notifier's destruction, but
// there's no reason to use the API in this risky way, so don't do it.
- static void RemoveObserver(Observer* observer);
+ static void RemoveIPAddressObserver(IPAddressObserver* observer);
+ static void RemoveOnlineStateObserver(OnlineStateObserver* observer);
#ifdef UNIT_TEST
// Allow unit tests to trigger notifications.
@@ -89,9 +107,13 @@ class NetworkChangeNotifier {
// happens asynchronously, even for observers on the current thread, even in
// tests.
static void NotifyObserversOfIPAddressChange();
+ void NotifyObserversOfOnlineStateChange();
private:
- const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_;
+ const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
+ ip_address_observer_list_;
+ const scoped_refptr<ObserverListThreadSafe<OnlineStateObserver> >
+ online_state_observer_list_;
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
};
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc
index bc906cb..718e40b 100644
--- a/net/base/network_change_notifier_win.cc
+++ b/net/base/network_change_notifier_win.cc
@@ -8,6 +8,7 @@
#include <winsock2.h>
#include "base/logging.h"
+#include "base/time.h"
#include "net/base/winsock_init.h"
#pragma comment(lib, "iphlpapi.lib")
@@ -146,6 +147,15 @@ bool NetworkChangeNotifierWin::IsCurrentlyOffline() const {
void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) {
NotifyObserversOfIPAddressChange();
+ // Calling IsOffline() at this very moment is likely to give
+ // the wrong result, so we delay that until a little bit later.
+ //
+ // The one second delay chosen here was determined experimentally
+ // by adamk on Windows 7.
+ timer_.Stop(); // cancel any already waiting notification
+ timer_.Start(base::TimeDelta::FromSeconds(1), this,
+ &NetworkChangeNotifierWin::NotifyParentOfOnlineStateChange);
+
// Start watching for the next address change.
WatchForAddressChange();
}
@@ -157,4 +167,8 @@ void NetworkChangeNotifierWin::WatchForAddressChange() {
addr_watcher_.StartWatching(addr_overlapped_.hEvent, this);
}
+void NetworkChangeNotifierWin::NotifyParentOfOnlineStateChange() {
+ NotifyObserversOfOnlineStateChange();
+}
+
} // namespace net
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h
index c76f7fd..9c2457e 100644
--- a/net/base/network_change_notifier_win.h
+++ b/net/base/network_change_notifier_win.h
@@ -9,6 +9,7 @@
#include <windows.h>
#include "base/basictypes.h"
+#include "base/timer.h"
#include "base/win/object_watcher.h"
#include "net/base/network_change_notifier.h"
@@ -31,9 +32,14 @@ class NetworkChangeNotifierWin : public NetworkChangeNotifier,
// Begins listening for a single subsequent address change.
void WatchForAddressChange();
+ // Forwards online state notifications to parent class.
+ void NotifyParentOfOnlineStateChange();
+
base::win::ObjectWatcher addr_watcher_;
OVERLAPPED addr_overlapped_;
+ base::OneShotTimer<NetworkChangeNotifierWin> timer_;
+
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierWin);
};
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 13d049e..47673c5 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -384,7 +384,7 @@ ProxyService::ProxyService(ProxyConfigService* config_service,
stall_proxy_auto_config_delay_(
base::TimeDelta::FromMilliseconds(
kNumMillisToStallAfterNetworkChanges)) {
- NetworkChangeNotifier::AddObserver(this);
+ NetworkChangeNotifier::AddIPAddressObserver(this);
ResetConfigService(config_service);
}
@@ -560,7 +560,7 @@ int ProxyService::TryToCompleteSynchronously(const GURL& url,
}
ProxyService::~ProxyService() {
- NetworkChangeNotifier::RemoveObserver(this);
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
config_service_->RemoveObserver(this);
// Cancel any inprogress requests.
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 75ac3c9..72b76ef 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -34,7 +34,7 @@ class URLRequestContext;
// HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy
// resolution. See ProxyResolverV8 for example.
class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
- public NetworkChangeNotifier::Observer,
+ public NetworkChangeNotifier::IPAddressObserver,
public ProxyConfigService::Observer {
public:
// The instance takes ownership of |config_service| and |resolver|.
@@ -280,7 +280,7 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
// Start initialization using |fetched_config_|.
void InitializeUsingLastFetchedConfig();
- // NetworkChangeNotifier::Observer
+ // NetworkChangeNotifier::IPAddressObserver
// When this is called, we re-fetch PAC scripts and re-run WPAD.
virtual void OnIPAddressChanged();
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index 64fb831..8aaf1b5 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -163,7 +163,7 @@ ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper(
DCHECK_LE(0, max_sockets_per_group);
DCHECK_LE(max_sockets_per_group, max_sockets);
- NetworkChangeNotifier::AddObserver(this);
+ NetworkChangeNotifier::AddIPAddressObserver(this);
}
ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() {
@@ -175,7 +175,7 @@ ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() {
DCHECK(pending_callback_map_.empty());
DCHECK_EQ(0, connecting_socket_count_);
- NetworkChangeNotifier::RemoveObserver(this);
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
}
// InsertRequestIntoQueue inserts the request into the queue based on
diff --git a/net/socket/client_socket_pool_base.h b/net/socket/client_socket_pool_base.h
index 1798997c..89273cc 100644
--- a/net/socket/client_socket_pool_base.h
+++ b/net/socket/client_socket_pool_base.h
@@ -156,7 +156,7 @@ namespace internal {
// ClientSocketPoolBase instead.
class ClientSocketPoolBaseHelper
: public ConnectJob::Delegate,
- public NetworkChangeNotifier::Observer {
+ public NetworkChangeNotifier::IPAddressObserver {
public:
typedef uint32 Flags;
@@ -289,7 +289,7 @@ class ClientSocketPoolBaseHelper
// ConnectJob::Delegate methods:
virtual void OnConnectJobComplete(int result, ConnectJob* job);
- // NetworkChangeNotifier::Observer methods:
+ // NetworkChangeNotifier::IPAddressObserver methods:
virtual void OnIPAddressChanged();
private:
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index b32495e..e2cae2b 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -19,7 +19,7 @@ bool SpdySessionPool::g_force_single_domain = false;
SpdySessionPool::SpdySessionPool(SSLConfigService* ssl_config_service)
: ssl_config_service_(ssl_config_service) {
- NetworkChangeNotifier::AddObserver(this);
+ NetworkChangeNotifier::AddIPAddressObserver(this);
if (ssl_config_service_)
ssl_config_service_->AddObserver(this);
}
@@ -29,7 +29,7 @@ SpdySessionPool::~SpdySessionPool() {
if (ssl_config_service_)
ssl_config_service_->RemoveObserver(this);
- NetworkChangeNotifier::RemoveObserver(this);
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
}
scoped_refptr<SpdySession> SpdySessionPool::Get(
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h
index 91ff8cb..16125e0 100644
--- a/net/spdy/spdy_session_pool.h
+++ b/net/spdy/spdy_session_pool.h
@@ -32,7 +32,7 @@ class SpdySession;
// This is a very simple pool for open SpdySessions.
// TODO(mbelshe): Make this production ready.
class SpdySessionPool
- : public NetworkChangeNotifier::Observer,
+ : public NetworkChangeNotifier::IPAddressObserver,
public SSLConfigService::Observer {
public:
explicit SpdySessionPool(SSLConfigService* ssl_config_service);
@@ -90,7 +90,7 @@ class SpdySessionPool
SpdySettingsStorage* mutable_spdy_settings() { return &spdy_settings_; }
const SpdySettingsStorage& spdy_settings() const { return spdy_settings_; }
- // NetworkChangeNotifier::Observer methods:
+ // NetworkChangeNotifier::IPAddressObserver methods:
// We flush all idle sessions and release references to the active ones so
// they won't get re-used. The active ones will either complete successfully