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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/service_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/service_manager.cc
diff --git a/src/service_manager.cc b/src/service_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..39f3c6d1d283d77c59bf4dea6823ea26cbe42e7d
--- /dev/null
+++ b/src/service_manager.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/service_manager.h"
+
+#include <glog/logging.h>
+
+#include "src/service.h"
+
+namespace cashew {
+
+// Flimflam D-Bus indentifiers
+static const char* kFlimflamManagerName = "org.chromium.flimflam";
+static const char* kFlimflamManagerPath = "/";
+
+// Flimflam property names
+static const char* kServicesProperty = "Services";
+
+// Flimflam service types
+static const char* kTypeCellular = "cellular";
+
+ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT
+ : DBus::ObjectProxy(connection, kFlimflamManagerPath,
+ kFlimflamManagerName),
+ connection_(connection) {
+ // init our state with a GetProperties() call to Flimflam
+ // we'll update this state by monitoring PropertyChanged signals
+ GetFlimflamServices();
+}
+
+ServiceManager::~ServiceManager() {
+ DeleteServices(&services_);
+}
+
+const Service* ServiceManager::GetService(const std::string& service_path)
+ const {
+ ServiceMap::const_iterator it = services_.find(service_path);
+ if (it == services_.end()) {
+ return NULL;
+ }
+ DCHECK(it->second != NULL);
+ return static_cast<const Service *>(it->second);
+}
+
+// Flimflam Manager D-Bus Proxy methods
+
+void ServiceManager::PropertyChanged(const std::string& property_name,
+ const DBus::Variant& new_value) {
+ DLOG(INFO) << "PropertyChanged: property_name = " << property_name;
+
+ // we only care about Services changes
+ if (property_name.compare(kServicesProperty)) {
+ return;
+ }
+
+ // interpret new_value as a vector of service paths
+ ServicePathList paths;
+ DBus::MessageIter reader = new_value.reader();
+ reader >> paths;
+
+ OnServicesUpdate(paths);
+}
+
+void ServiceManager::StateChanged(const std::string& new_state) {
+ DLOG(INFO) << "StateChanged: new_state = " << new_state;
+ // TODO(vlaviano): switch on state and call private onFlimflamOffline(),
+ // onFlimflamOnline() hooks. If we care.
+}
+
+// Private methods
+
+void ServiceManager::DeleteServices(ServiceMap *service_map) {
+ DCHECK(service_map != NULL);
+ while (!service_map->empty()) {
+ const std::string& path =
+ static_cast<std::string>(service_map->begin()->first);
+ DLOG(INFO) << "DeleteServices: deleting service: " << path;
+ Service *service = static_cast<Service *>(service_map->begin()->second);
+ delete service;
+ service_map->erase(service_map->begin());
+ }
+}
+
+void ServiceManager::GetFlimflamServices() {
+ DLOG(INFO) << "GetFlimflamServices";
+ PropertyMap properties;
+ // dbus-c++ throws exceptions
+ // invoke the "Existing Non-conformant Code" clause of the style guide and
+ // isolate the rest of the system from this
+ try {
+ // TODO(vlaviano): make this call asynchronous
+ properties = GetProperties();
+ } catch (DBus::Error& error) { // NOLINT
+ LOG(WARNING) << "GetFlimflamServices: GetProperties() -> Exception: "
+ << error.name() << ": " << error.message();
+ // TODO(vlaviano): schedule another attempt later
+ return;
+ } catch (...) { // NOLINT
+ LOG(WARNING) << "GetFlimflamServices: GetProperties() -> Exception";
+ // TODO(vlaviano): schedule another attempt later
+ return;
+ }
+
+ // grab Services property from result
+ PropertyMap::const_iterator it = properties.find(kServicesProperty);
+ if (it == properties.end()) {
+ DLOG(WARNING) << "GetFlimflamServices: no Services property";
+ return;
+ }
+ DBus::Variant value = static_cast<DBus::Variant>(it->second);
+
+ // interpret value as vector of service paths
+ ServicePathList paths;
+ DBus::MessageIter reader = value.reader();
+ reader >> paths;
+
+ OnServicesUpdate(paths);
+}
+
+void ServiceManager::OnServicesUpdate(const ServicePathList& paths) {
+ // Remember old set of services. This is the baseline from which we will
+ // determine what has changed.
+ ServiceMap old_services = services_;
+ services_.clear();
+
+ // Flimflam service types are embedded in their path names, so we can use
+ // the pattern "/cellular_" to decide which paths are cellular services.
+ static const std::string cellular_pattern = std::string("/") + kTypeCellular
+ + "_";
+
+ // Walk paths in this update and see if they're new to us
+ DLOG(INFO) << "OnServicesUpdate: " << paths.size() << " service paths";
+ ServicePathList::const_iterator it;
+ for (it = paths.begin(); it != paths.end(); ++it) {
+ const DBus::Path& path = *it;
+
+ // We only care about cellular services
+ if (path.find(cellular_pattern) == std::string::npos) {
+ continue;
+ }
+
+ ServiceMap::iterator old_it = old_services.find(path);
+ if (old_it != old_services.end()) {
+ // service is old: move it from old_services to services_
+ Service *service = static_cast<Service *>(old_it->second);
+ DCHECK(service != NULL);
+ old_services.erase(old_it);
+ services_[path] = service;
+ } else {
+ // service is new: create a Service obj for it and add it to services_
+ OnNewService(path);
+ }
+ }
+
+ // services left in old_services failed to appear in the update: delete them
+ DeleteServices(&old_services);
+}
+
+void ServiceManager::OnNewService(const DBus::Path& path) {
+ DLOG(INFO) << "OnNewService: " << path;
+ DCHECK(GetService(path) == NULL);
+ Service *service = new(std::nothrow) Service(connection_, path);
+ if (service == NULL) {
+ LOG(ERROR) << "OnNewService: couldn't create service for " << path;
+ return;
+ }
+ services_[path] = service;
+}
+
+} // namespace cashew
« 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