| 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.h" | 5 #include "src/service.h" |
| 6 | 6 |
| 7 #include <glog/logging.h> | 7 #include <glog/logging.h> |
| 8 | 8 |
| 9 #include "src/data_plan_provider.h" | 9 #include "src/data_plan_provider.h" |
| 10 #include "src/device.h" | 10 #include "src/device.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 static const char *kCrosUsageVersionProperty = "version"; | 44 static const char *kCrosUsageVersionProperty = "version"; |
| 45 static const char *kCrosUsageStatusProperty = "status"; | 45 static const char *kCrosUsageStatusProperty = "status"; |
| 46 static const char *kCrosUsageRestrictedProperty = "restricted"; | 46 static const char *kCrosUsageRestrictedProperty = "restricted"; |
| 47 static const char *kCrosUsagePlansProperty = "plans"; | 47 static const char *kCrosUsagePlansProperty = "plans"; |
| 48 | 48 |
| 49 // Chromium OS Usage API version values | 49 // Chromium OS Usage API version values |
| 50 static const int kCrosUsageVersionMinSupported = 1; | 50 static const int kCrosUsageVersionMinSupported = 1; |
| 51 static const int kCrosUsageVersionMaxSupported = 1; | 51 static const int kCrosUsageVersionMaxSupported = 1; |
| 52 | 52 |
| 53 // Chromium OS Usage API status values | 53 // Chromium OS Usage API status values |
| 54 // NOTE: add new values to IsValidCrosUsageStatus below also |
| 54 static const char *kCrosUsageStatusOk = "OK"; | 55 static const char *kCrosUsageStatusOk = "OK"; |
| 55 static const char *kCrosUsageStatusError = "ERROR"; | 56 static const char *kCrosUsageStatusError = "ERROR"; |
| 56 static const char *kCrosUsageStatusMalformedRequest = "MALFORMED REQUEST"; | 57 static const char *kCrosUsageStatusMalformedRequest = "MALFORMED REQUEST"; |
| 57 static const char *kCrosUsageStatusInternalError = "INTERNAL ERROR"; | 58 static const char *kCrosUsageStatusInternalError = "INTERNAL ERROR"; |
| 58 static const char *kCrosUsageStatusServiceUnavailable = "SERVICE UNAVAILABLE"; | 59 static const char *kCrosUsageStatusServiceUnavailable = "SERVICE UNAVAILABLE"; |
| 59 static const char *kCrosUsageStatusRequestRefused = "REQUEST REFUSED"; | 60 static const char *kCrosUsageStatusRequestRefused = "REQUEST REFUSED"; |
| 60 static const char *kCrosUsageStatusUnknownDevice = "UNKNOWN DEVICE"; | 61 static const char *kCrosUsageStatusUnknownDevice = "UNKNOWN DEVICE"; |
| 61 | 62 |
| 62 Service::Service(ServiceManager * const parent, | 63 Service::Service(ServiceManager * const parent, |
| 63 DBus::Connection& connection, // NOLINT | 64 DBus::Connection& connection, // NOLINT |
| 64 const DBus::Path& path) | 65 const DBus::Path& path) |
| 65 : DBus::ObjectProxy(connection, path, kFlimflamServiceName), | 66 : DBus::ObjectProxy(connection, path, kFlimflamServiceName), |
| 66 parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path), | 67 parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path), |
| 67 state_(kStateUnknown), type_(kTypeUnknown), device_(NULL), | 68 state_(kStateUnknown), type_(kTypeUnknown), device_(NULL), |
| 68 provider_(NULL), request_in_progress_(false), | 69 provider_(NULL), request_in_progress_(false), |
| 69 update_timeout_source_(NULL), policy_(NULL) { | 70 update_timeout_source_(NULL), policy_(NULL), |
| 71 is_default_service_(false) { |
| 70 // init our state with a GetProperties() call to our Flimflam service path | 72 // init our state with a GetProperties() call to our Flimflam service path |
| 71 // we'll update this state by monitoring PropertyChanged signals | 73 // we'll update this state by monitoring PropertyChanged signals |
| 72 GetServiceProperties(); | 74 GetServiceProperties(); |
| 73 } | 75 } |
| 74 | 76 |
| 75 Service::~Service() { | 77 Service::~Service() { |
| 76 DeleteCarrierState(); | 78 DeleteCarrierState(); |
| 77 DeleteDataPlans(&data_plans_); | 79 DeleteDataPlans(&data_plans_); |
| 78 if (device_ != NULL) { | 80 if (device_ != NULL) { |
| 79 DLOG(INFO) << path_ << ": deleting device " << device_->GetPath(); | 81 DLOG(INFO) << path_ << ": deleting device " << device_->GetPath(); |
| 80 delete device_; | 82 delete device_; |
| 81 device_ = NULL; | 83 device_ = NULL; |
| 82 } | 84 } |
| 83 } | 85 } |
| 84 | 86 |
| 85 const DBus::Path& Service::GetPath() const { | 87 const DBus::Path& Service::GetPath() const { |
| 86 return path_; | 88 return path_; |
| 87 } | 89 } |
| 88 | 90 |
| 89 Service::State Service::GetState() const { | 91 Service::State Service::GetState() const { |
| 90 return state_; | 92 return state_; |
| 91 } | 93 } |
| 92 | 94 |
| 93 Service::Type Service::GetType() const { | 95 Service::Type Service::GetType() const { |
| 94 return type_; | 96 return type_; |
| 95 } | 97 } |
| 96 | 98 |
| 99 // static |
| 100 Service::Type Service::TypeFromString(const std::string& type) { |
| 101 if (type == kFlimflamServiceTypeEthernet) { |
| 102 return kTypeEthernet; |
| 103 } |
| 104 if (type == kFlimflamServiceTypeWifi) { |
| 105 return kTypeWifi; |
| 106 } |
| 107 if (type == kFlimflamServiceTypeWimax) { |
| 108 return kTypeWimax; |
| 109 } |
| 110 if (type == kFlimflamServiceTypeBluetooth) { |
| 111 return kTypeBluetooth; |
| 112 } |
| 113 if (type == kFlimflamServiceTypeCellular) { |
| 114 return kTypeCellular; |
| 115 } |
| 116 return kTypeUnknown; |
| 117 } |
| 118 |
| 97 Device* Service::GetDevice() const { | 119 Device* Service::GetDevice() const { |
| 98 return device_; | 120 return device_; |
| 99 } | 121 } |
| 100 | 122 |
| 101 DBusDataPlanList Service::GetDBusDataPlans() const { | 123 DBusDataPlanList Service::GetDBusDataPlans() const { |
| 102 DBusDataPlanList dbus_data_plans; | 124 DBusDataPlanList dbus_data_plans; |
| 103 DataPlanList::const_iterator it; | 125 DataPlanList::const_iterator it; |
| 104 for (it = data_plans_.begin(); it != data_plans_.end(); ++it) { | 126 for (it = data_plans_.begin(); it != data_plans_.end(); ++it) { |
| 105 DataPlan *plan = *it; | 127 DataPlan *plan = *it; |
| 106 DCHECK(plan != NULL); | 128 DCHECK(plan != NULL); |
| 107 dbus_data_plans.push_back(plan->ToDBusFormat()); | 129 dbus_data_plans.push_back(plan->ToDBusFormat()); |
| 108 } | 130 } |
| 109 return dbus_data_plans; | 131 return dbus_data_plans; |
| 110 } | 132 } |
| 111 | 133 |
| 134 bool Service::IsDefaultService() const { |
| 135 if (is_default_service_) { |
| 136 // cross-check with parent's idea of default technology |
| 137 if (parent_->GetDefaultTechnology() != kTypeCellular) { |
| 138 DLOG(WARNING) << path_ << ": IsDefaultService: " |
| 139 << "service manager doesn't think default technology is cellular"; |
| 140 } |
| 141 return true; |
| 142 } |
| 143 return false; |
| 144 } |
| 145 |
| 112 // Flimflam Service D-Bus Proxy methods | 146 // Flimflam Service D-Bus Proxy methods |
| 113 | 147 |
| 114 void Service::PropertyChanged(const std::string& property_name, | 148 void Service::PropertyChanged(const std::string& property_name, |
| 115 const DBus::Variant& new_value) { | 149 const DBus::Variant& new_value) { |
| 116 DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name; | 150 DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name; |
| 117 if (property_name.compare(kFlimflamServiceDeviceProperty) == 0) { | 151 if (property_name == kFlimflamServiceDeviceProperty) { |
| 118 OnDeviceUpdate(new_value.reader().get_path()); | 152 OnDeviceUpdate(new_value.reader().get_path()); |
| 119 } else if (property_name.compare(kFlimflamServiceStateProperty) == 0) { | 153 } else if (property_name == kFlimflamServiceStateProperty) { |
| 120 OnStateUpdate(new_value.reader().get_string()); | 154 OnStateUpdate(new_value.reader().get_string()); |
| 121 } else if (property_name.compare(kFlimflamServiceTypeProperty) == 0) { | 155 } else if (property_name == kFlimflamServiceTypeProperty) { |
| 122 OnTypeUpdate(new_value.reader().get_string()); | 156 OnTypeUpdate(new_value.reader().get_string()); |
| 123 } else if (property_name.compare(kFlimflamServiceUsageUrlProperty) == 0) { | 157 } else if (property_name == kFlimflamServiceUsageUrlProperty) { |
| 124 OnUsageUrlUpdate(new_value.reader().get_string()); | 158 OnUsageUrlUpdate(new_value.reader().get_string()); |
| 125 } else { | 159 } else { |
| 126 // we don't care about this property | 160 // we don't care about this property |
| 127 } | 161 } |
| 128 } | 162 } |
| 129 | 163 |
| 130 // Device methods | 164 // Device methods |
| 131 | 165 |
| 132 void Service::OnCarrierUpdate(const std::string& carrier) { | 166 void Service::OnCarrierUpdate(const std::string& carrier) { |
| 133 DLOG(INFO) << path_ << ": OnCarrierUpdate: carrier = " << carrier; | 167 DLOG(INFO) << path_ << ": OnCarrierUpdate: carrier = " << carrier; |
| 134 // NOTE: device_ can be NULL here because we may still be in Device ctor | 168 // NOTE: device_ can be NULL here because we may still be in Device ctor |
| 135 DCHECK(device_ == NULL || carrier.compare(device_->GetCarrier()) == 0); | 169 DCHECK(device_ == NULL || carrier == device_->GetCarrier()); |
| 136 | 170 |
| 137 // get rid of state associated with old carrier | 171 // get rid of state associated with old carrier |
| 138 if (provider_ != NULL) { | 172 if (provider_ != NULL) { |
| 139 DCHECK(carrier.compare(provider_->GetCarrier())); | 173 DCHECK(carrier != provider_->GetCarrier()); |
| 140 } | 174 } |
| 141 DeleteCarrierState(); | 175 DeleteCarrierState(); |
| 142 | 176 |
| 143 // if we don't have new carrier info, we can't do anything now | 177 // if we don't have new carrier info, we can't do anything now |
| 144 if (carrier.compare(Device::kCarrierUnknown) == 0) { | 178 if (carrier == Device::kCarrierUnknown) { |
| 145 return; | 179 return; |
| 146 } | 180 } |
| 147 | 181 |
| 148 // create state for new carrier | 182 // create state for new carrier |
| 149 DLOG(INFO) << path_ << ": OnCarrierUpdate: creating data plan provider"; | 183 DLOG(INFO) << path_ << ": OnCarrierUpdate: creating data plan provider"; |
| 150 provider_ = new(std::nothrow) DataPlanProvider(carrier); | 184 provider_ = new(std::nothrow) DataPlanProvider(carrier); |
| 151 if (provider_ == NULL) { | 185 if (provider_ == NULL) { |
| 152 LOG(ERROR) << path_ | 186 LOG(ERROR) << path_ |
| 153 << ": OnCarrierUpdate: could not create data plan provider"; | 187 << ": OnCarrierUpdate: could not create data plan provider"; |
| 154 return; | 188 return; |
| 155 } | 189 } |
| 156 provider_->SetDelegate(this); | 190 provider_->SetDelegate(this); |
| 157 DLOG(INFO) << path_ << ": OnCarrierUpdate: getting policy for " << carrier; | 191 DLOG(INFO) << path_ << ": OnCarrierUpdate: getting policy for " << carrier; |
| 158 policy_ = Policy::GetPolicy(carrier); | 192 policy_ = Policy::GetPolicy(carrier); |
| 159 if (policy_ == NULL) { | 193 if (policy_ == NULL) { |
| 160 LOG(ERROR) << path_ << ": OnCarrierUpdate: could not get policy for " | 194 LOG(ERROR) << path_ << ": OnCarrierUpdate: could not get policy for " |
| 161 << carrier; | 195 << carrier; |
| 162 DeleteCarrierState(); | 196 DeleteCarrierState(); |
| 163 return; | 197 return; |
| 164 } | 198 } |
| 165 | 199 |
| 166 // if we already have usage url, set new provider in motion | 200 // if we already have usage url, set new provider in motion |
| 167 if (!usage_url_.empty()) { | 201 if (!usage_url_.empty()) { |
| 168 provider_->SetUsageUrl(usage_url_); | 202 provider_->SetUsageUrl(usage_url_); |
| 169 RequestUsageUpdate(); | 203 ReconsiderSendingUsageRequests(); |
| 170 CreateUpdateTimer(); | |
| 171 } else { | 204 } else { |
| 172 // we'll do this later in OnUsageUrlUpdate | 205 // we'll do this later in OnUsageUrlUpdate |
| 173 } | 206 } |
| 174 } | 207 } |
| 175 | 208 |
| 176 // DataPlanProviderDelegate methods | 209 // DataPlanProviderDelegate methods |
| 177 | 210 |
| 178 void Service::OnRequestComplete(const DataPlanProvider *provider, | 211 void Service::OnRequestComplete(const DataPlanProvider *provider, |
| 179 bool successful, | 212 bool successful, |
| 180 const Value *parsed_usage_update) { | 213 const Value *parsed_usage_update) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 DLOG(INFO) << path_ << ": OnRequestComplete: sending update"; | 313 DLOG(INFO) << path_ << ": OnRequestComplete: sending update"; |
| 281 parent_->EmitDataPlansUpdate(*this); | 314 parent_->EmitDataPlansUpdate(*this); |
| 282 } else { | 315 } else { |
| 283 DLOG(INFO) << path_ << ": OnRequestComplete: not sending update"; | 316 DLOG(INFO) << path_ << ": OnRequestComplete: not sending update"; |
| 284 } | 317 } |
| 285 | 318 |
| 286 DLOG(INFO) << path_ << ": OnRequestComplete: deleting old data plans"; | 319 DLOG(INFO) << path_ << ": OnRequestComplete: deleting old data plans"; |
| 287 DeleteDataPlans(&old_plans); | 320 DeleteDataPlans(&old_plans); |
| 288 } | 321 } |
| 289 | 322 |
| 323 // Service Manager methods |
| 324 |
| 325 void Service::OnDefaultServiceUpdate(bool is_default_service) { |
| 326 DCHECK(is_default_service_ == !is_default_service); |
| 327 DLOG(INFO) << path_ << ": OnDefaultServiceUpdate: is_default_service = " |
| 328 << is_default_service; |
| 329 is_default_service_ = is_default_service; |
| 330 if (is_default_service_) { |
| 331 // we just became the default service |
| 332 // cross-check with parent's idea of default technology |
| 333 if (parent_->GetDefaultTechnology() != kTypeCellular) { |
| 334 DLOG(WARNING) << path_ << ": OnDefaultServiceUpdate: " |
| 335 << "service manager doesn't think default technology is cellular"; |
| 336 } |
| 337 } |
| 338 ReconsiderSendingUsageRequests(); |
| 339 } |
| 340 |
| 341 void Service::OnFlimflamOnline() { |
| 342 DLOG(INFO) << path_ << ": OnFlimflamOnline"; |
| 343 ReconsiderSendingUsageRequests(); |
| 344 } |
| 345 |
| 346 void Service::OnFlimflamOffline() { |
| 347 DLOG(INFO) << path_ << ": OnFlimflamOffline"; |
| 348 ReconsiderSendingUsageRequests(); |
| 349 } |
| 350 |
| 290 // Private methods | 351 // Private methods |
| 291 | 352 |
| 292 Service::State Service::StateFromString(const std::string& state) const { | 353 Service::State Service::StateFromString(const std::string& state) const { |
| 293 if (state.compare(kFlimflamServiceStateIdle) == 0) { | 354 if (state == kFlimflamServiceStateIdle) { |
| 294 return kStateIdle; | 355 return kStateIdle; |
| 295 } | 356 } |
| 296 if (state.compare(kFlimflamServiceStateCarrier) == 0) { | 357 if (state == kFlimflamServiceStateCarrier) { |
| 297 return kStateCarrier; | 358 return kStateCarrier; |
| 298 } | 359 } |
| 299 if (state.compare(kFlimflamServiceStateAssociation) == 0) { | 360 if (state == kFlimflamServiceStateAssociation) { |
| 300 return kStateAssociation; | 361 return kStateAssociation; |
| 301 } | 362 } |
| 302 if (state.compare(kFlimflamServiceStateConfiguration) == 0) { | 363 if (state == kFlimflamServiceStateConfiguration) { |
| 303 return kStateConfiguration; | 364 return kStateConfiguration; |
| 304 } | 365 } |
| 305 if (state.compare(kFlimflamServiceStateReady) == 0) { | 366 if (state == kFlimflamServiceStateReady) { |
| 306 return kStateReady; | 367 return kStateReady; |
| 307 } | 368 } |
| 308 if (state.compare(kFlimflamServiceStateDisconnect) == 0) { | 369 if (state == kFlimflamServiceStateDisconnect) { |
| 309 return kStateDisconnect; | 370 return kStateDisconnect; |
| 310 } | 371 } |
| 311 if (state.compare(kFlimflamServiceStateFailure) == 0) { | 372 if (state == kFlimflamServiceStateFailure) { |
| 312 return kStateFailure; | 373 return kStateFailure; |
| 313 } | 374 } |
| 314 if (state.compare(kFlimflamServiceStateActivationFailure) == 0) { | 375 if (state == kFlimflamServiceStateActivationFailure) { |
| 315 return kStateActivationFailure; | 376 return kStateActivationFailure; |
| 316 } | 377 } |
| 317 return kStateUnknown; | 378 return kStateUnknown; |
| 318 } | 379 } |
| 319 | 380 |
| 320 Service::Type Service::TypeFromString(const std::string& type) const { | |
| 321 if (type.compare(kFlimflamServiceTypeEthernet) == 0) { | |
| 322 return kTypeEthernet; | |
| 323 } | |
| 324 if (type.compare(kFlimflamServiceTypeWifi) == 0) { | |
| 325 return kTypeWifi; | |
| 326 } | |
| 327 if (type.compare(kFlimflamServiceTypeWimax) == 0) { | |
| 328 return kTypeWimax; | |
| 329 } | |
| 330 if (type.compare(kFlimflamServiceTypeBluetooth) == 0) { | |
| 331 return kTypeBluetooth; | |
| 332 } | |
| 333 if (type.compare(kFlimflamServiceTypeCellular) == 0) { | |
| 334 return kTypeCellular; | |
| 335 } | |
| 336 return kTypeUnknown; | |
| 337 } | |
| 338 | |
| 339 void Service::OnDeviceUpdate(const DBus::Path& device_path) { | 381 void Service::OnDeviceUpdate(const DBus::Path& device_path) { |
| 340 DLOG(INFO) << path_ << ": OnDeviceUpdate: device_path = " << device_path; | 382 DLOG(INFO) << path_ << ": OnDeviceUpdate: device_path = " << device_path; |
| 341 | 383 |
| 342 // if there's an existing device with a non-matching path: destroy it and | 384 // if there's an existing device with a non-matching path: destroy it and |
| 343 // fall through to make a new one below. | 385 // fall through to make a new one below. |
| 344 if (device_ != NULL && device_->GetPath().compare(device_path)) { | 386 if (device_ != NULL && device_->GetPath() != device_path) { |
| 345 LOG(WARNING) << path_ << ": OnDeviceUpdate: device path changed from " | 387 LOG(WARNING) << path_ << ": OnDeviceUpdate: device path changed from " |
| 346 << device_->GetPath() << " to " << device_path; | 388 << device_->GetPath() << " to " << device_path; |
| 347 delete device_; | 389 delete device_; |
| 348 device_ = NULL; | 390 device_ = NULL; |
| 349 } | 391 } |
| 350 | 392 |
| 351 // if there's an existing device with matching path: all is well | 393 // if there's an existing device with matching path: all is well |
| 352 if (device_ != NULL) { | 394 if (device_ != NULL) { |
| 353 return; | 395 return; |
| 354 } | 396 } |
| 355 | 397 |
| 356 // if there's no existing device: make one | 398 // if there's no existing device: make one |
| 357 device_ = new(std::nothrow) Device(this, connection_, device_path); | 399 device_ = new(std::nothrow) Device(this, connection_, device_path); |
| 358 if (device_ == NULL) { | 400 if (device_ == NULL) { |
| 359 LOG(ERROR) << path_ << ": OnDeviceUpdate: couldn't create device for " | 401 LOG(ERROR) << path_ << ": OnDeviceUpdate: couldn't create device for " |
| 360 << device_path; | 402 << device_path; |
| 361 return; | 403 return; |
| 362 } | 404 } |
| 363 DLOG(INFO) << path_ << ": OnDeviceUpdate: created device for " | 405 DLOG(INFO) << path_ << ": OnDeviceUpdate: created device for " |
| 364 << device_path; | 406 << device_path; |
| 365 } | 407 } |
| 366 | 408 |
| 367 void Service::OnStateUpdate(const std::string& state) { | 409 void Service::OnStateUpdate(const std::string& state) { |
| 368 DLOG(INFO) << path_ << ": OnStateUpdate: state = " << state; | 410 DLOG(INFO) << path_ << ": OnStateUpdate: state = " << state; |
| 411 Service::State old_state = state_; |
| 369 state_ = StateFromString(state); | 412 state_ = StateFromString(state); |
| 370 // TODO(vlaviano): react to state changes | 413 if (old_state != kStateReady && IsConnected()) { |
| 371 // note that ready does not necessarily mean that we're the default route | 414 OnConnected(); |
| 415 } else if (old_state == kStateReady && !IsConnected()) { |
| 416 OnDisconnected(); |
| 417 } |
| 372 } | 418 } |
| 373 | 419 |
| 374 void Service::OnTypeUpdate(const std::string& type) { | 420 void Service::OnTypeUpdate(const std::string& type) { |
| 375 DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type; | 421 DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type; |
| 376 type_ = TypeFromString(type); | 422 type_ = TypeFromString(type); |
| 377 if (type_ != kTypeCellular) { | 423 if (type_ != kTypeCellular) { |
| 378 LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!"; | 424 LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!"; |
| 379 } | 425 } |
| 380 } | 426 } |
| 381 | 427 |
| 382 void Service::OnUsageUrlUpdate(const std::string& usage_url) { | 428 void Service::OnUsageUrlUpdate(const std::string& usage_url) { |
| 383 DLOG(INFO) << path_ << ": OnUsageUrlUpdate: url = " << usage_url; | 429 DLOG(INFO) << path_ << ": OnUsageUrlUpdate: url = " << usage_url; |
| 384 if (usage_url.compare(usage_url_) == 0) { | 430 if (usage_url == usage_url_) { |
| 385 return; | 431 return; |
| 386 } | 432 } |
| 387 usage_url_ = usage_url; | 433 usage_url_ = usage_url; |
| 388 if (provider_ != NULL) { | 434 if (provider_ != NULL) { |
| 389 DCHECK(usage_url.compare(provider_->GetUsageUrl())); | 435 DCHECK(usage_url != provider_->GetUsageUrl()); |
| 390 DestroyUpdateTimer(); | 436 StopSendingUsageRequests(); |
| 391 CancelPendingRequests(); | |
| 392 provider_->SetUsageUrl(usage_url); | 437 provider_->SetUsageUrl(usage_url); |
| 393 RequestUsageUpdate(); | 438 ReconsiderSendingUsageRequests(); |
| 394 CreateUpdateTimer(); | |
| 395 } | 439 } |
| 396 } | 440 } |
| 397 | 441 |
| 398 void Service::GetServiceProperties() { | 442 void Service::GetServiceProperties() { |
| 399 DLOG(INFO) << path_ << ": GetServiceProperties"; | 443 DLOG(INFO) << path_ << ": GetServiceProperties"; |
| 400 PropertyMap properties; | 444 PropertyMap properties; |
| 401 // dbus-c++ throws exceptions | 445 // dbus-c++ throws exceptions |
| 402 // invoke the "Existing Non-conformant Code" clause of the style guide and | 446 // invoke the "Existing Non-conformant Code" clause of the style guide and |
| 403 // isolate the rest of the system from this | 447 // isolate the rest of the system from this |
| 404 try { | 448 try { |
| 405 // TODO(vlaviano): make this call asynchronous | 449 // TODO(vlaviano): make this call asynchronous |
| 406 properties = GetProperties(); | 450 properties = GetProperties(); |
| 407 } catch (DBus::Error& error) { // NOLINT | 451 } catch (DBus::Error& error) { // NOLINT |
| 408 LOG(WARNING) << path_ | 452 LOG(WARNING) << path_ |
| 409 << ": GetServiceProperties: GetProperties() -> Exception: " | 453 << ": GetServiceProperties: GetProperties() -> Exception: " |
| 410 << error.name() << ": " << error.message(); | 454 << error.name() << ": " << error.message(); |
| 411 // TODO(vlaviano): schedule another attempt later | 455 // TODO(vlaviano): schedule another attempt later |
| 412 return; | 456 return; |
| 413 } catch (...) { // NOLINT | 457 } catch (...) { // NOLINT |
| 414 LOG(WARNING) << path_ | 458 LOG(WARNING) << path_ |
| 415 << ": GetServiceProperties: GetProperties() -> Exception"; | 459 << ": GetServiceProperties: GetProperties() -> Exception"; |
| 416 // TODO(vlaviano): schedule another attempt later | 460 // TODO(vlaviano): schedule another attempt later |
| 417 return; | 461 return; |
| 418 } | 462 } |
| 419 DLOG(INFO) << "Received " << properties.size() << " properties"; | 463 DLOG(INFO) << path_ << ": GetServiceProperties: Received " |
| 464 << properties.size() << " properties"; |
| 420 | 465 |
| 421 // grab the properties in which we're interested | 466 // grab the properties in which we're interested |
| 422 PropertyMap::const_iterator it; | 467 PropertyMap::const_iterator it; |
| 423 it = properties.find(kFlimflamServiceDeviceProperty); | 468 it = properties.find(kFlimflamServiceDeviceProperty); |
| 424 if (it != properties.end()) { | 469 if (it != properties.end()) { |
| 425 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); | 470 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 426 OnDeviceUpdate(value.reader().get_path()); | 471 OnDeviceUpdate(value.reader().get_path()); |
| 427 } else { | 472 } else { |
| 428 DLOG(WARNING) << path_ << ": GetServiceProperties: no Device property"; | 473 DLOG(WARNING) << path_ << ": GetServiceProperties: no Device property"; |
| 429 } | 474 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 data_bytes_max, data_bytes_used); | 527 data_bytes_max, data_bytes_used); |
| 483 if (plan == NULL) { | 528 if (plan == NULL) { |
| 484 LOG(ERROR) << path_ << ": AddHardcodedDataPlan: could not create plan"; | 529 LOG(ERROR) << path_ << ": AddHardcodedDataPlan: could not create plan"; |
| 485 return; | 530 return; |
| 486 } | 531 } |
| 487 | 532 |
| 488 data_plans_.push_back(plan); | 533 data_plans_.push_back(plan); |
| 489 } | 534 } |
| 490 | 535 |
| 491 void Service::RequestUsageUpdate() { | 536 void Service::RequestUsageUpdate() { |
| 492 DCHECK(provider_ != NULL); | 537 DCHECK(ShouldSendUsageRequests()); |
| 493 DCHECK(!usage_url_.empty()); | |
| 494 DCHECK(device_ == NULL || | |
| 495 device_->GetCarrier().compare(Device::kCarrierUnknown)); | |
| 496 | |
| 497 if (request_in_progress_) { | 538 if (request_in_progress_) { |
| 539 DLOG(WARNING) << path_ |
| 540 << ": RequestUsageUpdate: request already in progress"; |
| 498 return; | 541 return; |
| 499 } | 542 } |
| 500 | |
| 501 // TODO(vlaviano): apply policy to determine if current connectivity state | |
| 502 // allows this request (e.g., if we can only make API requests over the | |
| 503 // cellular service itself, is this service the default route?) | |
| 504 | |
| 505 request_in_progress_ = true; | 543 request_in_progress_ = true; |
| 506 if (!provider_->RequestUsageUpdate()) { | 544 if (!provider_->RequestUsageUpdate()) { |
| 507 DLOG(WARNING) << path_ << ": RequestUsageUpdate: request failed"; | 545 DLOG(WARNING) << path_ << ": RequestUsageUpdate: request failed"; |
| 508 request_in_progress_ = false; | 546 request_in_progress_ = false; |
| 509 } else { | 547 } else { |
| 510 DLOG(INFO) << path_ << ": RequestUsageUpdate: request succeeded"; | 548 DLOG(INFO) << path_ << ": RequestUsageUpdate: request succeeded"; |
| 511 } | 549 } |
| 512 } | 550 } |
| 513 | 551 |
| 514 void Service::CancelPendingRequests() { | 552 void Service::CancelPendingRequests() { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 597 } |
| 560 } | 598 } |
| 561 | 599 |
| 562 void Service::DeleteCarrierState() { | 600 void Service::DeleteCarrierState() { |
| 563 DLOG(INFO) << path_ << ": DeleteCarrierState"; | 601 DLOG(INFO) << path_ << ": DeleteCarrierState"; |
| 564 if (policy_ != NULL) { | 602 if (policy_ != NULL) { |
| 565 DLOG(INFO) << path_ << ": DeleteCarrierState: deleting policy"; | 603 DLOG(INFO) << path_ << ": DeleteCarrierState: deleting policy"; |
| 566 delete policy_; | 604 delete policy_; |
| 567 policy_ = NULL; | 605 policy_ = NULL; |
| 568 } | 606 } |
| 569 DestroyUpdateTimer(); | 607 StopSendingUsageRequests(); |
| 570 CancelPendingRequests(); | |
| 571 if (provider_ != NULL) { | 608 if (provider_ != NULL) { |
| 572 DLOG(INFO) << path_ << ": DeleteCarrierState: deleting data plan provider"; | 609 DLOG(INFO) << path_ << ": DeleteCarrierState: deleting data plan provider"; |
| 573 delete provider_; | 610 delete provider_; |
| 574 provider_ = NULL; | 611 provider_ = NULL; |
| 575 } | 612 } |
| 576 } | 613 } |
| 577 | 614 |
| 578 bool Service::IsValidCrosUsageStatus(const std::string& status) const { | 615 bool Service::IsValidCrosUsageStatus(const std::string& status) const { |
| 579 if (status == kCrosUsageStatusOk || | 616 if (status == kCrosUsageStatusOk || |
| 580 status == kCrosUsageStatusError || | 617 status == kCrosUsageStatusError || |
| 581 status == kCrosUsageStatusMalformedRequest || | 618 status == kCrosUsageStatusMalformedRequest || |
| 582 status == kCrosUsageStatusInternalError || | 619 status == kCrosUsageStatusInternalError || |
| 583 status == kCrosUsageStatusServiceUnavailable || | 620 status == kCrosUsageStatusServiceUnavailable || |
| 584 status == kCrosUsageStatusRequestRefused || | 621 status == kCrosUsageStatusRequestRefused || |
| 585 status == kCrosUsageStatusUnknownDevice) { | 622 status == kCrosUsageStatusUnknownDevice) { |
| 586 return true; | 623 return true; |
| 587 } | 624 } |
| 588 return false; | 625 return false; |
| 589 } | 626 } |
| 590 | 627 |
| 591 void Service::OnCrosUsageErrorResult(const std::string& status) { | 628 void Service::OnCrosUsageErrorResult(const std::string& status) { |
| 592 DLOG(WARNING) << path_ << ": OnCrosUsageErrorResult: " << status; | 629 DLOG(WARNING) << path_ << ": OnCrosUsageErrorResult: " << status; |
| 593 // TODO(vlaviano): take action based on which specific error status string | 630 // TODO(vlaviano): hook for future use |
| 594 // we've received (e.g., we could adjust the update timer interval, or | 631 } |
| 595 // disable the timer entirely). | 632 |
| 633 bool Service::IsConnected() const { |
| 634 if (state_ != kStateReady) { |
| 635 return false; |
| 636 } |
| 637 // cross-check with parent Service Manager's idea of Flimflam global |
| 638 // connectivity state |
| 639 if (ServiceManager::IsOfflineConnectivityState( |
| 640 parent_->GetConnectivityState())) { |
| 641 DLOG(WARNING) << path_ |
| 642 << ": IsConnected: service manager thinks we're offline"; |
| 643 return false; |
| 644 } |
| 645 return true; |
| 646 } |
| 647 |
| 648 void Service::OnConnected() { |
| 649 DLOG(INFO) << path_ << ": OnConnected"; |
| 650 DCHECK(IsConnected()); |
| 651 ReconsiderSendingUsageRequests(); |
| 652 } |
| 653 |
| 654 void Service::OnDisconnected() { |
| 655 DLOG(INFO) << path_ << ": OnDisconnected"; |
| 656 DCHECK(!IsConnected()); |
| 657 ReconsiderSendingUsageRequests(); |
| 658 } |
| 659 |
| 660 bool Service::IsSendingUsageRequests() const { |
| 661 return request_in_progress_ || update_timeout_source_ != NULL; |
| 662 } |
| 663 |
| 664 // NOTE: we centralize our decisionmaking here to avoid insanity and just call |
| 665 // ReconsiderSendingUsageRequests when anything changes |
| 666 bool Service::ShouldSendUsageRequests() const { |
| 667 if (provider_ == NULL) { |
| 668 DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: no provider"; |
| 669 DCHECK(policy_ == NULL); |
| 670 return false; |
| 671 } |
| 672 DCHECK(device_ == NULL || device_->GetCarrier() != Device::kCarrierUnknown); |
| 673 DCHECK(policy_ != NULL); |
| 674 if (usage_url_.empty()) { |
| 675 DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: no usage url"; |
| 676 return false; |
| 677 } |
| 678 if (ServiceManager::IsOfflineConnectivityState( |
| 679 parent_->GetConnectivityState())) { |
| 680 DLOG(INFO) << path_ |
| 681 << ": ShouldSendUsageRequests: no: flimflam is offline"; |
| 682 return false; |
| 683 } |
| 684 if (policy_->UsageRequestsMustBeSentOTA()) { |
| 685 if (!IsConnected()) { |
| 686 DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: " |
| 687 << "ota-only policy and not connected"; |
| 688 return false; |
| 689 } |
| 690 if (!IsDefaultService()) { |
| 691 DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: " |
| 692 << "ota-only policy and not default service"; |
| 693 return false; |
| 694 } |
| 695 } |
| 696 DLOG(INFO) << path_ << ": ShouldSendUsageRequests: yes"; |
| 697 return true; |
| 698 } |
| 699 |
| 700 void Service::StopSendingUsageRequests() { |
| 701 DLOG(INFO) << path_ << ": StopSendingUsageRequests"; |
| 702 DestroyUpdateTimer(); |
| 703 CancelPendingRequests(); |
| 704 } |
| 705 |
| 706 void Service::StartSendingUsageRequests() { |
| 707 DLOG(INFO) << path_ << ": StartSendingUsageRequests"; |
| 708 DCHECK(!IsSendingUsageRequests()); |
| 709 RequestUsageUpdate(); |
| 710 CreateUpdateTimer(); |
| 711 } |
| 712 |
| 713 void Service::ReconsiderSendingUsageRequests() { |
| 714 DLOG(INFO) << path_ << ": ReconsiderSendingUsageRequests"; |
| 715 if (!IsSendingUsageRequests() && ShouldSendUsageRequests()) { |
| 716 StartSendingUsageRequests(); |
| 717 } else if (IsSendingUsageRequests() && !ShouldSendUsageRequests()) { |
| 718 StopSendingUsageRequests(); |
| 719 } |
| 596 } | 720 } |
| 597 | 721 |
| 598 } // namespace cashew | 722 } // namespace cashew |
| OLD | NEW |