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

Side by Side Diff: src/service_manager.cc

Issue 3764012: cashew: support "usage requests allowed OTA only" policy (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cashew.git
Patch Set: jglasgow review comments Created 10 years, 2 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/service_manager.h ('k') | no next file » | 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) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS 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 #include "src/service_manager.h" 5 #include "src/service_manager.h"
6 6
7 #include <glog/logging.h> 7 #include <glog/logging.h>
8 8
9 #include "src/cashew_server.h" 9 #include "src/cashew_server.h"
10 #include "src/service.h" 10 #include "src/service.h"
11 11
12 namespace cashew { 12 namespace cashew {
13 13
14 // Flimflam D-Bus indentifiers 14 // Flimflam D-Bus indentifiers
15 static const char* kFlimflamManagerName = "org.chromium.flimflam"; 15 static const char *kFlimflamManagerName = "org.chromium.flimflam";
16 static const char* kFlimflamManagerPath = "/"; 16 static const char *kFlimflamManagerPath = "/";
17 17
18 // Flimflam property names 18 // Flimflam property names
19 static const char* kServicesProperty = "Services"; 19 static const char *kDefaultTechnologyProperty = "DefaultTechnology";
20 static const char *kServicesProperty = "Services";
21 static const char *kStateProperty = "State";
22
23 // Flimflam on-the-wire State values
24 static const char *kFlimflamStateOffline = "offline";
25 static const char *kFlimflamStateConnected = "connected";
26 static const char *kFlimflamStateOnline = "online";
20 27
21 // Flimflam service types 28 // Flimflam service types
22 static const char* kTypeCellular = "cellular"; 29 static const char *kTypeCellular = "cellular";
23 30
24 ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT 31 ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT
25 : DBus::ObjectProxy(connection, kFlimflamManagerPath, 32 : DBus::ObjectProxy(connection, kFlimflamManagerPath,
26 kFlimflamManagerName), 33 kFlimflamManagerName),
27 connection_(connection), cashew_server_(NULL) { 34 connection_(connection), cashew_server_(NULL),
35 default_technology_(Service::kTypeUnknown),
36 default_cellular_service_(NULL),
37 connectivity_state_(kConnectivityStateUnknown) {
28 // init our state with a GetProperties() call to Flimflam 38 // init our state with a GetProperties() call to Flimflam
29 // we'll update this state by monitoring PropertyChanged signals 39 // we'll update this state by monitoring PropertyChanged signals
30 GetFlimflamServices(); 40 GetFlimflamProperties();
31 } 41 }
32 42
33 ServiceManager::~ServiceManager() { 43 ServiceManager::~ServiceManager() {
44 ClearDefaultCellularService();
34 DeleteServices(&services_); 45 DeleteServices(&services_);
35 } 46 }
36 47
37 const Service* ServiceManager::GetService(const std::string& service_path) 48 const Service* ServiceManager::GetService(const std::string& service_path)
38 const { 49 const {
39 ServiceMap::const_iterator it = services_.find(service_path); 50 ServiceMap::const_iterator it = services_.find(service_path);
40 if (it == services_.end()) { 51 if (it == services_.end()) {
41 return NULL; 52 return NULL;
42 } 53 }
43 DCHECK(it->second != NULL); 54 DCHECK(it->second != NULL);
44 return static_cast<const Service *>(it->second); 55 return static_cast<const Service *>(it->second);
45 } 56 }
46 57
47 void ServiceManager::SetCashewServer(CashewServer *cashew_server) { 58 void ServiceManager::SetCashewServer(CashewServer *cashew_server) {
48 DLOG(INFO) << "SetCashewServer"; 59 DLOG(INFO) << "SetCashewServer";
49 cashew_server_ = cashew_server; 60 cashew_server_ = cashew_server;
50 } 61 }
51 62
63 Service::Type ServiceManager::GetDefaultTechnology() const {
64 return default_technology_;
65 }
66
67 ServiceManager::ConnectivityState ServiceManager::GetConnectivityState()
68 const {
69 return connectivity_state_;
70 }
71
72 // static
73 bool ServiceManager::IsOfflineConnectivityState(
74 ServiceManager::ConnectivityState state) {
75 if (state == kConnectivityStateUnknown ||
76 state == kConnectivityStateOffline) {
77 return true;
78 }
79 return false;
80 }
81
82 // static
83 bool ServiceManager::IsOnlineConnectivityState(
84 ServiceManager::ConnectivityState state) {
85 if (state == kConnectivityStateConnected ||
86 state == kConnectivityStateOnline) {
87 return true;
88 }
89 return false;
90 }
91
52 // Flimflam Manager D-Bus Proxy methods 92 // Flimflam Manager D-Bus Proxy methods
53 93
54 void ServiceManager::PropertyChanged(const std::string& property_name, 94 void ServiceManager::PropertyChanged(const std::string& property_name,
55 const DBus::Variant& new_value) { 95 const DBus::Variant& new_value) {
56 DLOG(INFO) << "PropertyChanged: property_name = " << property_name; 96 DLOG(INFO) << "PropertyChanged: property_name = " << property_name;
57 97 if (property_name == kDefaultTechnologyProperty) {
58 // we only care about Services changes 98 OnDefaultTechnologyUpdate(new_value.reader().get_string());
59 if (property_name.compare(kServicesProperty)) { 99 } else if (property_name == kServicesProperty) {
60 return; 100 // interpret new_value as a vector of service paths
101 ServicePathList paths;
102 DBus::MessageIter reader = new_value.reader();
103 reader >> paths;
104 OnServicesUpdate(paths);
105 } else if (property_name == kStateProperty) {
106 // this has its own signal, StateChanged, but just in case...
107 StateChanged(new_value.reader().get_string());
108 } else {
109 // we don't care about this property
61 } 110 }
62
63 // interpret new_value as a vector of service paths
64 ServicePathList paths;
65 DBus::MessageIter reader = new_value.reader();
66 reader >> paths;
67
68 OnServicesUpdate(paths);
69 } 111 }
70 112
71 void ServiceManager::StateChanged(const std::string& new_state) { 113 void ServiceManager::StateChanged(const std::string& new_state_string) {
72 DLOG(INFO) << "StateChanged: new_state = " << new_state; 114 DLOG(INFO) << "StateChanged: new_state = " << new_state_string;
73 // TODO(vlaviano): switch on state and call private onFlimflamOffline(), 115 ConnectivityState old_state = connectivity_state_;
74 // onFlimflamOnline() hooks. If we care. 116 connectivity_state_ = ConnectivityStateFromString(new_state_string);
117 // see if we're coming online or going offline
118 // NOTE: we consider "unknown" to be offline
119 if (IsOfflineConnectivityState(old_state) &&
120 IsOnlineConnectivityState(connectivity_state_)) {
121 OnFlimflamOnline();
122 } else if (IsOnlineConnectivityState(old_state) &&
123 IsOfflineConnectivityState(connectivity_state_)) {
124 OnFlimflamOffline();
125 }
75 } 126 }
76 127
77 // Service methods 128 // Service methods
78 129
79 void ServiceManager::EmitDataPlansUpdate(const Service& service) { 130 void ServiceManager::EmitDataPlansUpdate(const Service& service) {
80 DLOG(INFO) << "EmitDataPlansUpdate: service = " << service.GetPath(); 131 DLOG(INFO) << "EmitDataPlansUpdate: service = " << service.GetPath();
81 if (cashew_server_ == NULL) { 132 if (cashew_server_ == NULL) {
82 DLOG(WARNING) << "EmitDataPlansUpdate: no Cashew server"; 133 DLOG(WARNING) << "EmitDataPlansUpdate: no Cashew server";
83 return; 134 return;
84 } 135 }
85 cashew_server_->EmitDataPlansUpdate(service); 136 cashew_server_->EmitDataPlansUpdate(service);
86 } 137 }
87 138
88 // Private methods 139 // Private methods
89 140
90 void ServiceManager::DeleteServices(ServiceMap *service_map) { 141 void ServiceManager::DeleteServices(ServiceMap *service_map) {
91 DCHECK(service_map != NULL); 142 DCHECK(service_map != NULL);
92 while (!service_map->empty()) { 143 while (!service_map->empty()) {
93 const std::string& path = 144 const std::string& path =
94 static_cast<std::string>(service_map->begin()->first); 145 static_cast<std::string>(service_map->begin()->first);
95 DLOG(INFO) << "DeleteServices: deleting service: " << path; 146 DLOG(INFO) << "DeleteServices: deleting service: " << path;
96 Service *service = static_cast<Service *>(service_map->begin()->second); 147 Service *service = static_cast<Service *>(service_map->begin()->second);
97 delete service; 148 delete service;
98 service_map->erase(service_map->begin()); 149 service_map->erase(service_map->begin());
99 } 150 }
100 } 151 }
101 152
102 void ServiceManager::GetFlimflamServices() { 153 void ServiceManager::GetFlimflamProperties() {
103 DLOG(INFO) << "GetFlimflamServices"; 154 DLOG(INFO) << "GetFlimflamProperties";
104 PropertyMap properties; 155 PropertyMap properties;
105 // dbus-c++ throws exceptions 156 // dbus-c++ throws exceptions
106 // invoke the "Existing Non-conformant Code" clause of the style guide and 157 // invoke the "Existing Non-conformant Code" clause of the style guide and
107 // isolate the rest of the system from this 158 // isolate the rest of the system from this
108 try { 159 try {
109 // TODO(vlaviano): make this call asynchronous 160 // TODO(vlaviano): make this call asynchronous
110 properties = GetProperties(); 161 properties = GetProperties();
111 } catch (DBus::Error& error) { // NOLINT 162 } catch (DBus::Error& error) { // NOLINT
112 LOG(WARNING) << "GetFlimflamServices: GetProperties() -> Exception: " 163 LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception: "
113 << error.name() << ": " << error.message(); 164 << error.name() << ": " << error.message();
114 // TODO(vlaviano): schedule another attempt later 165 // TODO(vlaviano): schedule another attempt later
115 return; 166 return;
116 } catch (...) { // NOLINT 167 } catch (...) { // NOLINT
117 LOG(WARNING) << "GetFlimflamServices: GetProperties() -> Exception"; 168 LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception";
118 // TODO(vlaviano): schedule another attempt later 169 // TODO(vlaviano): schedule another attempt later
119 return; 170 return;
120 } 171 }
172 DLOG(INFO) << "GetFlimflamProperties: Received " << properties.size()
173 << " properties";
121 174
122 // grab Services property from result 175 // grab the properties in which we're interested
123 PropertyMap::const_iterator it = properties.find(kServicesProperty); 176 PropertyMap::const_iterator it = properties.find(kDefaultTechnologyProperty);
124 if (it == properties.end()) { 177 if (it != properties.end()) {
125 DLOG(WARNING) << "GetFlimflamServices: no Services property"; 178 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
126 return; 179 OnDefaultTechnologyUpdate(value.reader().get_string());
180 } else {
181 DLOG(WARNING) << "GetFlimflamProperties: no DefaultTechnology property";
127 } 182 }
128 DBus::Variant value = static_cast<DBus::Variant>(it->second); 183 it = properties.find(kServicesProperty);
184 if (it != properties.end()) {
185 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
186 // interpret value as vector of service paths
187 ServicePathList paths;
188 DBus::MessageIter reader = value.reader();
189 reader >> paths;
190 OnServicesUpdate(paths);
191 } else {
192 DLOG(WARNING) << "GetFlimflamProperties: no Services property";
193 }
194 it = properties.find(kStateProperty);
195 if (it != properties.end()) {
196 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
197 StateChanged(value.reader().get_string());
198 } else {
199 DLOG(WARNING) << "GetFlimflamProperties: no State property";
200 }
201 }
129 202
130 // interpret value as vector of service paths 203 void ServiceManager::OnDefaultTechnologyUpdate(
131 ServicePathList paths; 204 const std::string& default_technology) {
132 DBus::MessageIter reader = value.reader(); 205 DLOG(INFO) << "OnDefaultTechnologyUpdate: default technology = "
133 reader >> paths; 206 << default_technology;
134 207 default_technology_ = Service::TypeFromString(default_technology);
135 OnServicesUpdate(paths); 208 if (default_technology_ == Service::kTypeUnknown) {
209 LOG(WARNING) << "OnDefaultTechnologyUpdate: unknown default technology: "
210 << default_technology;
211 }
212 if (default_technology_ != Service::kTypeCellular &&
213 default_cellular_service_ != NULL) {
214 // if the default technology isn't cellular and yet we think that one of
215 // our cellular services is the default service, then we need to update
216 // our view of the world.
217 ClearDefaultCellularService();
218 }
136 } 219 }
137 220
138 void ServiceManager::OnServicesUpdate(const ServicePathList& paths) { 221 void ServiceManager::OnServicesUpdate(const ServicePathList& paths) {
139 // Remember old set of services. This is the baseline from which we will 222 // Remember old set of services. This is the baseline from which we will
140 // determine what has changed. 223 // determine what has changed.
141 ServiceMap old_services = services_; 224 ServiceMap old_services = services_;
142 services_.clear(); 225 services_.clear();
143 226
144 // Flimflam service types are embedded in their path names, so we can use 227 // Flimflam service types are embedded in their path names, so we can use
145 // the pattern "/cellular_" to decide which paths are cellular services. 228 // the pattern "/cellular_" to decide which paths are cellular services.
(...skipping 19 matching lines...) Expand all
165 old_services.erase(old_it); 248 old_services.erase(old_it);
166 services_[path] = service; 249 services_[path] = service;
167 } else { 250 } else {
168 // service is new: create a Service obj for it and add it to services_ 251 // service is new: create a Service obj for it and add it to services_
169 OnNewService(path); 252 OnNewService(path);
170 } 253 }
171 } 254 }
172 255
173 // services left in old_services failed to appear in the update: delete them 256 // services left in old_services failed to appear in the update: delete them
174 DeleteServices(&old_services); 257 DeleteServices(&old_services);
258
259 // Flimflam always places the default service first in its list of services,
260 // so we'll take a look at the first element in the paths list and see if the
261 // default service has changed. Note that |paths| can be empty. We still want
262 // to know about this, since it means that there is no default service.
263 const DBus::Path *default_service_path = NULL;
264 if (!paths.empty()) {
265 default_service_path = &*paths.begin();
266 }
267 OnDefaultServiceUpdate(default_service_path);
175 } 268 }
176 269
177 void ServiceManager::OnNewService(const DBus::Path& path) { 270 void ServiceManager::OnNewService(const DBus::Path& path) {
178 DLOG(INFO) << "OnNewService: " << path; 271 DLOG(INFO) << "OnNewService: " << path;
179 DCHECK(GetService(path) == NULL); 272 DCHECK(GetService(path) == NULL);
180 Service *service = new(std::nothrow) Service(this, connection_, path); 273 Service *service = new(std::nothrow) Service(this, connection_, path);
181 if (service == NULL) { 274 if (service == NULL) {
182 LOG(ERROR) << "OnNewService: couldn't create service for " << path; 275 LOG(ERROR) << "OnNewService: couldn't create service for " << path;
183 return; 276 return;
184 } 277 }
185 services_[path] = service; 278 services_[path] = service;
186 } 279 }
187 280
281 void ServiceManager::OnDefaultServiceUpdate(const DBus::Path *path) {
282 DLOG(INFO) << "OnDefaultServiceUpdate: new default service = "
283 << ((path == NULL) ? "None" : *path);
284 // check if new default service path (if any) corresponds to one of our
285 // cellular services
286 Service *new_default_cellular_service = NULL;
287 if (path != NULL) {
288 new_default_cellular_service = const_cast<Service*>(GetService(*path));
289 }
290 if (new_default_cellular_service != NULL) {
291 SetDefaultCellularService(new_default_cellular_service);
292 } else {
293 ClearDefaultCellularService();
294 }
295 }
296
297 void ServiceManager::ClearDefaultCellularService() {
298 DLOG(INFO) << "ClearDefaultCellularService";
299 if (default_cellular_service_ != NULL) {
300 DCHECK(default_cellular_service_->IsDefaultService());
301 default_cellular_service_->OnDefaultServiceUpdate(false);
302 default_cellular_service_ = NULL;
303 }
304 }
305
306 void ServiceManager::SetDefaultCellularService(Service *service) {
307 DLOG(INFO) << "SetDefaultCellularService: "
308 << ((service == NULL) ? "None" : service->GetPath());
309 if (default_cellular_service_ == service) {
310 return;
311 }
312 if (default_cellular_service_ != NULL) {
313 ClearDefaultCellularService();
314 }
315 DCHECK(default_cellular_service_ == NULL);
316 if (service != NULL) {
317 DCHECK(!service->IsDefaultService());
318 service->OnDefaultServiceUpdate(true);
319 default_cellular_service_ = service;
320 }
321 }
322
323 // static
324 ServiceManager::ConnectivityState ServiceManager::ConnectivityStateFromString(
325 const std::string& state) {
326 if (state == kFlimflamStateOffline) {
327 return kConnectivityStateOffline;
328 }
329 if (state == kFlimflamStateConnected) {
330 return kConnectivityStateConnected;
331 }
332 if (state == kFlimflamStateOnline) {
333 return kConnectivityStateOnline;
334 }
335 return kConnectivityStateUnknown;
336 }
337
338 void ServiceManager::OnFlimflamOnline() {
339 DLOG(INFO) << "OnFlimflamOnline";
340 // notify our child services
341 ServiceMap::iterator it;
342 for (it = services_.begin(); it != services_.end(); ++it) {
343 Service *service = static_cast<Service*>(it->second);
344 DCHECK(service != NULL);
345 service->OnFlimflamOnline();
346 }
347 }
348
349 void ServiceManager::OnFlimflamOffline() {
350 DLOG(INFO) << "OnFlimflamOffline";
351 // notify our child services
352 ServiceMap::iterator it;
353 for (it = services_.begin(); it != services_.end(); ++it) {
354 Service *service = static_cast<Service*>(it->second);
355 DCHECK(service != NULL);
356 service->OnFlimflamOffline();
357 }
358 }
359
188 } // namespace cashew 360 } // namespace cashew
OLDNEW
« no previous file with comments | « src/service_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698