Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: net/base/network_change_notifier_linux.cc

Issue 8591021: Fix initial offline state response handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Deal with review comments Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | net/base/network_change_notifier_linux_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.
4 // 4 //
5 // This implementation of NetworkChangeNotifier's offline state detection 5 // This implementation of NetworkChangeNotifier's offline state detection
6 // depends on D-Bus and NetworkManager, and is known to work on at least 6 // depends on D-Bus and NetworkManager, and is known to work on at least
7 // GNOME version 2.30. If D-Bus or NetworkManager are unavailable, this 7 // GNOME version 2.30. If D-Bus or NetworkManager are unavailable, this
8 // implementation will always behave as if it is online. 8 // implementation will always behave as if it is online.
9 9
10 #include "net/base/network_change_notifier_linux.h" 10 #include "net/base/network_change_notifier_linux.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 81
82 // Must be called by the helper thread's CleanUp() method. 82 // Must be called by the helper thread's CleanUp() method.
83 void CleanUp(); 83 void CleanUp();
84 84
85 // Implementation of NetworkChangeNotifierLinux::IsCurrentlyOffline(). 85 // Implementation of NetworkChangeNotifierLinux::IsCurrentlyOffline().
86 // Safe to call from any thread, but will block until Init() has completed. 86 // Safe to call from any thread, but will block until Init() has completed.
87 bool IsCurrentlyOffline(); 87 bool IsCurrentlyOffline();
88 88
89 private: 89 private:
90 // Callbacks for D-Bus API. 90 // Callbacks for D-Bus API.
91 void OnStateChanged(dbus::Message* message); 91 void OnInitialResponse(dbus::Response* response) {
92 92 HandleResponse(response);
93 void OnResponse(dbus::Response* response) {
94 OnStateChanged(response);
95 offline_state_initialized_.Signal(); 93 offline_state_initialized_.Signal();
96 } 94 }
97 95
98 void OnSignaled(dbus::Signal* signal) { 96 void OnSignaled(dbus::Signal* signal);
99 OnStateChanged(signal);
100 }
101 97
102 void OnConnected(const std::string&, const std::string&, bool success) { 98 void OnConnected(const std::string&, const std::string&, bool success) {
103 if (!success) { 99 if (!success) {
104 DLOG(WARNING) << "Failed to set up offline state detection"; 100 DLOG(WARNING) << "Failed to set up offline state detection";
105 offline_state_initialized_.Signal(); 101 offline_state_initialized_.Signal();
106 } 102 }
107 } 103 }
108 104
105 // Helper for OnInitialResponse.
106 void HandleResponse(dbus::Response* response);
107
109 // Converts a NetworkManager state uint to a bool. 108 // Converts a NetworkManager state uint to a bool.
110 static bool StateIsOffline(uint32 state); 109 static bool StateIsOffline(uint32 state);
111 110
112 bool is_offline_; 111 bool is_offline_;
113 base::Lock is_offline_lock_; 112 base::Lock is_offline_lock_;
114 base::WaitableEvent offline_state_initialized_; 113 base::WaitableEvent offline_state_initialized_;
115 114
116 base::Closure notification_callback_; 115 base::Closure notification_callback_;
117 116
118 base::PlatformThreadId helper_thread_id_; 117 base::PlatformThreadId helper_thread_id_;
(...skipping 21 matching lines...) Expand all
140 system_bus_->GetObjectProxy(kNetworkManagerServiceName, 139 system_bus_->GetObjectProxy(kNetworkManagerServiceName,
141 kNetworkManagerPath); 140 kNetworkManagerPath);
142 141
143 // Get the initial state asynchronously. 142 // Get the initial state asynchronously.
144 dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get"); 143 dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get");
145 dbus::MessageWriter builder(&method_call); 144 dbus::MessageWriter builder(&method_call);
146 builder.AppendString(kNetworkManagerInterface); 145 builder.AppendString(kNetworkManagerInterface);
147 builder.AppendString("State"); 146 builder.AppendString("State");
148 proxy->CallMethod( 147 proxy->CallMethod(
149 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 148 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
150 base::Bind(&NetworkManagerApi::OnResponse, ptr_factory_.GetWeakPtr())); 149 base::Bind(&NetworkManagerApi::OnInitialResponse,
150 ptr_factory_.GetWeakPtr()));
151 151
152 // And sign up for notifications. 152 // And sign up for notifications.
153 proxy->ConnectToSignal( 153 proxy->ConnectToSignal(
154 kNetworkManagerInterface, 154 kNetworkManagerInterface,
155 "StateChanged", 155 "StateChanged",
156 base::Bind(&NetworkManagerApi::OnSignaled, ptr_factory_.GetWeakPtr()), 156 base::Bind(&NetworkManagerApi::OnSignaled, ptr_factory_.GetWeakPtr()),
157 base::Bind(&NetworkManagerApi::OnConnected, ptr_factory_.GetWeakPtr())); 157 base::Bind(&NetworkManagerApi::OnConnected, ptr_factory_.GetWeakPtr()));
158 } 158 }
159 159
160 void NetworkManagerApi::CleanUp() { 160 void NetworkManagerApi::CleanUp() {
161 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId()); 161 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId());
162 ptr_factory_.InvalidateWeakPtrs(); 162 ptr_factory_.InvalidateWeakPtrs();
163 } 163 }
164 164
165 void NetworkManagerApi::OnStateChanged(dbus::Message* message) { 165 void NetworkManagerApi::HandleResponse(dbus::Response* response) {
166 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId()); 166 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId());
167 if (!message) { 167 if (!response) {
168 DLOG(WARNING) << "No response received for initial state request"; 168 DLOG(WARNING) << "No response received for initial state request";
169 return; 169 return;
170 } 170 }
171 dbus::MessageReader reader(message); 171 dbus::MessageReader reader(response);
172 uint32 state = 0; 172 uint32 state = 0;
173 if (!reader.HasMoreData() || !reader.PopUint32(&state)) { 173 if (!reader.PopVariantOfUint32(&state)) {
174 DLOG(WARNING) << "Unexpected response for NetworkManager State request: " 174 DLOG(WARNING) << "Unexpected response for NetworkManager State request: "
175 << message->ToString(); 175 << response->ToString();
176 return;
177 }
178 {
179 base::AutoLock lock(is_offline_lock_);
180 is_offline_ = StateIsOffline(state);
181 }
182 }
183
184 void NetworkManagerApi::OnSignaled(dbus::Signal* signal) {
185 DCHECK_EQ(helper_thread_id_, base::PlatformThread::CurrentId());
186 dbus::MessageReader reader(signal);
187 uint32 state = 0;
188 if (!reader.PopUint32(&state)) {
189 DLOG(WARNING) << "Unexpected signal for NetworkManager StateChanged: "
190 << signal->ToString();
176 return; 191 return;
177 } 192 }
178 bool new_is_offline = StateIsOffline(state); 193 bool new_is_offline = StateIsOffline(state);
179 { 194 {
180 base::AutoLock lock(is_offline_lock_); 195 base::AutoLock lock(is_offline_lock_);
181 if (is_offline_ != new_is_offline) 196 if (is_offline_ != new_is_offline)
182 is_offline_ = new_is_offline; 197 is_offline_ = new_is_offline;
183 else 198 else
184 return; 199 return;
185 } 200 }
186 if (offline_state_initialized_.IsSignaled()) 201 notification_callback_.Run();
187 notification_callback_.Run();
188 } 202 }
189 203
190 bool NetworkManagerApi::StateIsOffline(uint32 state) { 204 bool NetworkManagerApi::StateIsOffline(uint32 state) {
191 switch (state) { 205 switch (state) {
192 case NM_LEGACY_STATE_CONNECTED: 206 case NM_LEGACY_STATE_CONNECTED:
193 case NM_STATE_CONNECTED_SITE: 207 case NM_STATE_CONNECTED_SITE:
194 case NM_STATE_CONNECTED_GLOBAL: 208 case NM_STATE_CONNECTED_GLOBAL:
195 // Definitely connected 209 // Definitely connected
196 return false; 210 return false;
197 case NM_LEGACY_STATE_DISCONNECTED: 211 case NM_LEGACY_STATE_DISCONNECTED:
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // Stopping from here allows us to sanity- check that the notifier 457 // Stopping from here allows us to sanity- check that the notifier
444 // thread shut down properly. 458 // thread shut down properly.
445 notifier_thread_->Stop(); 459 notifier_thread_->Stop();
446 } 460 }
447 461
448 bool NetworkChangeNotifierLinux::IsCurrentlyOffline() const { 462 bool NetworkChangeNotifierLinux::IsCurrentlyOffline() const {
449 return notifier_thread_->IsCurrentlyOffline(); 463 return notifier_thread_->IsCurrentlyOffline();
450 } 464 }
451 465
452 } // namespace net 466 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/base/network_change_notifier_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698