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

Side by Side Diff: src/service_manager.cc

Issue 3576011: Cashew: track cellular service state. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cashew.git
Patch Set: Make debug logging less verbose 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/service_manager.h"
6
7 #include <glog/logging.h>
8
9 #include "src/service.h"
10
11 namespace cashew {
12
13 // Flimflam D-Bus indentifiers
14 static const char* kFlimflamManagerName = "org.chromium.flimflam";
15 static const char* kFlimflamManagerPath = "/";
16
17 // Flimflam property names
18 static const char* kServicesProperty = "Services";
19
20 // Flimflam service types
21 static const char* kTypeCellular = "cellular";
22
23 ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT
24 : DBus::ObjectProxy(connection, kFlimflamManagerPath,
25 kFlimflamManagerName),
26 connection_(connection) {
27 // init our state with a GetProperties() call to Flimflam
28 // we'll update this state by monitoring PropertyChanged signals
29 GetFlimflamServices();
30 }
31
32 ServiceManager::~ServiceManager() {
33 DeleteServices(&services_);
34 }
35
36 const Service* ServiceManager::GetService(const std::string& service_path)
37 const {
38 ServiceMap::const_iterator it = services_.find(service_path);
39 if (it == services_.end()) {
40 return NULL;
41 }
42 DCHECK(it->second != NULL);
43 return static_cast<const Service *>(it->second);
44 }
45
46 // Flimflam Manager D-Bus Proxy methods
47
48 void ServiceManager::PropertyChanged(const std::string& property_name,
49 const DBus::Variant& new_value) {
50 DLOG(INFO) << "PropertyChanged: property_name = " << property_name;
51
52 // we only care about Services changes
53 if (property_name.compare(kServicesProperty)) {
54 return;
55 }
56
57 // interpret new_value as a vector of service paths
58 ServicePathList paths;
59 DBus::MessageIter reader = new_value.reader();
60 reader >> paths;
61
62 OnServicesUpdate(paths);
63 }
64
65 void ServiceManager::StateChanged(const std::string& new_state) {
66 DLOG(INFO) << "StateChanged: new_state = " << new_state;
67 // TODO(vlaviano): switch on state and call private onFlimflamOffline(),
68 // onFlimflamOnline() hooks. If we care.
69 }
70
71 // Private methods
72
73 void ServiceManager::DeleteServices(ServiceMap *service_map) {
74 DCHECK(service_map != NULL);
75 while (!service_map->empty()) {
76 const std::string& path =
77 static_cast<std::string>(service_map->begin()->first);
78 DLOG(INFO) << "DeleteServices: deleting service: " << path;
79 Service *service = static_cast<Service *>(service_map->begin()->second);
80 delete service;
81 service_map->erase(service_map->begin());
82 }
83 }
84
85 void ServiceManager::GetFlimflamServices() {
86 DLOG(INFO) << "GetFlimflamServices";
87 PropertyMap properties;
88 // dbus-c++ throws exceptions
89 // invoke the "Existing Non-conformant Code" clause of the style guide and
90 // isolate the rest of the system from this
91 try {
92 // TODO(vlaviano): make this call asynchronous
93 properties = GetProperties();
94 } catch (DBus::Error& error) { // NOLINT
95 LOG(WARNING) << "GetFlimflamServices: GetProperties() -> Exception: "
96 << error.name() << ": " << error.message();
97 // TODO(vlaviano): schedule another attempt later
98 return;
99 } catch (...) { // NOLINT
100 LOG(WARNING) << "GetFlimflamServices: GetProperties() -> Exception";
101 // TODO(vlaviano): schedule another attempt later
102 return;
103 }
104
105 // grab Services property from result
106 PropertyMap::const_iterator it = properties.find(kServicesProperty);
107 if (it == properties.end()) {
108 DLOG(WARNING) << "GetFlimflamServices: no Services property";
109 return;
110 }
111 DBus::Variant value = static_cast<DBus::Variant>(it->second);
112
113 // interpret value as vector of service paths
114 ServicePathList paths;
115 DBus::MessageIter reader = value.reader();
116 reader >> paths;
117
118 OnServicesUpdate(paths);
119 }
120
121 void ServiceManager::OnServicesUpdate(const ServicePathList& paths) {
122 // Remember old set of services. This is the baseline from which we will
123 // determine what has changed.
124 ServiceMap old_services = services_;
125 services_.clear();
126
127 // Flimflam service types are embedded in their path names, so we can use
128 // the pattern "/cellular_" to decide which paths are cellular services.
129 static const std::string cellular_pattern = std::string("/") + kTypeCellular
130 + "_";
131
132 // Walk paths in this update and see if they're new to us
133 DLOG(INFO) << "OnServicesUpdate: " << paths.size() << " service paths";
134 ServicePathList::const_iterator it;
135 for (it = paths.begin(); it != paths.end(); ++it) {
136 const DBus::Path& path = *it;
137
138 // We only care about cellular services
139 if (path.find(cellular_pattern) == std::string::npos) {
140 continue;
141 }
142
143 ServiceMap::iterator old_it = old_services.find(path);
144 if (old_it != old_services.end()) {
145 // service is old: move it from old_services to services_
146 Service *service = static_cast<Service *>(old_it->second);
147 DCHECK(service != NULL);
148 old_services.erase(old_it);
149 services_[path] = service;
150 } else {
151 // service is new: create a Service obj for it and add it to services_
152 OnNewService(path);
153 }
154 }
155
156 // services left in old_services failed to appear in the update: delete them
157 DeleteServices(&old_services);
158 }
159
160 void ServiceManager::OnNewService(const DBus::Path& path) {
161 DLOG(INFO) << "OnNewService: " << path;
162 DCHECK(GetService(path) == NULL);
163 Service *service = new(std::nothrow) Service(connection_, path);
164 if (service == NULL) {
165 LOG(ERROR) << "OnNewService: couldn't create service for " << path;
166 return;
167 }
168 services_[path] = service;
169 }
170
171 } // 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