summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/io_thread.cc46
-rw-r--r--chrome/browser/io_thread.h4
-rw-r--r--chrome/browser/net/passive_log_collector.cc38
-rw-r--r--chrome/browser/net/passive_log_collector.h50
-rw-r--r--net/base/net_log_event_type_list.h10
-rw-r--r--net/base/net_log_source_type_list.h18
6 files changed, 141 insertions, 25 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index c451b25..90af284 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -74,6 +74,42 @@ net::HostResolver* CreateGlobalHostResolver() {
return remapped_resolver;
}
+class LoggingNetworkChangeObserver
+ : public net::NetworkChangeNotifier::Observer {
+ public:
+ // |net_log| must remain valid throughout our lifetime.
+ explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
+ : net_log_(net_log) {
+ net::NetworkChangeNotifier::AddObserver(this);
+ }
+
+ ~LoggingNetworkChangeObserver() {
+ net::NetworkChangeNotifier::RemoveObserver(this);
+ }
+
+ virtual void OnIPAddressChanged() {
+ LOG(INFO) << "Observed a change to the network IP addresses";
+
+ net::NetLog::Source global_source;
+
+ // TODO(eroman): We shouldn't need to assign an ID to this source, since
+ // conceptually it is the "global event stream". However
+ // currently the javascript does a grouping on source id, so
+ // the display will look weird if we don't give it one.
+ global_source.id = net_log_->NextID();
+
+ net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSSES_CHANGED,
+ base::TimeTicks::Now(),
+ global_source,
+ net::NetLog::PHASE_NONE,
+ NULL);
+ }
+
+ private:
+ net::NetLog* net_log_;
+ DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
+};
+
} // namespace
// The IOThread object must outlive any tasks posted to the IO thread before the
@@ -132,12 +168,22 @@ void IOThread::Init() {
globals_ = new Globals;
globals_->net_log.reset(new ChromeNetLog());
+
+ // Add an observer that will emit network change events to the ChromeNetLog.
+ // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
+ // logging the network change before other IO thread consumers respond to it.
+ network_change_observer_.reset(
+ new LoggingNetworkChangeObserver(globals_->net_log.get()));
+
globals_->host_resolver = CreateGlobalHostResolver();
globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
globals_->host_resolver));
}
void IOThread::CleanUp() {
+ // This must be reset before the ChromeNetLog is destroyed.
+ network_change_observer_.reset();
+
// If any child processes are still running, terminate them and
// and delete the BrowserChildProcessHost instances to release whatever
// IO thread only resources they are referencing.
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index f0ddca4..2df6b68 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -16,6 +16,7 @@
#include "chrome/common/net/predictor_common.h"
#include "chrome/browser/net/connect_interceptor.h"
#include "net/base/host_resolver.h"
+#include "net/base/network_change_notifier.h"
class ChromeNetLog;
class ListValue;
@@ -100,6 +101,9 @@ class IOThread : public BrowserProcessSubThread {
// though |globals_| is reset by CleanUp().
scoped_ptr<ChromeNetLog> deferred_net_log_to_delete_;
+ // Observer that logs network changes to the ChromeNetLog.
+ scoped_ptr<net::NetworkChangeNotifier::Observer> network_change_observer_;
+
// These member variables are initialized by a task posted to the IO thread,
// which gets posted by calling certain member functions of IOThread.
diff --git a/chrome/browser/net/passive_log_collector.cc b/chrome/browser/net/passive_log_collector.cc
index 165cabf..152d332 100644
--- a/chrome/browser/net/passive_log_collector.cc
+++ b/chrome/browser/net/passive_log_collector.cc
@@ -49,6 +49,7 @@ PassiveLogCollector::PassiveLogCollector()
// Define the mapping between source types and the tracker objects.
memset(&trackers_[0], 0, sizeof(trackers_));
+ trackers_[net::NetLog::SOURCE_NONE] = &global_source_tracker_;
trackers_[net::NetLog::SOURCE_URL_REQUEST] = &url_request_tracker_;
trackers_[net::NetLog::SOURCE_SOCKET_STREAM] = &socket_stream_tracker_;
trackers_[net::NetLog::SOURCE_CONNECT_JOB] = &connect_job_tracker_;
@@ -74,12 +75,12 @@ void PassiveLogCollector::OnAddEntry(
// Package the parameters into a single struct for convenience.
Entry entry(num_events_seen_++, type, time, source, phase, params);
- SourceTracker* tracker = GetTrackerForSourceType(entry.source.type);
+ SourceTrackerInterface* tracker = GetTrackerForSourceType(entry.source.type);
if (tracker)
tracker->OnAddEntry(entry);
}
-PassiveLogCollector::SourceTracker*
+PassiveLogCollector::SourceTrackerInterface*
PassiveLogCollector::GetTrackerForSourceType(
net::NetLog::SourceType source_type) {
DCHECK_LE(source_type, static_cast<int>(arraysize(trackers_)));
@@ -126,6 +127,29 @@ std::string PassiveLogCollector::SourceInfo::GetURL() const {
}
//----------------------------------------------------------------------------
+// GlobalSourceTracker
+//----------------------------------------------------------------------------
+
+PassiveLogCollector::GlobalSourceTracker::GlobalSourceTracker() {}
+PassiveLogCollector::GlobalSourceTracker::~GlobalSourceTracker() {}
+
+void PassiveLogCollector::GlobalSourceTracker::OnAddEntry(const Entry& entry) {
+ const size_t kMaxEntries = 30u;
+ entries_.push_back(entry);
+ if (entries_.size() > kMaxEntries)
+ entries_.pop_front();
+}
+
+void PassiveLogCollector::GlobalSourceTracker::Clear() {
+ entries_.clear();
+}
+
+void PassiveLogCollector::GlobalSourceTracker::AppendAllEntries(
+ EntryList* out) const {
+ out->insert(out->end(), entries_.begin(), entries_.end());
+}
+
+//----------------------------------------------------------------------------
// SourceTracker
//----------------------------------------------------------------------------
@@ -280,8 +304,9 @@ void PassiveLogCollector::SourceTracker::AddReferenceToSourceDependency(
const net::NetLog::Source& source, SourceInfo* info) {
// Find the tracker which should be holding |source|.
DCHECK(parent_);
- SourceTracker* tracker =
- parent_->GetTrackerForSourceType(source.type);
+ DCHECK_NE(source.type, net::NetLog::SOURCE_NONE);
+ SourceTracker* tracker = static_cast<SourceTracker*>(
+ parent_->GetTrackerForSourceType(source.type));
DCHECK(tracker);
// Tell the owning tracker to increment the reference count of |source|.
@@ -301,8 +326,9 @@ PassiveLogCollector::SourceTracker::ReleaseAllReferencesToDependencies(
// Find the tracker which should be holding |source|.
DCHECK(parent_);
- SourceTracker* tracker =
- parent_->GetTrackerForSourceType(source.type);
+ DCHECK_NE(source.type, net::NetLog::SOURCE_NONE);
+ SourceTracker* tracker = static_cast<SourceTracker*>(
+ parent_->GetTrackerForSourceType(source.type));
DCHECK(tracker);
// Tell the owning tracker to decrement the reference count of |source|.
diff --git a/chrome/browser/net/passive_log_collector.h b/chrome/browser/net/passive_log_collector.h
index b927c0c..7615b28 100644
--- a/chrome/browser/net/passive_log_collector.h
+++ b/chrome/browser/net/passive_log_collector.h
@@ -90,9 +90,41 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
typedef std::vector<SourceInfo> SourceInfoList;
+ // Interface for consuming a NetLog entry.
+ class SourceTrackerInterface {
+ public:
+ virtual ~SourceTrackerInterface() {}
+
+ virtual void OnAddEntry(const Entry& entry) = 0;
+
+ // Clears all the passively logged data from this tracker.
+ virtual void Clear() = 0;
+
+ // Appends all the captured entries to |out|. The ordering is undefined.
+ virtual void AppendAllEntries(EntryList* out) const = 0;
+ };
+
+ // This source tracker is intended for TYPE_NONE. All entries go into a
+ // circular buffer, and there is no concept of live/dead requests.
+ class GlobalSourceTracker : public SourceTrackerInterface {
+ public:
+ GlobalSourceTracker();
+ ~GlobalSourceTracker();
+
+ // SourceTrackerInterface implementation:
+ virtual void OnAddEntry(const Entry& entry);
+ virtual void Clear();
+ virtual void AppendAllEntries(EntryList* out) const;
+
+ private:
+ typedef std::deque<Entry> CircularEntryList;
+ CircularEntryList entries_;
+ DISALLOW_COPY_AND_ASSIGN(GlobalSourceTracker);
+ };
+
// This class stores and manages the passively logged information for
// URLRequests/SocketStreams/ConnectJobs.
- class SourceTracker {
+ class SourceTracker : public SourceTrackerInterface {
public:
// Creates a SourceTracker that will track at most |max_num_sources|.
// Up to |max_graveyard_size| unreferenced sources will be kept around
@@ -105,13 +137,10 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
virtual ~SourceTracker();
- void OnAddEntry(const Entry& entry);
-
- // Clears all the passively logged data from this tracker.
- void Clear();
-
- // Appends all the captured entries to |out|. The ordering is undefined.
- void AppendAllEntries(EntryList* out) const;
+ // SourceTrackerInterface implementation:
+ virtual void OnAddEntry(const Entry& entry);
+ virtual void Clear();
+ virtual void AppendAllEntries(EntryList* out) const;
#ifdef UNIT_TEST
// Helper used to inspect the current state by unit-tests.
@@ -264,7 +293,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
net::NetLog::EventParameters* params);
// Returns the tracker to use for sources of type |source_type|, or NULL.
- SourceTracker* GetTrackerForSourceType(
+ SourceTrackerInterface* GetTrackerForSourceType(
net::NetLog::SourceType source_type);
// Clears all of the passively logged data.
@@ -280,6 +309,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
FRIEND_TEST_ALL_PREFIXES(PassiveLogCollectorTest,
HoldReferenceToDeletedSource);
+ GlobalSourceTracker global_source_tracker_;
ConnectJobTracker connect_job_tracker_;
SocketTracker socket_tracker_;
RequestTracker url_request_tracker_;
@@ -290,7 +320,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
// This array maps each NetLog::SourceType to one of the tracker instances
// defined above. Use of this array avoid duplicating the list of trackers
// elsewhere.
- SourceTracker* trackers_[net::NetLog::SOURCE_COUNT];
+ SourceTrackerInterface* trackers_[net::NetLog::SOURCE_COUNT];
// The count of how many events have flowed through this log. Used to set the
// "order" field on captured events.
diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h
index cc26f5f..8c8df02 100644
--- a/net/base/net_log_event_type_list.h
+++ b/net/base/net_log_event_type_list.h
@@ -572,3 +572,13 @@ EVENT_TYPE(AUTH_PROXY)
// The time spent authentication to the server.
EVENT_TYPE(AUTH_SERVER)
+
+// ------------------------------------------------------------------------
+// Global events
+// ------------------------------------------------------------------------
+// These are events which are not grouped by source id, as they have no
+// context.
+
+// This event is emitted whenever NetworkChangeNotifier determines that the
+// underlying network has changed.
+EVENT_TYPE(NETWORK_IP_ADDRESSSES_CHANGED)
diff --git a/net/base/net_log_source_type_list.h b/net/base/net_log_source_type_list.h
index 6664c2d..d416f3f 100644
--- a/net/base/net_log_source_type_list.h
+++ b/net/base/net_log_source_type_list.h
@@ -5,13 +5,13 @@
// NOTE: No header guards are used, since this file is intended to be expanded
// directly within a block where the SOURCE_TYPE macro is defined.
-SOURCE_TYPE(NONE, -1)
+// Used for global events which don't correspond to a particular entity.
+SOURCE_TYPE(NONE, 0)
+SOURCE_TYPE(URL_REQUEST, 1)
+SOURCE_TYPE(SOCKET_STREAM, 2)
+SOURCE_TYPE(INIT_PROXY_RESOLVER, 3)
+SOURCE_TYPE(CONNECT_JOB, 4)
+SOURCE_TYPE(SOCKET, 5)
+SOURCE_TYPE(SPDY_SESSION, 6)
-SOURCE_TYPE(URL_REQUEST, 0)
-SOURCE_TYPE(SOCKET_STREAM, 1)
-SOURCE_TYPE(INIT_PROXY_RESOLVER, 2)
-SOURCE_TYPE(CONNECT_JOB, 3)
-SOURCE_TYPE(SOCKET, 4)
-SOURCE_TYPE(SPDY_SESSION, 5)
-
-SOURCE_TYPE(COUNT, 6) // Always keep this as the last entry.
+SOURCE_TYPE(COUNT, 7) // Always keep this as the last entry.