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

Side by Side Diff: src/device_impl.cc

Issue 6395007: cashew: gmock integration (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cashew.git@master
Patch Set: Created 9 years, 10 months 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 | « src/device_impl.h ('k') | src/device_mock.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010, 2011 The Chromium OS 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 #include "src/device_impl.h"
6
7 #include <glog/logging.h>
8
9 #include "src/byte_counter.h"
10 #include "src/service.h"
11
12 namespace cashew {
13
14 // Flimflam Device D-Bus identifiers
15 static const char *kFlimflamDeviceName = "org.chromium.flimflam";
16
17 // Flimflam Device property names
18 static const char *kFlimflamDeviceCarrierProperty = "Cellular.Carrier";
19 static const char *kFlimflamDeviceInterfaceProperty = "Interface";
20 static const char *kFlimflamDeviceTypeProperty = "Type";
21
22 // Flimflam Device on-the-wire Type values
23 static const char *kFlimflamDeviceTypeEthernet = "ethernet";
24 static const char *kFlimflamDeviceTypeWifi = "wifi";
25 static const char *kFlimflamDeviceTypeWimax = "wimax";
26 static const char *kFlimflamDeviceTypeBluetooth = "bluetooth";
27 static const char *kFlimflamDeviceTypeGPS = "gps";
28 static const char *kFlimflamDeviceTypeCellular = "cellular";
29 // TODO(vlaviano): what does vendor look like?
30 static const char *kFlimflamDeviceTypeVendor = "";
31
32 // GetDeviceProperties retry interval
33 static const guint kSecondsPerMinute = 60;
34 static const guint kGetDevicePropertiesIntervalSeconds = 1 * kSecondsPerMinute;
35
36 DeviceImpl::DeviceImpl(Service * const parent,
37 DBus::Connection& connection, // NOLINT
38 const DBus::Path& path)
39 : DBus::ObjectProxy(connection, path, kFlimflamDeviceName),
40 parent_(CHECK_NOTNULL(parent)), path_(path), type_(kTypeUnknown),
41 get_properties_source_id_(0), retrying_get_properties_(false),
42 byte_counter_(NULL), byte_counter_running_(false) {
43 // schedule a GetProperties() call to our Flimflam service path to init state
44 // we'll keep trying periodically until we succeed
45 // we'll subsequently update this state by monitoring PropertyChanged signals
46 get_properties_source_id_ =
47 g_idle_add(StaticGetDevicePropertiesCallback, this);
48 if (get_properties_source_id_ == 0) {
49 LOG(ERROR) << path_ << ": ctor: g_idle_add failed";
50 }
51 property_changed_handler_.delegate(this);
52 }
53
54 DeviceImpl::~DeviceImpl() {
55 StopByteCounter();
56 if (get_properties_source_id_ != 0 &&
57 !g_source_remove(get_properties_source_id_)) {
58 DLOG(WARNING) << path_ << ": dtor: g_source_remove failed";
59 }
60 }
61
62 const DBus::Path& DeviceImpl::GetPath() const {
63 return path_;
64 }
65
66 Device::Type DeviceImpl::GetType() const {
67 return type_;
68 }
69
70 const std::string& DeviceImpl::GetCarrier() const {
71 return carrier_;
72 }
73
74 const std::string& DeviceImpl::GetInterface() const {
75 return interface_;
76 }
77
78 // Flimflam Device D-Bus Proxy methods
79
80 void DeviceImpl::PropertyChanged(const std::string& property_name,
81 const DBus::Variant& new_value) {
82 DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name;
83 // Queue a tuple representing this signal for later processing from the glib
84 // main loop. We do this to avoid libdbus-c++ deadlocks that can occur when
85 // sending a dbus message from within a dbus callback like this one.
86 PropertyChangedSignal signal(property_name, new_value);
87 property_changed_handler_.EnqueueSignal(signal);
88 }
89
90 // PropertyChangedDelegate methods
91
92 void DeviceImpl::OnPropertyChanged(const PropertyChangedHandler *handler,
93 const std::string& property_name,
94 const DBus::Variant& new_value) {
95 DCHECK(handler == &property_changed_handler_);
96 DLOG(INFO) << path_ << ": OnPropertyChanged: property_name = "
97 << property_name;
98 if (property_name == kFlimflamDeviceCarrierProperty) {
99 OnCarrierUpdate(new_value.reader().get_string());
100 } else if (property_name == kFlimflamDeviceInterfaceProperty) {
101 OnInterfaceUpdate(new_value.reader().get_string());
102 } else if (property_name == kFlimflamDeviceTypeProperty) {
103 OnTypeUpdate(new_value.reader().get_string());
104 } else {
105 // we don't care about this property
106 }
107 }
108
109 // Service methods
110
111 bool DeviceImpl::StartByteCounter() {
112 if (byte_counter_running_) {
113 DLOG(WARNING) << path_ << ": StartByteCounter: counter already running";
114 return false;
115 }
116 byte_counter_running_ = true;
117 if (interface_.empty()) {
118 // if we don't yet know our interface name, we report success but hold off
119 // creating a byte counter object; we'll do so later in OnInterfaceUpdate
120 DLOG(INFO) << path_
121 << ": StartByteCounter: no interface name, delaying counter creation";
122 return true;
123 }
124 if (!CreateByteCounter()) {
125 DLOG(WARNING) << path_
126 << ": StartByteCounter: couldn't create byte counter for " << interface_;
127 byte_counter_running_ = false;
128 return false;
129 }
130 DLOG(INFO) << path_ << ": StartByteCounter: created byte counter for "
131 << interface_;
132 return true;
133 }
134
135 void DeviceImpl::StopByteCounter() {
136 if (byte_counter_running_) {
137 DeleteByteCounter();
138 byte_counter_running_ = false;
139 }
140 DCHECK(byte_counter_ == NULL);
141 }
142
143 bool DeviceImpl::ByteCounterRunning() const {
144 return byte_counter_running_;
145 }
146
147 // ByteCounterDelegate methods
148
149 void DeviceImpl::OnByteCounterUpdate(const ByteCounter *counter,
150 uint64 rx_bytes, uint64 tx_bytes) {
151 DCHECK(byte_counter_running_);
152 DCHECK(byte_counter_ != NULL);
153 DCHECK(counter == byte_counter_);
154 DLOG(INFO) << path_ << ": OnByteCounterUpdate: rx_bytes = " << rx_bytes
155 << ", tx_bytes = " << tx_bytes;
156 parent_->OnByteCounterUpdate(rx_bytes, tx_bytes);
157 }
158
159 // Private methods
160
161 Device::Type DeviceImpl::TypeFromString(const std::string& type) const {
162 if (type == kFlimflamDeviceTypeEthernet) {
163 return kTypeEthernet;
164 }
165 if (type == kFlimflamDeviceTypeWifi) {
166 return kTypeWifi;
167 }
168 if (type == kFlimflamDeviceTypeWimax) {
169 return kTypeWimax;
170 }
171 if (type == kFlimflamDeviceTypeBluetooth) {
172 return kTypeBluetooth;
173 }
174 if (type == kFlimflamDeviceTypeGPS) {
175 return kTypeGPS;
176 }
177 if (type == kFlimflamDeviceTypeCellular) {
178 return kTypeCellular;
179 }
180 if (type == kFlimflamDeviceTypeVendor) {
181 return kTypeVendor;
182 }
183 return kTypeUnknown;
184 }
185
186 void DeviceImpl::OnCarrierUpdate(const std::string& carrier) {
187 DLOG(INFO) << path_ << ": OnCarrierUpdate: carrier = " << carrier;
188 // only propagate this to parent Service if there's been a change
189 // we expect to see only one such change (from "Unknown")
190 if (carrier_ == carrier) {
191 return;
192 }
193 if (!carrier_.empty()) {
194 LOG(WARNING) << path_ << ": OnCarrierUpdate: carrier change from "
195 << carrier_ << " to " << carrier << "!";
196 }
197 carrier_ = carrier;
198 parent_->OnCarrierUpdate(carrier);
199 }
200
201 void DeviceImpl::OnInterfaceUpdate(const std::string& interface) {
202 DLOG(INFO) << path_ << ": OnInterfaceUpdate: interface = " << interface;
203 if (interface_ == interface) {
204 return;
205 }
206 if (!interface_.empty()) {
207 LOG(WARNING) << path_ << ": OnInterfaceUpdate: interface change from "
208 << interface_ << " to " << interface << "!";
209 }
210 const std::string old_interface = interface_;
211 interface_ = interface;
212 if (!byte_counter_running_) {
213 return;
214 }
215 // get rid of byte counter for old interface
216 StopByteCounter();
217 // if we don't have new interface info, we can't make a new byte counter yet
218 if (interface_.empty()) {
219 return;
220 }
221 // create byte counter for new interface
222 // TODO(vlaviano): creating new counter on interface change may confuse our
223 // parent service.
224 if (!StartByteCounter()) {
225 LOG(ERROR) << path_
226 << ": OnInterfaceUpdate: could not create byte counter for "
227 << interface_;
228 return;
229 }
230 }
231
232 void DeviceImpl::OnTypeUpdate(const std::string& type) {
233 DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type;
234 type_ = TypeFromString(type);
235 if (type_ != kTypeCellular) {
236 LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!";
237 }
238 }
239
240 // static
241 gboolean DeviceImpl::StaticGetDevicePropertiesCallback(gpointer data) {
242 DeviceImpl *device = reinterpret_cast<DeviceImpl*>(data);
243 CHECK_NOTNULL(device);
244 DCHECK_NE(device->get_properties_source_id_, 0);
245 if (!device->GetDeviceProperties()) {
246 // call failed, so try again later
247 DLOG(WARNING) << device->GetPath()
248 << ": StaticGetDevicePropertiesCallback: "
249 << "GetDeviceProperties failed, will retry in "
250 << kGetDevicePropertiesIntervalSeconds << " secs";
251 // if we've arrived here from our first g_idle_add call, set up a timer
252 if (!device->retrying_get_properties_) {
253 guint source_id =
254 g_timeout_add_seconds(kGetDevicePropertiesIntervalSeconds,
255 StaticGetDevicePropertiesCallback, device);
256 device->get_properties_source_id_ = source_id;
257 if (source_id == 0) {
258 LOG(ERROR) << device->GetPath()
259 << ": StaticGetDevicePropertiesCallback: "
260 << "g_timeout_add_seconds failed";
261 return FALSE; // get rid of old glib source and give up
262 }
263 device->retrying_get_properties_ = true;
264 // get rid of our old glib source, but our new timer will call us
265 return FALSE;
266 }
267 // otherwise, our timer is already set up
268 // return TRUE to indicate that we want to be called again later
269 return TRUE;
270 }
271 device->get_properties_source_id_ = 0;
272 device->retrying_get_properties_ = false;
273 return FALSE; // we succeeded, so don't repeat
274 }
275
276 bool DeviceImpl::GetDeviceProperties() {
277 DLOG(INFO) << path_ << ": GetDeviceProperties";
278 PropertyMap properties;
279 // dbus-c++ throws exceptions
280 // invoke the "Existing Non-conformant Code" clause of the style guide and
281 // isolate the rest of the system from this
282 try {
283 // TODO(vlaviano): make this call asynchronous
284 properties = GetProperties();
285 } catch (DBus::Error& error) { // NOLINT
286 LOG(WARNING) << path_
287 << ": GetDeviceProperties: GetProperties() -> Exception: "
288 << error.name() << ": " << error.message();
289 return false;
290 } catch (...) { // NOLINT
291 LOG(WARNING) << path_
292 << ": GetDeviceProperties: GetProperties() -> Exception";
293 return false;
294 }
295 DLOG(INFO) << "Received " << properties.size() << " properties";
296
297 // grab the properties in which we're interested
298 PropertyMap::const_iterator it;
299 it = properties.find(kFlimflamDeviceInterfaceProperty);
300 if (it != properties.end()) {
301 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
302 OnInterfaceUpdate(value.reader().get_string());
303 } else {
304 DLOG(WARNING) << path_ << ": GetDeviceProperties: no Interface property";
305 }
306 it = properties.find(kFlimflamDeviceTypeProperty);
307 if (it != properties.end()) {
308 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
309 OnTypeUpdate(value.reader().get_string());
310 } else {
311 DLOG(WARNING) << path_ << ": GetDeviceProperties: no Type property";
312 }
313 // don't expect to find Cellular.* properties if we're not a cellular device
314 if (type_ != kTypeCellular) {
315 return true;
316 }
317 it = properties.find(kFlimflamDeviceCarrierProperty);
318 if (it != properties.end()) {
319 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
320 OnCarrierUpdate(value.reader().get_string());
321 } else {
322 DLOG(WARNING) << path_
323 << ": GetDeviceProperties: no Cellular.Carrier property";
324 }
325 return true;
326 }
327
328 bool DeviceImpl::CreateByteCounter() {
329 if (byte_counter_ != NULL) {
330 DLOG(WARNING) << path_ << ": CreateByteCounter: counter already exists";
331 return false;
332 }
333 if (interface_.empty()) {
334 DLOG(WARNING) << path_ << ": CreateByteCounter: interface name unknown";
335 return false;
336 }
337 byte_counter_ = ByteCounter::NewByteCounter(interface_);
338 if (byte_counter_ == NULL) {
339 LOG(ERROR) << path_
340 << ": CreateByteCounter: could not create byte counter for "
341 << interface_;
342 return false;
343 }
344 byte_counter_->SetDelegate(this);
345 return true;
346 }
347
348 void DeviceImpl::DeleteByteCounter() {
349 DLOG(INFO) << path_ << ": DeleteByteCounter";
350 if (byte_counter_ != NULL) {
351 delete byte_counter_;
352 byte_counter_ = NULL;
353 }
354 }
355
356 } // namespace cashew
OLDNEW
« no previous file with comments | « src/device_impl.h ('k') | src/device_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698