[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 1 | // 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] | 9840b18e | 2012-11-20 01:52:10 | [diff] [blame] | 24 | #if (defined(OS_LINUX) || defined(OS_OPENBSD)) && !defined(OS_CHROMEOS) |
[email protected] | a6f8cb73 | 2012-11-19 19:22:15 | [diff] [blame] | 25 | #include <glib-object.h> |
| 26 | #endif |
| 27 | |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 28 | #if defined(OS_MACOSX) |
| 29 | #include "base/mac/scoped_nsautorelease_pool.h" |
| 30 | #endif |
| 31 | |
| 32 | namespace { |
| 33 | |
| 34 | // Conversions from various network-related types to string. |
| 35 | |
| 36 | const 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] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 58 | std::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 | |
| 65 | const 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. |
| 80 | class NetWatcher : |
| 81 | public net::NetworkChangeNotifier::IPAddressObserver, |
| 82 | public net::NetworkChangeNotifier::ConnectionTypeObserver, |
| 83 | public net::NetworkChangeNotifier::DNSObserver, |
[email protected] | 0384887 | 2012-12-08 02:46:41 | [diff] [blame] | 84 | public net::NetworkChangeNotifier::NetworkChangeObserver, |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 85 | 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] | bb0e3454 | 2012-08-31 19:52:40 | [diff] [blame] | 104 | virtual void OnDNSChanged() OVERRIDE { |
| 105 | LOG(INFO) << "OnDNSChanged()"; |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 106 | } |
| 107 | |
[email protected] | 0384887 | 2012-12-08 02:46:41 | [diff] [blame] | 108 | // 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] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 115 | // 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 | |
| 130 | int main(int argc, char* argv[]) { |
| 131 | #if defined(OS_MACOSX) |
| 132 | base::mac::ScopedNSAutoreleasePool pool; |
| 133 | #endif |
[email protected] | 9840b18e | 2012-11-20 01:52:10 | [diff] [blame] | 134 | #if (defined(OS_LINUX) || defined(OS_OPENBSD)) && !defined(OS_CHROMEOS) |
[email protected] | a6f8cb73 | 2012-11-19 19:22:15 | [diff] [blame] | 135 | // Needed so ProxyConfigServiceLinux can use gconf. |
| 136 | // Normally handled by BrowserMainLoop::InitializeToolkit(). |
| 137 | g_type_init(); |
| 138 | #endif |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 139 | 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] | 2da659e | 2013-05-23 20:51:34 | [diff] [blame^] | 149 | base::MessageLoopForIO network_loop; |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 150 | |
| 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] | a22af40 | 2012-06-22 23:58:47 | [diff] [blame] | 162 | // Uses |network_change_notifier|. |
| 163 | net::NetworkChangeNotifier::AddIPAddressObserver(&net_watcher); |
| 164 | net::NetworkChangeNotifier::AddConnectionTypeObserver(&net_watcher); |
| 165 | net::NetworkChangeNotifier::AddDNSObserver(&net_watcher); |
[email protected] | 0384887 | 2012-12-08 02:46:41 | [diff] [blame] | 166 | net::NetworkChangeNotifier::AddNetworkChangeObserver(&net_watcher); |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 167 | |
| 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] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 185 | // Start watching for events. |
| 186 | network_loop.Run(); |
| 187 | |
| 188 | proxy_config_service->RemoveObserver(&net_watcher); |
| 189 | |
[email protected] | a22af40 | 2012-06-22 23:58:47 | [diff] [blame] | 190 | // Uses |network_change_notifier|. |
| 191 | net::NetworkChangeNotifier::RemoveDNSObserver(&net_watcher); |
| 192 | net::NetworkChangeNotifier::RemoveConnectionTypeObserver(&net_watcher); |
| 193 | net::NetworkChangeNotifier::RemoveIPAddressObserver(&net_watcher); |
[email protected] | 0384887 | 2012-12-08 02:46:41 | [diff] [blame] | 194 | net::NetworkChangeNotifier::RemoveNetworkChangeObserver(&net_watcher); |
[email protected] | a6b32f6e | 2012-06-20 23:46:26 | [diff] [blame] | 195 | |
| 196 | return 0; |
| 197 | } |