Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
|
satorux1
2011/10/13 21:41:19
BTW, this code works only if NetworkManager is run
adamk
2011/10/24 22:37:00
I'm not familiar with usual D-Bus practices...how
satorux1
2011/10/26 17:37:09
I guess that ConnectToSignal fails fast to connect
adamk
2011/10/26 18:35:52
To be honest, I haven't yet had a chance to test t
| |
| 4 | 4 |
| 5 #include "net/base/network_change_notifier_linux.h" | 5 #include "net/base/network_change_notifier_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback.h" | |
| 11 #include "base/callback_old.h" | 12 #include "base/callback_old.h" |
| 12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 13 #include "base/eintr_wrapper.h" | 14 #include "base/eintr_wrapper.h" |
| 14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 15 #include "base/files/file_path_watcher.h" | 16 #include "base/files/file_path_watcher.h" |
| 17 #include "base/memory/weak_ptr.h" | |
| 18 #include "base/synchronization/lock.h" | |
| 19 #include "base/synchronization/waitable_event.h" | |
| 16 #include "base/task.h" | 20 #include "base/task.h" |
| 21 #include "base/threading/platform_thread.h" | |
| 17 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
| 23 #include "dbus/bus.h" | |
| 24 #include "dbus/message.h" | |
| 25 #include "dbus/object_proxy.h" | |
| 18 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
| 19 #include "net/base/network_change_notifier_netlink_linux.h" | 27 #include "net/base/network_change_notifier_netlink_linux.h" |
| 20 | 28 |
| 21 using ::base::files::FilePathWatcher; | 29 using ::base::files::FilePathWatcher; |
| 22 | 30 |
| 23 namespace net { | 31 namespace net { |
| 24 | 32 |
| 25 namespace { | 33 namespace { |
| 26 | 34 |
| 27 const int kInvalidSocket = -1; | 35 const int kInvalidSocket = -1; |
| 28 | 36 |
| 37 const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager"; | |
| 38 const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager"; | |
| 39 const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager"; | |
| 40 | |
| 41 // http://projects.gnome.org/NetworkManager/developers/spec-08.html#type-NM_STAT E | |
| 42 enum { | |
| 43 NM_LEGACY_STATE_UNKNOWN = 0, | |
| 44 NM_LEGACY_STATE_ASLEEP = 1, | |
| 45 NM_LEGACY_STATE_CONNECTING = 2, | |
| 46 NM_LEGACY_STATE_CONNECTED = 3, | |
| 47 NM_LEGACY_STATE_DISCONNECTED = 4 | |
| 48 }; | |
| 49 | |
| 50 // http://projects.gnome.org/NetworkManager/developers/migrating-to-09/spec.html #type-NM_STATE | |
| 51 enum { | |
| 52 NM_STATE_UNKNOWN = 0, | |
| 53 NM_STATE_ASLEEP = 10, | |
| 54 NM_STATE_DISCONNECTED = 20, | |
| 55 NM_STATE_DISCONNECTING = 30, | |
| 56 NM_STATE_CONNECTING = 40, | |
| 57 NM_STATE_CONNECTED_LOCAL = 50, | |
| 58 NM_STATE_CONNECTED_SITE = 60, | |
| 59 NM_STATE_CONNECTED_GLOBAL = 70 | |
| 60 }; | |
| 61 | |
| 62 // A wrapper around NetworkManager's D-Bus API. | |
| 63 class NetworkManagerApi { | |
| 64 public: | |
| 65 typedef base::Callback<void(void)> NotificationCallback; | |
| 66 | |
| 67 explicit NetworkManagerApi(NotificationCallback notification_callback) | |
| 68 : online_state_(UNINITIALIZED), | |
| 69 online_state_initialized_(false, false), | |
| 70 notification_callback_(notification_callback), | |
| 71 helper_thread_id_(base::kInvalidThreadId), | |
| 72 ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { } | |
|
satorux1
2011/10/13 21:41:19
nit: {} is probably more common than { }.
| |
| 73 | |
| 74 ~NetworkManagerApi() { } | |
| 75 | |
| 76 // Should be called on a helper thread which must be of type IO. | |
| 77 void Init(); | |
| 78 | |
| 79 // Must be called by the helper thread's CleanUp() method. | |
| 80 void CleanUp(); | |
| 81 | |
| 82 // Implementation of NetworkChangeNotifierLinux::IsCurrentlyOffline(). | |
| 83 // Safe to call from any thread, but will block until Init() has completed. | |
| 84 bool IsCurrentlyOffline(); | |
| 85 | |
| 86 private: | |
| 87 enum OnlineState { | |
| 88 UNINITIALIZED = -1, | |
| 89 OFFLINE = 0, | |
| 90 ONLINE = 1 | |
| 91 }; | |
| 92 | |
| 93 // Callbacks for D-Bus API. | |
| 94 void OnStateChanged(dbus::Signal* signal); | |
| 95 void OnConnected(const std::string&, const std::string&, bool success) { | |
| 96 LOG_IF(WARNING, !success) << "Failed to set up offline state detection"; | |
| 97 } | |
| 98 | |
| 99 // Synchronously gets the current state from the NetworkManager. | |
| 100 // Should be called on a helper thread. | |
| 101 uint32 GetCurrentState(dbus::ObjectProxy* proxy); | |
| 102 | |
| 103 // Converts a NetworkManager state uint to our enum. | |
| 104 // Always returns either ONLINE or OFFLINE. | |
| 105 static OnlineState TranslateState(uint32 state); | |
| 106 | |
| 107 OnlineState online_state_; | |
| 108 base::Lock online_state_lock_; | |
| 109 base::WaitableEvent online_state_initialized_; | |
| 110 | |
| 111 NotificationCallback notification_callback_; | |
| 112 | |
| 113 scoped_refptr<dbus::Bus> system_bus_; | |
| 114 | |
| 115 base::PlatformThreadId helper_thread_id_; | |
| 116 | |
| 117 base::WeakPtrFactory<NetworkManagerApi> ptr_factory_; | |
| 118 | |
| 119 DISALLOW_COPY_AND_ASSIGN(NetworkManagerApi); | |
| 120 }; | |
| 121 | |
| 122 void NetworkManagerApi::Init() { | |
| 123 // D-Bus requires an IO MessageLoop. | |
| 124 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_IO); | |
| 125 helper_thread_id_ = base::PlatformThread::CurrentId(); | |
| 126 | |
| 127 dbus::Bus::Options options; | |
| 128 options.bus_type = dbus::Bus::SYSTEM; | |
| 129 options.connection_type = dbus::Bus::PRIVATE; | |
| 130 system_bus_ = new dbus::Bus(options); | |
| 131 | |
| 132 dbus::ObjectProxy* proxy = | |
| 133 system_bus_->GetObjectProxy(kNetworkManagerServiceName, | |
| 134 kNetworkManagerPath); | |
| 135 OnlineState initial_state = TranslateState(GetCurrentState(proxy)); | |
| 136 { | |
| 137 base::AutoLock lock(online_state_lock_); | |
| 138 online_state_ = initial_state; | |
| 139 } | |
| 140 online_state_initialized_.Signal(); | |
| 141 | |
| 142 proxy->ConnectToSignal( | |
| 143 kNetworkManagerInterface, | |
| 144 "StateChanged", | |
| 145 base::Bind(&NetworkManagerApi::OnStateChanged, ptr_factory_.GetWeakPtr()), | |
| 146 base::Bind(&NetworkManagerApi::OnConnected, ptr_factory_.GetWeakPtr())); | |
| 147 } | |
| 148 | |
| 149 void NetworkManagerApi::CleanUp() { | |
| 150 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId()); | |
| 151 ptr_factory_.InvalidateWeakPtrs(); | |
| 152 } | |
| 153 | |
| 154 void NetworkManagerApi::OnStateChanged(dbus::Signal* signal) { | |
| 155 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId()); | |
| 156 DCHECK(signal); | |
| 157 dbus::MessageReader reader(signal); | |
| 158 uint32 state; | |
|
satorux1
2011/10/13 21:41:19
nit: I'd initialize this with 0 to avoid a possibl
adamk
2011/10/24 22:37:00
Done. I hope there's no chance of nondeterminism
satorux1
2011/10/26 17:37:09
Right. PopUint32 is guaranteed to do so, but it's
| |
| 159 if (!reader.PopUint32(&state)) { | |
| 160 LOG(WARNING) << "Unexpected response for NetworkManager State request: " | |
| 161 << signal->ToString(); | |
| 162 return; | |
| 163 } | |
| 164 OnlineState new_online_state = TranslateState(state); | |
| 165 { | |
| 166 base::AutoLock lock(online_state_lock_); | |
| 167 if (new_online_state != online_state_) | |
| 168 online_state_ = new_online_state; | |
| 169 else | |
| 170 return; | |
| 171 } | |
| 172 // Can't notify while we hold the lock | |
| 173 notification_callback_.Run(); | |
| 174 } | |
| 175 | |
| 176 uint32 NetworkManagerApi::GetCurrentState(dbus::ObjectProxy* proxy) { | |
| 177 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId()); | |
| 178 dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get"); | |
| 179 dbus::MessageWriter builder(&method_call); | |
| 180 builder.AppendString(kNetworkManagerInterface); | |
| 181 builder.AppendString("State"); | |
| 182 // OK to block since we're on the helper thread. | |
| 183 scoped_ptr<dbus::Response> response( | |
| 184 proxy->CallMethodAndBlock(&method_call, | |
| 185 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 186 if (!response.get()) | |
| 187 return NM_STATE_UNKNOWN; | |
|
satorux1
2011/10/13 21:41:19
you might want to add log warning about a method c
adamk
2011/10/24 22:37:00
Done.
| |
| 188 | |
| 189 dbus::MessageReader reader(response.get()); | |
| 190 uint32 state; | |
|
satorux1
2011/10/13 21:41:19
nit: initialize this?
adamk
2011/10/24 22:37:00
De-duped this code, so done.
| |
| 191 if (!reader.PopUint32(&state)) { | |
| 192 LOG(WARNING) << "Unexpected response for NetworkManager State request: " | |
| 193 << response->ToString(); | |
| 194 return NM_STATE_UNKNOWN; | |
| 195 } | |
| 196 | |
| 197 return state; | |
| 198 } | |
| 199 | |
| 200 NetworkManagerApi::OnlineState NetworkManagerApi::TranslateState(uint32 state) { | |
| 201 switch (state) { | |
| 202 case NM_LEGACY_STATE_CONNECTED: | |
| 203 case NM_STATE_CONNECTED_SITE: | |
| 204 case NM_STATE_CONNECTED_GLOBAL: | |
| 205 // Definitely connected | |
| 206 return ONLINE; | |
| 207 case NM_LEGACY_STATE_DISCONNECTED: | |
| 208 case NM_STATE_DISCONNECTED: | |
| 209 // Definitely disconnected | |
| 210 return OFFLINE; | |
| 211 case NM_STATE_CONNECTED_LOCAL: | |
| 212 // Local networking only; I'm treating this as offline (keybuk) | |
| 213 return OFFLINE; | |
| 214 case NM_LEGACY_STATE_CONNECTING: | |
| 215 case NM_STATE_DISCONNECTING: | |
| 216 case NM_STATE_CONNECTING: | |
| 217 // In-flight change to connection status currently underway | |
| 218 return OFFLINE; | |
| 219 case NM_LEGACY_STATE_ASLEEP: | |
| 220 case NM_STATE_ASLEEP: | |
| 221 // Networking disabled or no devices on system | |
| 222 return OFFLINE; | |
| 223 default: | |
| 224 // Unknown status | |
| 225 return ONLINE; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 bool NetworkManagerApi::IsCurrentlyOffline() { | |
| 230 online_state_initialized_.Wait(); | |
| 231 base::AutoLock lock(online_state_lock_); | |
| 232 return online_state_ == OFFLINE; | |
| 233 } | |
| 234 | |
| 29 class DNSWatchDelegate : public FilePathWatcher::Delegate { | 235 class DNSWatchDelegate : public FilePathWatcher::Delegate { |
| 30 public: | 236 public: |
| 31 explicit DNSWatchDelegate(Callback0::Type* callback) | 237 explicit DNSWatchDelegate(Callback0::Type* callback) |
| 32 : callback_(callback) {} | 238 : callback_(callback) {} |
| 33 virtual ~DNSWatchDelegate() {} | 239 virtual ~DNSWatchDelegate() {} |
| 34 // FilePathWatcher::Delegate interface | 240 // FilePathWatcher::Delegate interface |
| 35 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE; | 241 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE; |
| 36 virtual void OnFilePathError(const FilePath& path) OVERRIDE; | 242 virtual void OnFilePathError(const FilePath& path) OVERRIDE; |
| 37 private: | 243 private: |
| 38 scoped_ptr<Callback0::Type> callback_; | 244 scoped_ptr<Callback0::Type> callback_; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 54 class NetworkChangeNotifierLinux::Thread | 260 class NetworkChangeNotifierLinux::Thread |
| 55 : public base::Thread, public MessageLoopForIO::Watcher { | 261 : public base::Thread, public MessageLoopForIO::Watcher { |
| 56 public: | 262 public: |
| 57 Thread(); | 263 Thread(); |
| 58 virtual ~Thread(); | 264 virtual ~Thread(); |
| 59 | 265 |
| 60 // MessageLoopForIO::Watcher: | 266 // MessageLoopForIO::Watcher: |
| 61 virtual void OnFileCanReadWithoutBlocking(int fd); | 267 virtual void OnFileCanReadWithoutBlocking(int fd); |
| 62 virtual void OnFileCanWriteWithoutBlocking(int /* fd */); | 268 virtual void OnFileCanWriteWithoutBlocking(int /* fd */); |
| 63 | 269 |
| 270 // Plumbing for NetworkChangeNotifier::IsCurrentlyOffline. | |
| 271 // Safe to call from any thread. | |
| 272 bool IsCurrentlyOffline() { | |
| 273 return network_manager_api_.IsCurrentlyOffline(); | |
| 274 } | |
| 275 | |
| 64 protected: | 276 protected: |
| 65 // base::Thread | 277 // base::Thread |
| 66 virtual void Init(); | 278 virtual void Init(); |
| 67 virtual void CleanUp(); | 279 virtual void CleanUp(); |
| 68 | 280 |
| 69 private: | 281 private: |
| 70 void NotifyObserversOfIPAddressChange() { | 282 void NotifyObserversOfIPAddressChange() { |
| 71 NetworkChangeNotifier::NotifyObserversOfIPAddressChange(); | 283 NetworkChangeNotifier::NotifyObserversOfIPAddressChange(); |
| 72 } | 284 } |
| 73 | 285 |
| 74 void NotifyObserversOfDNSChange() { | 286 void NotifyObserversOfDNSChange() { |
| 75 NetworkChangeNotifier::NotifyObserversOfDNSChange(); | 287 NetworkChangeNotifier::NotifyObserversOfDNSChange(); |
| 76 } | 288 } |
| 77 | 289 |
| 290 static void NotifyObserversOfOnlineStateChange() { | |
| 291 NetworkChangeNotifier::NotifyObserversOfOnlineStateChange(); | |
| 292 } | |
| 293 | |
| 78 // Starts listening for netlink messages. Also handles the messages if there | 294 // Starts listening for netlink messages. Also handles the messages if there |
| 79 // are any available on the netlink socket. | 295 // are any available on the netlink socket. |
| 80 void ListenForNotifications(); | 296 void ListenForNotifications(); |
| 81 | 297 |
| 82 // Attempts to read from the netlink socket into |buf| of length |len|. | 298 // Attempts to read from the netlink socket into |buf| of length |len|. |
| 83 // Returns the bytes read on synchronous success and ERR_IO_PENDING if the | 299 // Returns the bytes read on synchronous success and ERR_IO_PENDING if the |
| 84 // recv() would block. Otherwise, it returns a net error code. | 300 // recv() would block. Otherwise, it returns a net error code. |
| 85 int ReadNotificationMessage(char* buf, size_t len); | 301 int ReadNotificationMessage(char* buf, size_t len); |
| 86 | 302 |
| 87 // The netlink socket descriptor. | 303 // The netlink socket descriptor. |
| 88 int netlink_fd_; | 304 int netlink_fd_; |
| 89 MessageLoopForIO::FileDescriptorWatcher netlink_watcher_; | 305 MessageLoopForIO::FileDescriptorWatcher netlink_watcher_; |
| 90 | 306 |
| 91 // Technically only needed for ChromeOS, but it's ugly to #ifdef out. | 307 // Technically only needed for ChromeOS, but it's ugly to #ifdef out. |
| 92 ScopedRunnableMethodFactory<Thread> method_factory_; | 308 ScopedRunnableMethodFactory<Thread> method_factory_; |
| 93 | 309 |
| 94 // Used to watch for changes to /etc/resolv.conf and /etc/hosts. | 310 // Used to watch for changes to /etc/resolv.conf and /etc/hosts. |
| 95 scoped_ptr<base::files::FilePathWatcher> resolv_file_watcher_; | 311 scoped_ptr<base::files::FilePathWatcher> resolv_file_watcher_; |
| 96 scoped_ptr<base::files::FilePathWatcher> hosts_file_watcher_; | 312 scoped_ptr<base::files::FilePathWatcher> hosts_file_watcher_; |
| 97 scoped_refptr<DNSWatchDelegate> file_watcher_delegate_; | 313 scoped_refptr<DNSWatchDelegate> file_watcher_delegate_; |
| 98 | 314 |
| 315 // Used to detect online/offline state changes. | |
| 316 NetworkManagerApi network_manager_api_; | |
| 317 | |
| 99 DISALLOW_COPY_AND_ASSIGN(Thread); | 318 DISALLOW_COPY_AND_ASSIGN(Thread); |
| 100 }; | 319 }; |
| 101 | 320 |
| 102 NetworkChangeNotifierLinux::Thread::Thread() | 321 NetworkChangeNotifierLinux::Thread::Thread() |
| 103 : base::Thread("NetworkChangeNotifier"), | 322 : base::Thread("NetworkChangeNotifier"), |
| 104 netlink_fd_(kInvalidSocket), | 323 netlink_fd_(kInvalidSocket), |
| 105 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 324 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
| 325 network_manager_api_( | |
| 326 base::Bind(&NetworkChangeNotifierLinux::Thread | |
| 327 ::NotifyObserversOfOnlineStateChange)) { | |
| 106 } | 328 } |
| 107 | 329 |
| 108 NetworkChangeNotifierLinux::Thread::~Thread() {} | 330 NetworkChangeNotifierLinux::Thread::~Thread() {} |
| 109 | 331 |
| 110 void NetworkChangeNotifierLinux::Thread::Init() { | 332 void NetworkChangeNotifierLinux::Thread::Init() { |
| 111 resolv_file_watcher_.reset(new FilePathWatcher); | 333 resolv_file_watcher_.reset(new FilePathWatcher); |
| 112 hosts_file_watcher_.reset(new FilePathWatcher); | 334 hosts_file_watcher_.reset(new FilePathWatcher); |
| 113 file_watcher_delegate_ = new DNSWatchDelegate(NewCallback(this, | 335 file_watcher_delegate_ = new DNSWatchDelegate(NewCallback(this, |
| 114 &NetworkChangeNotifierLinux::Thread::NotifyObserversOfDNSChange)); | 336 &NetworkChangeNotifierLinux::Thread::NotifyObserversOfDNSChange)); |
| 115 if (!resolv_file_watcher_->Watch( | 337 if (!resolv_file_watcher_->Watch( |
| 116 FilePath(FILE_PATH_LITERAL("/etc/resolv.conf")), | 338 FilePath(FILE_PATH_LITERAL("/etc/resolv.conf")), |
| 117 file_watcher_delegate_.get())) { | 339 file_watcher_delegate_.get())) { |
| 118 LOG(ERROR) << "Failed to setup watch for /etc/resolv.conf"; | 340 LOG(ERROR) << "Failed to setup watch for /etc/resolv.conf"; |
| 119 } | 341 } |
| 120 if (!hosts_file_watcher_->Watch(FilePath(FILE_PATH_LITERAL("/etc/hosts")), | 342 if (!hosts_file_watcher_->Watch(FilePath(FILE_PATH_LITERAL("/etc/hosts")), |
| 121 file_watcher_delegate_.get())) { | 343 file_watcher_delegate_.get())) { |
| 122 LOG(ERROR) << "Failed to setup watch for /etc/hosts"; | 344 LOG(ERROR) << "Failed to setup watch for /etc/hosts"; |
| 123 } | 345 } |
| 124 netlink_fd_ = InitializeNetlinkSocket(); | 346 netlink_fd_ = InitializeNetlinkSocket(); |
| 125 if (netlink_fd_ < 0) { | 347 if (netlink_fd_ < 0) { |
| 126 netlink_fd_ = kInvalidSocket; | 348 netlink_fd_ = kInvalidSocket; |
| 127 return; | 349 return; |
| 128 } | 350 } |
| 129 ListenForNotifications(); | 351 ListenForNotifications(); |
| 352 | |
| 353 network_manager_api_.Init(); | |
| 130 } | 354 } |
| 131 | 355 |
| 132 void NetworkChangeNotifierLinux::Thread::CleanUp() { | 356 void NetworkChangeNotifierLinux::Thread::CleanUp() { |
| 133 if (netlink_fd_ != kInvalidSocket) { | 357 if (netlink_fd_ != kInvalidSocket) { |
| 134 if (HANDLE_EINTR(close(netlink_fd_)) != 0) | 358 if (HANDLE_EINTR(close(netlink_fd_)) != 0) |
| 135 PLOG(ERROR) << "Failed to close socket"; | 359 PLOG(ERROR) << "Failed to close socket"; |
| 136 netlink_fd_ = kInvalidSocket; | 360 netlink_fd_ = kInvalidSocket; |
| 137 netlink_watcher_.StopWatchingFileDescriptor(); | 361 netlink_watcher_.StopWatchingFileDescriptor(); |
| 138 } | 362 } |
| 139 // Kill watchers early to make sure they won't try to call | 363 // Kill watchers early to make sure they won't try to call |
| 140 // into us via the delegate during destruction. | 364 // into us via the delegate during destruction. |
| 141 resolv_file_watcher_.reset(); | 365 resolv_file_watcher_.reset(); |
| 142 hosts_file_watcher_.reset(); | 366 hosts_file_watcher_.reset(); |
| 367 | |
| 368 network_manager_api_.CleanUp(); | |
| 143 } | 369 } |
| 144 | 370 |
| 145 void NetworkChangeNotifierLinux::Thread::OnFileCanReadWithoutBlocking(int fd) { | 371 void NetworkChangeNotifierLinux::Thread::OnFileCanReadWithoutBlocking(int fd) { |
| 146 DCHECK_EQ(fd, netlink_fd_); | 372 DCHECK_EQ(fd, netlink_fd_); |
| 147 ListenForNotifications(); | 373 ListenForNotifications(); |
| 148 } | 374 } |
| 149 | 375 |
| 150 void NetworkChangeNotifierLinux::Thread::OnFileCanWriteWithoutBlocking( | 376 void NetworkChangeNotifierLinux::Thread::OnFileCanWriteWithoutBlocking( |
| 151 int /* fd */) { | 377 int /* fd */) { |
| 152 NOTREACHED(); | 378 NOTREACHED(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 notifier_thread_->StartWithOptions(thread_options); | 437 notifier_thread_->StartWithOptions(thread_options); |
| 212 } | 438 } |
| 213 | 439 |
| 214 NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() { | 440 NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() { |
| 215 // We don't need to explicitly Stop(), but doing so allows us to sanity- | 441 // We don't need to explicitly Stop(), but doing so allows us to sanity- |
| 216 // check that the notifier thread shut down properly. | 442 // check that the notifier thread shut down properly. |
| 217 notifier_thread_->Stop(); | 443 notifier_thread_->Stop(); |
| 218 } | 444 } |
| 219 | 445 |
| 220 bool NetworkChangeNotifierLinux::IsCurrentlyOffline() const { | 446 bool NetworkChangeNotifierLinux::IsCurrentlyOffline() const { |
| 221 // TODO(eroman): http://crbug.com/53473 | 447 return notifier_thread_->IsCurrentlyOffline(); |
| 222 return false; | |
| 223 } | 448 } |
| 224 | 449 |
| 225 } // namespace net | 450 } // namespace net |
| OLD | NEW |