| OLD | NEW |
| 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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 static const char *kStateProperty = "State"; | 21 static const char *kStateProperty = "State"; |
| 22 | 22 |
| 23 // Flimflam on-the-wire State values | 23 // Flimflam on-the-wire State values |
| 24 static const char *kFlimflamStateOffline = "offline"; | 24 static const char *kFlimflamStateOffline = "offline"; |
| 25 static const char *kFlimflamStateConnected = "connected"; | 25 static const char *kFlimflamStateConnected = "connected"; |
| 26 static const char *kFlimflamStateOnline = "online"; | 26 static const char *kFlimflamStateOnline = "online"; |
| 27 | 27 |
| 28 // Flimflam service types | 28 // Flimflam service types |
| 29 static const char *kTypeCellular = "cellular"; | 29 static const char *kTypeCellular = "cellular"; |
| 30 | 30 |
| 31 // GetFlimflamProperties retry interval |
| 32 static const guint kSecondsPerMinute = 60; |
| 33 static const guint kGetFlimflamPropertiesIntervalSeconds = |
| 34 1 * kSecondsPerMinute; |
| 35 |
| 31 ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT | 36 ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT |
| 32 : DBus::ObjectProxy(connection, kFlimflamManagerPath, | 37 : DBus::ObjectProxy(connection, kFlimflamManagerPath, |
| 33 kFlimflamManagerName), | 38 kFlimflamManagerName), |
| 34 connection_(connection), cashew_server_(NULL), | 39 connection_(connection), cashew_server_(NULL), |
| 35 default_technology_(Service::kTypeUnknown), | 40 default_technology_(Service::kTypeUnknown), |
| 36 default_cellular_service_(NULL), | 41 default_cellular_service_(NULL), |
| 37 connectivity_state_(kConnectivityStateUnknown) { | 42 connectivity_state_(kConnectivityStateUnknown), |
| 38 // init our state with a GetProperties() call to Flimflam | 43 get_properties_source_id_(0), retrying_get_properties_(false) { |
| 39 // we'll update this state by monitoring PropertyChanged signals | 44 // schedule a GetProperties() call to Flimflam to init our state |
| 40 GetFlimflamProperties(); | 45 // we'll keep trying periodically until we succeed |
| 46 // we'll subsequently update this state by monitoring PropertyChanged signals |
| 47 get_properties_source_id_ = |
| 48 g_idle_add(StaticGetFlimflamPropertiesCallback, this); |
| 49 if (get_properties_source_id_ == 0) { |
| 50 LOG(ERROR) << "ctor: g_idle_add failed"; |
| 51 } |
| 41 } | 52 } |
| 42 | 53 |
| 43 ServiceManager::~ServiceManager() { | 54 ServiceManager::~ServiceManager() { |
| 44 ClearDefaultCellularService(); | 55 ClearDefaultCellularService(); |
| 45 DeleteServices(&services_); | 56 DeleteServices(&services_); |
| 57 if (get_properties_source_id_ != 0 && |
| 58 !g_source_remove(get_properties_source_id_)) { |
| 59 DLOG(WARNING) << "dtor: g_source_remove failed"; |
| 60 } |
| 46 } | 61 } |
| 47 | 62 |
| 48 const Service* ServiceManager::GetService(const std::string& service_path) | 63 const Service* ServiceManager::GetService(const std::string& service_path) |
| 49 const { | 64 const { |
| 50 ServiceMap::const_iterator it = services_.find(service_path); | 65 ServiceMap::const_iterator it = services_.find(service_path); |
| 51 if (it == services_.end()) { | 66 if (it == services_.end()) { |
| 52 return NULL; | 67 return NULL; |
| 53 } | 68 } |
| 54 DCHECK(it->second != NULL); | 69 DCHECK(it->second != NULL); |
| 55 return static_cast<const Service *>(it->second); | 70 return static_cast<const Service *>(it->second); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 144 |
| 130 void ServiceManager::EmitDataPlansUpdate(const Service& service) { | 145 void ServiceManager::EmitDataPlansUpdate(const Service& service) { |
| 131 DLOG(INFO) << "EmitDataPlansUpdate: service = " << service.GetPath(); | 146 DLOG(INFO) << "EmitDataPlansUpdate: service = " << service.GetPath(); |
| 132 if (cashew_server_ == NULL) { | 147 if (cashew_server_ == NULL) { |
| 133 DLOG(WARNING) << "EmitDataPlansUpdate: no Cashew server"; | 148 DLOG(WARNING) << "EmitDataPlansUpdate: no Cashew server"; |
| 134 return; | 149 return; |
| 135 } | 150 } |
| 136 cashew_server_->EmitDataPlansUpdate(service); | 151 cashew_server_->EmitDataPlansUpdate(service); |
| 137 } | 152 } |
| 138 | 153 |
| 154 // glib integration interface |
| 155 |
| 156 guint ServiceManager::GetGetPropertiesSourceId() const { |
| 157 return get_properties_source_id_; |
| 158 } |
| 159 |
| 160 void ServiceManager::SetGetPropertiesSourceId(guint source_id) { |
| 161 get_properties_source_id_ = source_id; |
| 162 } |
| 163 |
| 164 bool ServiceManager::RetryingGetProperties() const { |
| 165 return retrying_get_properties_; |
| 166 } |
| 167 |
| 168 void ServiceManager::OnRetryingGetProperties(bool retrying) { |
| 169 retrying_get_properties_ = retrying; |
| 170 } |
| 171 |
| 139 // Private methods | 172 // Private methods |
| 140 | 173 |
| 141 void ServiceManager::DeleteServices(ServiceMap *service_map) { | 174 void ServiceManager::DeleteServices(ServiceMap *service_map) { |
| 142 DCHECK(service_map != NULL); | 175 DCHECK(service_map != NULL); |
| 143 while (!service_map->empty()) { | 176 while (!service_map->empty()) { |
| 144 const std::string& path = | 177 const std::string& path = |
| 145 static_cast<std::string>(service_map->begin()->first); | 178 static_cast<std::string>(service_map->begin()->first); |
| 146 DLOG(INFO) << "DeleteServices: deleting service: " << path; | 179 DLOG(INFO) << "DeleteServices: deleting service: " << path; |
| 147 Service *service = static_cast<Service *>(service_map->begin()->second); | 180 Service *service = static_cast<Service *>(service_map->begin()->second); |
| 148 DCHECK(service != NULL); | 181 DCHECK(service != NULL); |
| 149 DCHECK(service != default_cellular_service_); | 182 DCHECK(service != default_cellular_service_); |
| 150 DCHECK(*service_map == services_ || GetService(service->GetPath()) == NULL); | 183 DCHECK(*service_map == services_ || GetService(service->GetPath()) == NULL); |
| 151 delete service; | 184 delete service; |
| 152 service_map->erase(service_map->begin()); | 185 service_map->erase(service_map->begin()); |
| 153 } | 186 } |
| 154 } | 187 } |
| 155 | 188 |
| 156 void ServiceManager::GetFlimflamProperties() { | 189 // static |
| 190 gboolean ServiceManager::StaticGetFlimflamPropertiesCallback(gpointer data) { |
| 191 ServiceManager *service_manager = reinterpret_cast<ServiceManager*>(data); |
| 192 CHECK_NOTNULL(service_manager); |
| 193 DCHECK_NE(service_manager->GetGetPropertiesSourceId(), 0); |
| 194 if (!service_manager->GetFlimflamProperties()) { |
| 195 // call failed, so try again later |
| 196 DLOG(WARNING) << "StaticGetFlimflamPropertiesCallback: " |
| 197 << "GetFlimflamProperties failed, will retry in " |
| 198 << kGetFlimflamPropertiesIntervalSeconds << " secs"; |
| 199 // if we've arrived here from our first g_idle_add call, set up a timer |
| 200 if (!service_manager->RetryingGetProperties()) { |
| 201 guint source_id = |
| 202 g_timeout_add_seconds(kGetFlimflamPropertiesIntervalSeconds, |
| 203 StaticGetFlimflamPropertiesCallback, |
| 204 service_manager); |
| 205 service_manager->SetGetPropertiesSourceId(source_id); |
| 206 if (source_id == 0) { |
| 207 LOG(ERROR) << "StaticGetFlimflamPropertiesCallback: " |
| 208 << "g_timeout_add_seconds failed"; |
| 209 return FALSE; // get rid of old glib source and give up |
| 210 } |
| 211 service_manager->OnRetryingGetProperties(true); |
| 212 // get rid of our old glib source, but our new timer will call us |
| 213 return FALSE; |
| 214 } |
| 215 // otherwise, our timer is already set up |
| 216 // return TRUE to indicate that we want to be called again later |
| 217 return TRUE; |
| 218 } |
| 219 service_manager->SetGetPropertiesSourceId(0); |
| 220 service_manager->OnRetryingGetProperties(false); |
| 221 return FALSE; // we succeeded, so don't repeat |
| 222 } |
| 223 |
| 224 bool ServiceManager::GetFlimflamProperties() { |
| 157 DLOG(INFO) << "GetFlimflamProperties"; | 225 DLOG(INFO) << "GetFlimflamProperties"; |
| 158 PropertyMap properties; | 226 PropertyMap properties; |
| 159 // dbus-c++ throws exceptions | 227 // dbus-c++ throws exceptions |
| 160 // invoke the "Existing Non-conformant Code" clause of the style guide and | 228 // invoke the "Existing Non-conformant Code" clause of the style guide and |
| 161 // isolate the rest of the system from this | 229 // isolate the rest of the system from this |
| 162 try { | 230 try { |
| 163 // TODO(vlaviano): make this call asynchronous | 231 // TODO(vlaviano): make this call asynchronous |
| 164 properties = GetProperties(); | 232 properties = GetProperties(); |
| 165 } catch (DBus::Error& error) { // NOLINT | 233 } catch (DBus::Error& error) { // NOLINT |
| 166 LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception: " | 234 LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception: " |
| 167 << error.name() << ": " << error.message(); | 235 << error.name() << ": " << error.message(); |
| 168 // TODO(vlaviano): schedule another attempt later | 236 return false; |
| 169 return; | |
| 170 } catch (...) { // NOLINT | 237 } catch (...) { // NOLINT |
| 171 LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception"; | 238 LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception"; |
| 172 // TODO(vlaviano): schedule another attempt later | 239 return false; |
| 173 return; | |
| 174 } | 240 } |
| 175 DLOG(INFO) << "GetFlimflamProperties: Received " << properties.size() | 241 DLOG(INFO) << "GetFlimflamProperties: Received " << properties.size() |
| 176 << " properties"; | 242 << " properties"; |
| 177 | 243 |
| 178 // grab the properties in which we're interested | 244 // grab the properties in which we're interested |
| 179 PropertyMap::const_iterator it = properties.find(kDefaultTechnologyProperty); | 245 PropertyMap::const_iterator it = properties.find(kDefaultTechnologyProperty); |
| 180 if (it != properties.end()) { | 246 if (it != properties.end()) { |
| 181 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); | 247 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 182 OnDefaultTechnologyUpdate(value.reader().get_string()); | 248 OnDefaultTechnologyUpdate(value.reader().get_string()); |
| 183 } else { | 249 } else { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 194 } else { | 260 } else { |
| 195 DLOG(WARNING) << "GetFlimflamProperties: no Services property"; | 261 DLOG(WARNING) << "GetFlimflamProperties: no Services property"; |
| 196 } | 262 } |
| 197 it = properties.find(kStateProperty); | 263 it = properties.find(kStateProperty); |
| 198 if (it != properties.end()) { | 264 if (it != properties.end()) { |
| 199 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); | 265 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 200 StateChanged(value.reader().get_string()); | 266 StateChanged(value.reader().get_string()); |
| 201 } else { | 267 } else { |
| 202 DLOG(WARNING) << "GetFlimflamProperties: no State property"; | 268 DLOG(WARNING) << "GetFlimflamProperties: no State property"; |
| 203 } | 269 } |
| 270 return true; |
| 204 } | 271 } |
| 205 | 272 |
| 206 void ServiceManager::OnDefaultTechnologyUpdate( | 273 void ServiceManager::OnDefaultTechnologyUpdate( |
| 207 const std::string& default_technology) { | 274 const std::string& default_technology) { |
| 208 DLOG(INFO) << "OnDefaultTechnologyUpdate: default technology = " | 275 DLOG(INFO) << "OnDefaultTechnologyUpdate: default technology = " |
| 209 << default_technology; | 276 << default_technology; |
| 210 default_technology_ = Service::TypeFromString(default_technology); | 277 default_technology_ = Service::TypeFromString(default_technology); |
| 211 if (default_technology_ == Service::kTypeUnknown) { | 278 if (default_technology_ == Service::kTypeUnknown) { |
| 212 LOG(WARNING) << "OnDefaultTechnologyUpdate: unknown default technology: " | 279 LOG(WARNING) << "OnDefaultTechnologyUpdate: unknown default technology: " |
| 213 << default_technology; | 280 << default_technology; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 // notify our child services | 432 // notify our child services |
| 366 ServiceMap::iterator it; | 433 ServiceMap::iterator it; |
| 367 for (it = services_.begin(); it != services_.end(); ++it) { | 434 for (it = services_.begin(); it != services_.end(); ++it) { |
| 368 Service *service = static_cast<Service*>(it->second); | 435 Service *service = static_cast<Service*>(it->second); |
| 369 DCHECK(service != NULL); | 436 DCHECK(service != NULL); |
| 370 service->OnFlimflamOffline(); | 437 service->OnFlimflamOffline(); |
| 371 } | 438 } |
| 372 } | 439 } |
| 373 | 440 |
| 374 } // namespace cashew | 441 } // namespace cashew |
| OLD | NEW |