blob: 426fea1781aadc4310ed350823e4df4ca7b2a8b0 [file] [log] [blame]
[email protected]a6b32f6e2012-06-20 23:46:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This is a small utility that watches for and logs network changes.
6
7#include <string>
8
9#include "base/at_exit.h"
10#include "base/basictypes.h"
11#include "base/command_line.h"
12#include "base/compiler_specific.h"
13#include "base/json/json_writer.h"
14#include "base/logging.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/message_loop.h"
17#include "base/values.h"
18#include "build/build_config.h"
19#include "net/base/network_change_notifier.h"
20#include "net/proxy/proxy_config.h"
21#include "net/proxy/proxy_config_service.h"
22#include "net/proxy/proxy_service.h"
23
[email protected]9840b18e2012-11-20 01:52:1024#if (defined(OS_LINUX) || defined(OS_OPENBSD)) && !defined(OS_CHROMEOS)
[email protected]a6f8cb732012-11-19 19:22:1525#include <glib-object.h>
26#endif
27
[email protected]a6b32f6e2012-06-20 23:46:2628#if defined(OS_MACOSX)
29#include "base/mac/scoped_nsautorelease_pool.h"
30#endif
31
32namespace {
33
34// Conversions from various network-related types to string.
35
36const char* ConnectionTypeToString(
37 net::NetworkChangeNotifier::ConnectionType type) {
38 switch (type) {
39 case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
40 return "CONNECTION_UNKNOWN";
41 case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
42 return "CONNECTION_ETHERNET";
43 case net::NetworkChangeNotifier::CONNECTION_WIFI:
44 return "CONNECTION_WIFI";
45 case net::NetworkChangeNotifier::CONNECTION_2G:
46 return "CONNECTION_2G";
47 case net::NetworkChangeNotifier::CONNECTION_3G:
48 return "CONNECTION_3G";
49 case net::NetworkChangeNotifier::CONNECTION_4G:
50 return "CONNECTION_4G";
51 case net::NetworkChangeNotifier::CONNECTION_NONE:
52 return "CONNECTION_NONE";
53 default:
54 return "CONNECTION_UNEXPECTED";
55 }
56}
57
[email protected]a6b32f6e2012-06-20 23:46:2658std::string ProxyConfigToString(const net::ProxyConfig& config) {
59 scoped_ptr<base::Value> config_value(config.ToValue());
60 std::string str;
61 base::JSONWriter::Write(config_value.get(), &str);
62 return str;
63}
64
65const char* ConfigAvailabilityToString(
66 net::ProxyConfigService::ConfigAvailability availability) {
67 switch (availability) {
68 case net::ProxyConfigService::CONFIG_PENDING:
69 return "CONFIG_PENDING";
70 case net::ProxyConfigService::CONFIG_VALID:
71 return "CONFIG_VALID";
72 case net::ProxyConfigService::CONFIG_UNSET:
73 return "CONFIG_UNSET";
74 default:
75 return "CONFIG_UNEXPECTED";
76 }
77}
78
79// The main observer class that logs network events.
80class NetWatcher :
81 public net::NetworkChangeNotifier::IPAddressObserver,
82 public net::NetworkChangeNotifier::ConnectionTypeObserver,
83 public net::NetworkChangeNotifier::DNSObserver,
[email protected]03848872012-12-08 02:46:4184 public net::NetworkChangeNotifier::NetworkChangeObserver,
[email protected]a6b32f6e2012-06-20 23:46:2685 public net::ProxyConfigService::Observer {
86 public:
87 NetWatcher() {}
88
89 virtual ~NetWatcher() {}
90
91 // net::NetworkChangeNotifier::IPAddressObserver implementation.
92 virtual void OnIPAddressChanged() OVERRIDE {
93 LOG(INFO) << "OnIPAddressChanged()";
94 }
95
96 // net::NetworkChangeNotifier::ConnectionTypeObserver implementation.
97 virtual void OnConnectionTypeChanged(
98 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE {
99 LOG(INFO) << "OnConnectionTypeChanged("
100 << ConnectionTypeToString(type) << ")";
101 }
102
103 // net::NetworkChangeNotifier::DNSObserver implementation.
[email protected]bb0e34542012-08-31 19:52:40104 virtual void OnDNSChanged() OVERRIDE {
105 LOG(INFO) << "OnDNSChanged()";
[email protected]a6b32f6e2012-06-20 23:46:26106 }
107
[email protected]03848872012-12-08 02:46:41108 // net::NetworkChangeNotifier::NetworkChangeObserver implementation.
109 virtual void OnNetworkChanged(
110 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE {
111 LOG(INFO) << "OnNetworkChanged("
112 << ConnectionTypeToString(type) << ")";
113 }
114
[email protected]a6b32f6e2012-06-20 23:46:26115 // net::ProxyConfigService::Observer implementation.
116 virtual void OnProxyConfigChanged(
117 const net::ProxyConfig& config,
118 net::ProxyConfigService::ConfigAvailability availability) OVERRIDE {
119 LOG(INFO) << "OnProxyConfigChanged("
120 << ProxyConfigToString(config) << ", "
121 << ConfigAvailabilityToString(availability) << ")";
122 }
123
124 private:
125 DISALLOW_COPY_AND_ASSIGN(NetWatcher);
126};
127
128} // namespace
129
130int main(int argc, char* argv[]) {
131#if defined(OS_MACOSX)
132 base::mac::ScopedNSAutoreleasePool pool;
133#endif
[email protected]9840b18e2012-11-20 01:52:10134#if (defined(OS_LINUX) || defined(OS_OPENBSD)) && !defined(OS_CHROMEOS)
[email protected]a6f8cb732012-11-19 19:22:15135 // Needed so ProxyConfigServiceLinux can use gconf.
136 // Normally handled by BrowserMainLoop::InitializeToolkit().
137 g_type_init();
138#endif
[email protected]a6b32f6e2012-06-20 23:46:26139 base::AtExitManager exit_manager;
140 CommandLine::Init(argc, argv);
141 logging::InitLogging(
142 NULL,
143 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
144 logging::LOCK_LOG_FILE,
145 logging::DELETE_OLD_LOG_FILE,
146 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
147
148 // Just make the main message loop the network loop.
[email protected]2da659e2013-05-23 20:51:34149 base::MessageLoopForIO network_loop;
[email protected]a6b32f6e2012-06-20 23:46:26150
151 NetWatcher net_watcher;
152
153 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier(
154 net::NetworkChangeNotifier::Create());
155
156 // Use the network loop as the file loop also.
157 scoped_ptr<net::ProxyConfigService> proxy_config_service(
158 net::ProxyService::CreateSystemProxyConfigService(
159 network_loop.message_loop_proxy(),
160 &network_loop));
161
[email protected]a22af402012-06-22 23:58:47162 // Uses |network_change_notifier|.
163 net::NetworkChangeNotifier::AddIPAddressObserver(&net_watcher);
164 net::NetworkChangeNotifier::AddConnectionTypeObserver(&net_watcher);
165 net::NetworkChangeNotifier::AddDNSObserver(&net_watcher);
[email protected]03848872012-12-08 02:46:41166 net::NetworkChangeNotifier::AddNetworkChangeObserver(&net_watcher);
[email protected]a6b32f6e2012-06-20 23:46:26167
168 proxy_config_service->AddObserver(&net_watcher);
169
170 LOG(INFO) << "Initial connection type: "
171 << ConnectionTypeToString(
172 network_change_notifier->GetCurrentConnectionType());
173
174 {
175 net::ProxyConfig config;
176 const net::ProxyConfigService::ConfigAvailability availability =
177 proxy_config_service->GetLatestProxyConfig(&config);
178 LOG(INFO) << "Initial proxy config: "
179 << ProxyConfigToString(config) << ", "
180 << ConfigAvailabilityToString(availability);
181 }
182
183 LOG(INFO) << "Watching for network events...";
184
[email protected]a6b32f6e2012-06-20 23:46:26185 // Start watching for events.
186 network_loop.Run();
187
188 proxy_config_service->RemoveObserver(&net_watcher);
189
[email protected]a22af402012-06-22 23:58:47190 // Uses |network_change_notifier|.
191 net::NetworkChangeNotifier::RemoveDNSObserver(&net_watcher);
192 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(&net_watcher);
193 net::NetworkChangeNotifier::RemoveIPAddressObserver(&net_watcher);
[email protected]03848872012-12-08 02:46:41194 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(&net_watcher);
[email protected]a6b32f6e2012-06-20 23:46:26195
196 return 0;
197}