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

Unified Diff: src/service.cc

Issue 6395007: cashew: gmock integration (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cashew.git@master
Patch Set: Created 9 years, 11 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.h ('k') | src/service_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/service.cc
diff --git a/src/service.cc b/src/service.cc
index 7427022e31b442213f7c57f3ae29a793ee75d725..39b69bd94c8e799b30ba2596a55d81e85de80985 100644
--- a/src/service.cc
+++ b/src/service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2010, 2011 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.
@@ -6,935 +6,21 @@
#include <glog/logging.h>
-#include "src/data_plan_provider.h"
-#include "src/device.h"
-#include "src/policy.h"
-#include "src/service_manager.h"
+#include "src/service_impl.h"
namespace cashew {
-// Flimflam Service D-Bus identifiers
-static const char *kFlimflamServiceName = "org.chromium.flimflam";
-
-// Flimflam Service property names
-static const char *kFlimflamServiceConnectivityStateProperty =
- "ConnectivityState";
-static const char *kFlimflamServiceDeviceProperty = "Device";
-static const char *kFlimflamServiceStateProperty = "State";
-static const char *kFlimflamServiceTypeProperty = "Type";
-static const char *kFlimflamServiceUsageUrlProperty = "Cellular.UsageUrl";
-
-// Flimflam Service on-the-wire ConnectivityState values
-static const char *kFlimflamServiceConnectivityStateUnknown = "unknown";
-static const char *kFlimflamServiceConnectivityStateRestricted = "restricted";
-static const char *kFlimflamServiceConnectivityStateUnrestricted =
- "unrestricted";
-static const char *kFlimflamServiceConnectivityStateNone = "none";
-
-// Flimflam Service on-the-wire State values
-static const char *kFlimflamServiceStateIdle = "idle";
-static const char *kFlimflamServiceStateCarrier = "carrier";
-static const char *kFlimflamServiceStateAssociation = "association";
-static const char *kFlimflamServiceStateConfiguration = "configuration";
-static const char *kFlimflamServiceStateReady = "ready";
-static const char *kFlimflamServiceStateDisconnect = "disconnect";
-static const char *kFlimflamServiceStateFailure = "failure";
-static const char *kFlimflamServiceStateActivationFailure =
- "activation-failure";
-
-// Flimflam Service on-the-wire Type values
-static const char *kFlimflamServiceTypeEthernet = "ethernet";
-static const char *kFlimflamServiceTypeWifi = "wifi";
-static const char *kFlimflamServiceTypeWimax = "wimax";
-static const char *kFlimflamServiceTypeBluetooth = "bluetooth";
-static const char *kFlimflamServiceTypeCellular = "cellular";
-
-// Chromium OS Usage API property names
-static const char *kCrosUsageVersionProperty = "version";
-static const char *kCrosUsageStatusProperty = "status";
-static const char *kCrosUsageRestrictedProperty = "restricted";
-static const char *kCrosUsagePlansProperty = "plans";
-
-// Chromium OS Usage API version values
-static const int kCrosUsageVersionMinSupported = 1;
-static const int kCrosUsageVersionMaxSupported = 1;
-
-// Chromium OS Usage API status values
-// NOTE: add new values to IsValidCrosUsageStatus below also
-static const char *kCrosUsageStatusOk = "OK";
-static const char *kCrosUsageStatusError = "ERROR";
-static const char *kCrosUsageStatusMalformedRequest = "MALFORMED REQUEST";
-static const char *kCrosUsageStatusInternalError = "INTERNAL ERROR";
-static const char *kCrosUsageStatusServiceUnavailable = "SERVICE UNAVAILABLE";
-static const char *kCrosUsageStatusRequestRefused = "REQUEST REFUSED";
-static const char *kCrosUsageStatusUnknownDevice = "UNKNOWN DEVICE";
-
-// GetServiceProperties retry interval
-static const guint kSecondsPerMinute = 60;
-static const guint kGetServicePropertiesIntervalSeconds = 1 * kSecondsPerMinute;
-
-Service::Service(ServiceManager * const parent,
- DBus::Connection& connection, // NOLINT
- const DBus::Path& path)
- : DBus::ObjectProxy(connection, path, kFlimflamServiceName),
- parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path),
- state_(kStateUnknown), type_(kTypeUnknown), device_(NULL),
- provider_(NULL), request_in_progress_(false),
- update_timeout_source_(NULL), policy_(NULL),
- is_default_service_(false), get_properties_source_id_(0),
- retrying_get_properties_(false),
- connectivity_state_(kConnectivityStateUnknown) {
- // schedule a GetProperties() call to our Flimflam service path to init state
- // we'll keep trying periodically until we succeed
- // we'll subsequently update this state by monitoring PropertyChanged signals
- get_properties_source_id_ =
- g_idle_add(StaticGetServicePropertiesCallback, this);
- if (get_properties_source_id_ == 0) {
- LOG(ERROR) << path_ << ": ctor: g_idle_add failed";
- }
- property_changed_handler_.delegate(this);
-}
-
-Service::~Service() {
- DeleteCarrierState();
- DeleteDataPlans(&data_plans_);
- if (device_ != NULL) {
- DLOG(INFO) << path_ << ": deleting device " << device_->GetPath();
- delete device_;
- device_ = NULL;
- }
- if (get_properties_source_id_ != 0 &&
- !g_source_remove(get_properties_source_id_)) {
- DLOG(WARNING) << path_ << ": dtor: g_source_remove failed";
- }
-}
-
-const DBus::Path& Service::GetPath() const {
- return path_;
-}
-
-Service::State Service::GetState() const {
- return state_;
-}
-
-Service::Type Service::GetType() const {
- return type_;
-}
-
// static
Service::Type Service::TypeFromString(const std::string& type) {
- if (type == kFlimflamServiceTypeEthernet) {
- return kTypeEthernet;
- }
- if (type == kFlimflamServiceTypeWifi) {
- return kTypeWifi;
- }
- if (type == kFlimflamServiceTypeWimax) {
- return kTypeWimax;
- }
- if (type == kFlimflamServiceTypeBluetooth) {
- return kTypeBluetooth;
- }
- if (type == kFlimflamServiceTypeCellular) {
- return kTypeCellular;
- }
- return kTypeUnknown;
-}
-
-Device* Service::GetDevice() const {
- return device_;
-}
-
-DBusDataPlanList Service::GetDBusDataPlans() const {
- DBusDataPlanList dbus_data_plans;
- DataPlanList::const_iterator it;
- for (it = data_plans_.begin(); it != data_plans_.end(); ++it) {
- DataPlan *plan = *it;
- DCHECK(plan != NULL);
- // filter out inactive plans
- if (plan->IsActive()) {
- dbus_data_plans.push_back(plan->ToDBusFormat());
- } else {
- DLOG(INFO) << path_ << ": GetBusDataPlans: skipping inactive plan: \""
- << plan->GetName() << "\"";
- }
- }
- return dbus_data_plans;
-}
-
-bool Service::IsDefaultService() const {
- if (is_default_service_) {
- // cross-check with parent's idea of default technology
- if (parent_->GetDefaultTechnology() != kTypeCellular) {
- DLOG(WARNING) << path_ << ": IsDefaultService: "
- << "service manager doesn't think default technology is cellular";
- }
- return true;
- }
- return false;
-}
-
-Service::ConnectivityState Service::GetConnectivityState() const {
- return connectivity_state_;
-}
-
-// Flimflam Service D-Bus Proxy methods
-
-void Service::PropertyChanged(const std::string& property_name,
- const DBus::Variant& new_value) {
- DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name;
- // Queue a tuple representing this signal for later processing from the glib
- // main loop. We do this to avoid libdbus-c++ deadlocks that can occur when
- // sending a dbus message from within a dbus callback like this one.
- PropertyChangedSignal signal(property_name, new_value);
- property_changed_handler_.EnqueueSignal(signal);
-}
-
-// PropertyChangedDelegate methods
-
-void Service::OnPropertyChanged(const PropertyChangedHandler *handler,
- const std::string& property_name,
- const DBus::Variant& new_value) {
- DCHECK(handler == &property_changed_handler_);
- DLOG(INFO) << path_ << ": OnPropertyChanged: property_name = "
- << property_name;
- if (property_name == kFlimflamServiceDeviceProperty) {
- OnDeviceUpdate(new_value.reader().get_path());
- } else if (property_name == kFlimflamServiceStateProperty) {
- OnStateUpdate(new_value.reader().get_string());
- } else if (property_name == kFlimflamServiceTypeProperty) {
- OnTypeUpdate(new_value.reader().get_string());
- } else if (property_name == kFlimflamServiceUsageUrlProperty) {
- OnUsageUrlUpdate(new_value.reader().get_string());
- } else if (property_name == kFlimflamServiceConnectivityStateProperty) {
- OnConnectivityStateUpdate(new_value.reader().get_string());
- } else {
- // we don't care about this property
- }
-}
-
-// Device methods
-
-void Service::OnCarrierUpdate(const std::string& carrier) {
- DLOG(INFO) << path_ << ": OnCarrierUpdate: carrier = " << carrier;
- DCHECK(device_ != NULL);
- DCHECK(carrier == device_->GetCarrier());
-
- // get rid of state associated with old carrier
- if (provider_ != NULL) {
- DCHECK(carrier != provider_->GetCarrier());
- }
- DeleteCarrierState();
-
- // if we don't have new carrier info, we can't do anything now
- if (carrier.empty()) {
- return;
- }
-
- // create state for new carrier
- DLOG(INFO) << path_ << ": OnCarrierUpdate: creating data plan provider";
- provider_ = new(std::nothrow) DataPlanProvider(carrier);
- if (provider_ == NULL) {
- LOG(ERROR) << path_
- << ": OnCarrierUpdate: could not create data plan provider";
- return;
- }
- provider_->SetDelegate(this);
- DLOG(INFO) << path_ << ": OnCarrierUpdate: getting policy for " << carrier;
- policy_ = Policy::GetPolicy(carrier);
- if (policy_ == NULL) {
- LOG(ERROR) << path_ << ": OnCarrierUpdate: could not get policy for "
- << carrier;
- DeleteCarrierState();
- return;
- }
-
- // if we already have usage url, set new provider in motion
- if (!usage_url_.empty()) {
- provider_->SetUsageUrl(usage_url_);
- ReconsiderSendingUsageRequests();
- } else {
- // we'll do this later in OnUsageUrlUpdate
- }
-}
-
-void Service::OnByteCounterUpdate(uint64 rx_bytes, uint64 tx_bytes) {
- DCHECK(device_ != NULL);
- DCHECK(device_->ByteCounterRunning());
- DLOG(INFO) << path_ << ": OnByteCounterUpdate: rx_bytes = " << rx_bytes
- << ", tx_bytes = " << tx_bytes;
- DataPlan *active_plan = DataPlan::GetActivePlan(data_plans_);
- if (active_plan == NULL) {
- DLOG(WARNING) << path_ << ": OnByteCounterUpdate: no active plan";
- return;
- }
- Bytes local_bytes_used = rx_bytes + tx_bytes;
- DLOG(INFO) << path_ << ": OnByteCounterUpdate: local_bytes_used = "
- << local_bytes_used;
- // try to detect two error conditions:
- // (1) overflow of the unsigned addition above prior to the assignment
- // (2) no overflow, but result has high order bit set and so is interpreted as
- // a negative number when assigned to |local_bytes_used|
- if (local_bytes_used < 0 ||
- static_cast<uint64>(local_bytes_used) < rx_bytes ||
- static_cast<uint64>(local_bytes_used) < tx_bytes) {
- LOG(WARNING) << path_ << ": OnByteCounterUpdate: overflow detected";
- return;
- }
- active_plan->SetLocalBytesUsed(local_bytes_used);
- DLOG(INFO) << path_
- << ": OnByteCounterUpdate: updated plan state: data bytes used = "
- << active_plan->GetDataBytesUsed() << ", local bytes used = "
- << active_plan->GetLocalBytesUsed() << ", total bytes used = "
- << active_plan->GetTotalBytesUsed();
- MaybeEmitDataPlansUpdate();
-}
-
-// DataPlanProviderDelegate methods
-
-void Service::OnRequestComplete(const DataPlanProvider *provider,
- bool successful,
- const Value *parsed_usage_update) {
- DCHECK(provider != NULL);
- DCHECK(!successful || parsed_usage_update != NULL);
- if (provider != provider_) {
- DLOG(WARNING) << path_ << ": OnRequestComplete: wrong provider";
- return;
- }
- DCHECK(request_in_progress_);
- DCHECK(policy_ != NULL);
- DLOG(INFO) << path_ << ": OnRequestComplete: result = " << successful;
- request_in_progress_ = false;
- if (!successful) {
- LOG(WARNING) << path_ << ": OnRequestComplete: request failed";
- return;
- }
-
- // interpret and validate parsed usage update
- if (!parsed_usage_update->IsType(Value::TYPE_DICTIONARY)) {
- LOG(WARNING) << path_
- << ": OnRequestComplete: root value is not a dictionary";
- return;
- }
- const DictionaryValue *root =
- static_cast<const DictionaryValue*>(parsed_usage_update);
-
- int version;
- if (!root->GetInteger(kCrosUsageVersionProperty, &version)) {
- LOG(WARNING) << path_ << ": OnRequestComplete: no version property";
- return;
- }
- DLOG(INFO) << path_ << ": OnRequestComplete: version = " << version;
- if (version < kCrosUsageVersionMinSupported ||
- version > kCrosUsageVersionMaxSupported) {
- LOG(WARNING) << path_ << ": OnRequestComplete: version " << version
- << " not in supported range of [" << kCrosUsageVersionMinSupported
- << ", " << kCrosUsageVersionMaxSupported << "]";
- return;
- }
-
- std::string status;
- if (!root->GetString(kCrosUsageStatusProperty, &status)) {
- LOG(WARNING) << path_ << ": OnRequestComplete: no status property";
- return;
- }
- DLOG(INFO) << path_ << ": OnRequestComplete: status = " << status;
- if (!IsValidCrosUsageStatus(status)) {
- LOG(WARNING) << path_ << ": OnRequestComplete: invalid status: " << status;
- return;
- }
- if (status != kCrosUsageStatusOk) {
- LOG(WARNING) << path_ << ": OnRequestComplete: status: " << status;
- OnCrosUsageErrorResult(status);
- return;
- }
-
- bool restricted = false;
- if (root->GetBoolean(kCrosUsageRestrictedProperty, &restricted)) {
- DLOG(INFO) << path_ << ": OnRequestComplete: restricted = " << restricted;
- // TODO(vlaviano): this should probably be combined with flimflam's
- // ConnectivityState property to arrive at a conclusion.
-
- } else {
- DLOG(INFO) << path_ << ": OnRequestComplete: no restricted property";
- // restricted property is optional
- }
-
- ListValue *plans = NULL; // list to which this points is owned by dictionary
- if (!root->GetList(kCrosUsagePlansProperty, &plans)) {
- LOG(WARNING) << path_ << ": OnRequestComplete: no plans property";
- return;
- }
- DCHECK(plans != NULL);
- size_t plans_size = plans->GetSize();
- DLOG(INFO) << path_ << ": OnRequestComplete: plans list has size "
- << plans_size;
-
- // walk plans list and convert each into a DataPlan object
- DataPlanList new_plans;
- for (size_t i = 0; i < plans_size; ++i) {
- DictionaryValue *plan_dict = NULL;
- if (!plans->GetDictionary(i, &plan_dict)) {
- LOG(WARNING) << path_
- << ": OnRequestComplete: could not get plan[" << i << "]";
- continue;
- }
- DCHECK(plan_dict != NULL);
- DataPlan *plan = DataPlan::FromDictionaryValue(plan_dict, policy_);
- if (plan == NULL) {
- LOG(WARNING) << path_
- << ": OnRequestComplete: could not convert plan[" << i << "]";
- continue;
- }
- DLOG(INFO) << path_ << ": OnRequestComplete: converted plan[" << i << "]";
- new_plans.push_back(plan);
- }
-
- // store new info, causing it to be used for subsequent updates to clients
- DataPlanList old_plans = data_plans_;
- data_plans_ = new_plans;
- LOG(INFO) << path_ << ": OnRequestComplete: updated data plans";
-
- MaybeEmitDataPlansUpdate();
-
- DLOG(INFO) << path_ << ": OnRequestComplete: deleting old data plans";
- DeleteDataPlans(&old_plans);
-
- // start local byte counter so that we can stop hitting usage API
- // we'll stop the counter when we disconnect
- // we don't bother if carrier told us that there are no active data plans
- DataPlan *active_plan = DataPlan::GetActivePlan(data_plans_);
- if (active_plan == NULL) {
- DLOG(INFO) << path_
- << ": OnRequestComplete: no active plans, not starting byte counter";
- return;
- }
- DCHECK(device_ != NULL);
- DCHECK(!device_->ByteCounterRunning());
- if (!device_->StartByteCounter()) {
- LOG(WARNING) << path_
- << ": OnRequestComplete: could not start byte counter";
- // we'll keep the update timer running and try again later
- }
- DLOG(INFO) << path_ << ": OnRequestComplete: started byte counter";
- ReconsiderSendingUsageRequests();
-}
-
-// Service Manager methods
-
-void Service::OnDefaultServiceUpdate(bool is_default_service) {
- DCHECK(is_default_service_ == !is_default_service);
- DLOG(INFO) << path_ << ": OnDefaultServiceUpdate: is_default_service = "
- << is_default_service;
- is_default_service_ = is_default_service;
- if (is_default_service_) {
- // we just became the default service
- // cross-check with parent's idea of default technology
- if (parent_->GetDefaultTechnology() != kTypeCellular) {
- DLOG(WARNING) << path_ << ": OnDefaultServiceUpdate: "
- << "service manager doesn't think default technology is cellular";
- }
- }
- ReconsiderSendingUsageRequests();
-}
-
-void Service::OnFlimflamOnline() {
- DLOG(INFO) << path_ << ": OnFlimflamOnline";
- ReconsiderSendingUsageRequests();
-}
-
-void Service::OnFlimflamOffline() {
- DLOG(INFO) << path_ << ": OnFlimflamOffline";
- ReconsiderSendingUsageRequests();
-}
-
-// glib integration interface
-
-guint Service::GetGetPropertiesSourceId() const {
- return get_properties_source_id_;
-}
-
-void Service::SetGetPropertiesSourceId(guint source_id) {
- get_properties_source_id_ = source_id;
-}
-
-bool Service::RetryingGetProperties() const {
- return retrying_get_properties_;
-}
-
-void Service::OnRetryingGetProperties(bool retrying) {
- retrying_get_properties_ = retrying;
+ return ServiceImpl::TypeFromString(type);
}
-// Private methods
-
// static
-Service::ConnectivityState Service::ConnectivityStateFromString(
- const std::string& connectivity_state) {
- if (connectivity_state == kFlimflamServiceConnectivityStateUnknown) {
- return kConnectivityStateUnknown;
- }
- if (connectivity_state == kFlimflamServiceConnectivityStateRestricted) {
- return kConnectivityStateRestricted;
- }
- if (connectivity_state == kFlimflamServiceConnectivityStateUnrestricted) {
- return kConnectivityStateUnrestricted;
- }
- if (connectivity_state == kFlimflamServiceConnectivityStateNone) {
- return kConnectivityStateNone;
- }
- return kConnectivityStateUnknown;
-}
-
-// static
-Service::State Service::StateFromString(const std::string& state) {
- if (state == kFlimflamServiceStateIdle) {
- return kStateIdle;
- }
- if (state == kFlimflamServiceStateCarrier) {
- return kStateCarrier;
- }
- if (state == kFlimflamServiceStateAssociation) {
- return kStateAssociation;
- }
- if (state == kFlimflamServiceStateConfiguration) {
- return kStateConfiguration;
- }
- if (state == kFlimflamServiceStateReady) {
- return kStateReady;
- }
- if (state == kFlimflamServiceStateDisconnect) {
- return kStateDisconnect;
- }
- if (state == kFlimflamServiceStateFailure) {
- return kStateFailure;
- }
- if (state == kFlimflamServiceStateActivationFailure) {
- return kStateActivationFailure;
- }
- return kStateUnknown;
-}
-
-void Service::OnDeviceUpdate(const DBus::Path& device_path) {
- DLOG(INFO) << path_ << ": OnDeviceUpdate: device_path = " << device_path;
-
- // if there's an existing device with a non-matching path: destroy it and
- // fall through to make a new one below.
- if (device_ != NULL && device_->GetPath() != device_path) {
- LOG(WARNING) << path_ << ": OnDeviceUpdate: device path changed from "
- << device_->GetPath() << " to " << device_path;
- delete device_;
- device_ = NULL;
- }
-
- // if there's an existing device with matching path: all is well
- if (device_ != NULL) {
- return;
- }
-
- // if there's no existing device: make one
- device_ = new(std::nothrow) Device(this, connection_, device_path);
- if (device_ == NULL) {
- LOG(ERROR) << path_ << ": OnDeviceUpdate: couldn't create device for "
- << device_path;
- return;
- }
- DLOG(INFO) << path_ << ": OnDeviceUpdate: created device for "
- << device_path;
-}
-
-void Service::OnConnectivityStateUpdate(const std::string& connectivity_state) {
- DLOG(INFO) << path_ << ": OnConnectivityStateUpdate: connectivity_state = "
- << connectivity_state;
- Service::ConnectivityState new_connectivity_state =
- ConnectivityStateFromString(connectivity_state);
- if (connectivity_state_ == new_connectivity_state) {
- return;
- }
- connectivity_state_ = new_connectivity_state;
- ReconsiderSendingUsageRequests();
-}
-
-void Service::OnStateUpdate(const std::string& state) {
- DLOG(INFO) << path_ << ": OnStateUpdate: state = " << state;
- Service::State old_state = state_;
- state_ = StateFromString(state);
- if (old_state != kStateReady && IsConnected()) {
- OnConnected();
- } else if (old_state == kStateReady && !IsConnected()) {
- OnDisconnected();
- }
-}
-
-void Service::OnTypeUpdate(const std::string& type) {
- DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type;
- type_ = TypeFromString(type);
- if (type_ != kTypeCellular) {
- LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!";
- }
-}
-
-void Service::OnUsageUrlUpdate(const std::string& usage_url) {
- DLOG(INFO) << path_ << ": OnUsageUrlUpdate: url = " << usage_url;
- if (usage_url == usage_url_) {
- return;
- }
- usage_url_ = usage_url;
- if (provider_ != NULL) {
- DCHECK(usage_url_ != provider_->GetUsageUrl());
- StopSendingUsageRequests();
- provider_->SetUsageUrl(usage_url_);
- ReconsiderSendingUsageRequests();
- }
-}
-
-// static
-gboolean Service::StaticGetServicePropertiesCallback(gpointer data) {
- Service *service = reinterpret_cast<Service*>(data);
- CHECK_NOTNULL(service);
- DCHECK_NE(service->GetGetPropertiesSourceId(), 0);
- if (!service->GetServiceProperties()) {
- // call failed, so try again later
- DLOG(WARNING) << service->GetPath()
- << ": StaticGetServicePropertiesCallback: "
- << "GetServiceProperties failed, will retry in "
- << kGetServicePropertiesIntervalSeconds << " secs";
- // if we've arrived here from our first g_idle_add call, set up a timer
- if (!service->RetryingGetProperties()) {
- guint source_id =
- g_timeout_add_seconds(kGetServicePropertiesIntervalSeconds,
- StaticGetServicePropertiesCallback, service);
- service->SetGetPropertiesSourceId(source_id);
- if (source_id == 0) {
- LOG(ERROR) << service->GetPath()
- << ": StaticGetServicePropertiesCallback: "
- << "g_timeout_add_seconds failed";
- return FALSE; // get rid of old glib source and give up
- }
- service->OnRetryingGetProperties(true);
- // get rid of our old glib source, but our new timer will call us
- return FALSE;
- }
- // otherwise, our timer is already set up
- // return TRUE to indicate that we want to be called again later
- return TRUE;
- }
- service->SetGetPropertiesSourceId(0);
- service->OnRetryingGetProperties(false);
- return FALSE; // we succeeded, so don't repeat
-}
-
-bool Service::GetServiceProperties() {
- DLOG(INFO) << path_ << ": GetServiceProperties";
- 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) << path_
- << ": GetServiceProperties: GetProperties() -> Exception: "
- << error.name() << ": " << error.message();
- return false;
- } catch (...) { // NOLINT
- LOG(WARNING) << path_
- << ": GetServiceProperties: GetProperties() -> Exception";
- return false;
- }
- DLOG(INFO) << path_ << ": GetServiceProperties: Received "
- << properties.size() << " properties";
-
- // grab the properties in which we're interested
- PropertyMap::const_iterator it;
- it = properties.find(kFlimflamServiceDeviceProperty);
- if (it != properties.end()) {
- const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
- OnDeviceUpdate(value.reader().get_path());
- } else {
- DLOG(WARNING) << path_ << ": GetServiceProperties: no Device property";
- }
- it = properties.find(kFlimflamServiceStateProperty);
- if (it != properties.end()) {
- const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
- OnStateUpdate(value.reader().get_string());
- } else {
- DLOG(WARNING) << path_ << ": GetServiceProperties: no State property";
- }
- it = properties.find(kFlimflamServiceTypeProperty);
- if (it != properties.end()) {
- const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
- OnTypeUpdate(value.reader().get_string());
- } else {
- DLOG(WARNING) << path_ << ": GetServiceProperties: no Type property";
- }
- // don't expect to find Cellular.* properties if we're not a cellular service
- if (type_ != kTypeCellular) {
- return true;
- }
- it = properties.find(kFlimflamServiceUsageUrlProperty);
- if (it != properties.end()) {
- const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
- OnUsageUrlUpdate(value.reader().get_string());
- } else {
- DLOG(WARNING) << path_
- << ": GetServiceProperties: no Cellular.UsageUrl property";
- }
- // flimflam docs re: ConnectivityState: "This state is currently only
- // computed for services of type Cellular"
- it = properties.find(kFlimflamServiceConnectivityStateProperty);
- if (it != properties.end()) {
- const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
- OnConnectivityStateUpdate(value.reader().get_string());
- } else {
- DLOG(WARNING) << path_
- << ": GetServiceProperties: no ConnectivityState property";
- }
- return true;
-}
-
-void Service::DeleteDataPlans(DataPlanList *data_plans) {
- DCHECK(data_plans != NULL);
- while (!data_plans->empty()) {
- DataPlan *plan = *data_plans->begin();
- DCHECK(plan != NULL);
- DLOG(INFO) << path_ << ": DeleteDataPlans: deleting plan: "
- << plan->GetName();
- delete plan;
- data_plans->erase(data_plans->begin());
- }
-}
-
-void Service::AddHardcodedDataPlan() {
- const std::string name = "Chromium OS Test Plan";
- DataPlan::Type type = DataPlan::kTypeMeteredPaid;
- base::Time update_time = base::Time::Now();
- base::TimeDelta twelve_hours = base::TimeDelta::FromHours(12);
- base::Time start_time = base::Time::Now() - twelve_hours;
- base::Time end_time = base::Time::Now() + twelve_hours;
- Bytes data_bytes_max = 100*1024*1024; // 100 MB
- Bytes data_bytes_used = 30*1024*1024; // 30 MB
-
- DataPlan *plan = new(std::nothrow) DataPlan(name, type, update_time,
- start_time, end_time,
- data_bytes_max, data_bytes_used);
- if (plan == NULL) {
- LOG(ERROR) << path_ << ": AddHardcodedDataPlan: could not create plan";
- return;
- }
-
- data_plans_.push_back(plan);
-}
-
-void Service::RequestUsageUpdate() {
- DCHECK(ShouldSendUsageRequests());
- if (request_in_progress_) {
- DLOG(WARNING) << path_
- << ": RequestUsageUpdate: request already in progress";
- return;
- }
- request_in_progress_ = true;
- if (!provider_->RequestUsageUpdate()) {
- DLOG(WARNING) << path_ << ": RequestUsageUpdate: request failed";
- request_in_progress_ = false;
- } else {
- DLOG(INFO) << path_ << ": RequestUsageUpdate: request succeeded";
- }
-}
-
-void Service::CancelPendingRequests() {
- if (provider_ != NULL && request_in_progress_) {
- provider_->CancelPendingRequests();
- request_in_progress_ = false;
- }
-}
-
-gboolean Service::UpdateTimeoutCallback() {
- DLOG(INFO) << path_ << ": UpdateTimeoutCallback";
- RequestUsageUpdate();
- return TRUE;
-}
-
-// static
-gboolean Service::StaticUpdateTimeoutCallback(gpointer data) {
- Service *service = reinterpret_cast<Service*>(data);
- CHECK_NOTNULL(service);
- return service->UpdateTimeoutCallback();
-}
-
-bool Service::CreateUpdateTimer() {
- DCHECK(provider_ != NULL);
- DCHECK(policy_ != NULL);
- guint idle_seconds = policy_->GetUpdateTimerIdleSecs(data_plans_);
- DLOG(INFO) << path_ << ": CreateUpdateTimer: idle_seconds = " << idle_seconds;
- if (update_timeout_source_ != NULL) {
- DLOG(WARNING) << path_ << ": CreateUpdateTimer: timer already running";
- return false;
- }
- update_timeout_source_ = g_timeout_source_new_seconds(idle_seconds);
- if (update_timeout_source_ == NULL) {
- DLOG(WARNING) << path_
- << ": CreateUpdateTimer: could not create timeout source";
- return false;
- }
- g_source_set_callback(update_timeout_source_, StaticUpdateTimeoutCallback,
- this, NULL);
- g_source_attach(update_timeout_source_, NULL);
- return true;
-}
-
-void Service::DestroyUpdateTimer() {
- DLOG(INFO) << path_ << ": DestroyUpdateTimer";
- if (update_timeout_source_ != NULL) {
- g_source_destroy(update_timeout_source_);
- update_timeout_source_ = NULL;
- }
-}
-
-void Service::DeleteCarrierState() {
- DLOG(INFO) << path_ << ": DeleteCarrierState";
- if (policy_ != NULL) {
- DLOG(INFO) << path_ << ": DeleteCarrierState: deleting policy";
- delete policy_;
- policy_ = NULL;
- }
- StopSendingUsageRequests();
- if (provider_ != NULL) {
- DLOG(INFO) << path_ << ": DeleteCarrierState: deleting data plan provider";
- delete provider_;
- provider_ = NULL;
- }
-}
-
-bool Service::IsValidCrosUsageStatus(const std::string& status) const {
- if (status == kCrosUsageStatusOk ||
- status == kCrosUsageStatusError ||
- status == kCrosUsageStatusMalformedRequest ||
- status == kCrosUsageStatusInternalError ||
- status == kCrosUsageStatusServiceUnavailable ||
- status == kCrosUsageStatusRequestRefused ||
- status == kCrosUsageStatusUnknownDevice) {
- return true;
- }
- return false;
-}
-
-void Service::OnCrosUsageErrorResult(const std::string& status) {
- DLOG(WARNING) << path_ << ": OnCrosUsageErrorResult: " << status;
- // TODO(vlaviano): hook for future use
-}
-
-bool Service::IsConnected() const {
- if (state_ != kStateReady) {
- return false;
- }
- // cross-check with parent Service Manager's idea of Flimflam global
- // connectivity state
- if (ServiceManager::IsOfflineConnectivityState(
- parent_->GetConnectivityState())) {
- DLOG(WARNING) << path_
- << ": IsConnected: service manager thinks we're offline";
- return false;
- }
- return true;
-}
-
-void Service::OnConnected() {
- DLOG(INFO) << path_ << ": OnConnected";
- DCHECK(IsConnected());
- ReconsiderSendingUsageRequests();
-}
-
-void Service::OnDisconnected() {
- DLOG(INFO) << path_ << ": OnDisconnected";
- DCHECK(!IsConnected());
- // stop byte counter
- // we'll issue a new usage API request when we reconnect
- if (device_ != NULL) {
- device_->StopByteCounter();
- }
- ReconsiderSendingUsageRequests();
-}
-
-bool Service::IsSendingUsageRequests() const {
- return request_in_progress_ || update_timeout_source_ != NULL;
-}
-
-// NOTE: we centralize our decisionmaking here to avoid insanity and just call
-// ReconsiderSendingUsageRequests when anything changes
-bool Service::ShouldSendUsageRequests() const {
- if (provider_ == NULL) {
- DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: no provider";
- DCHECK(policy_ == NULL);
- return false;
- }
- DCHECK(device_ != NULL);
- DCHECK(!device_->GetCarrier().empty());
- DCHECK(policy_ != NULL);
- if (usage_url_.empty()) {
- DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: no usage url";
- return false;
- }
- if (ServiceManager::IsOfflineConnectivityState(
- parent_->GetConnectivityState())) {
- DLOG(INFO) << path_
- << ": ShouldSendUsageRequests: no: flimflam is offline";
- return false;
- }
- if (!IsConnected()) {
- DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: not connected";
- return false;
- }
- if (!IsDefaultService()) {
- DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: not default service";
- return false;
- }
- // TODO(vlaviano): this is a blunt way to ensure that we don't count local
- // traffic if we're already in the restricted pool when cashew starts
- if (GetConnectivityState() == kConnectivityStateRestricted) {
- DLOG(INFO) << path_ << ": ShouldSendUsageRequests: no: in restricted pool";
- return false;
- }
- if (device_->ByteCounterRunning()) {
- DLOG(INFO) << path_
- << ": ShouldSendUsageRequests: no: local byte counter is running";
- return false;
- }
- DLOG(INFO) << path_ << ": ShouldSendUsageRequests: yes";
- return true;
-}
-
-void Service::StopSendingUsageRequests() {
- DLOG(INFO) << path_ << ": StopSendingUsageRequests";
- DestroyUpdateTimer();
- CancelPendingRequests();
-}
-
-void Service::StartSendingUsageRequests() {
- DLOG(INFO) << path_ << ": StartSendingUsageRequests";
- DCHECK(!IsSendingUsageRequests());
- RequestUsageUpdate();
- CreateUpdateTimer();
-}
-
-void Service::ReconsiderSendingUsageRequests() {
- DLOG(INFO) << path_ << ": ReconsiderSendingUsageRequests";
- if (!IsSendingUsageRequests() && ShouldSendUsageRequests()) {
- StartSendingUsageRequests();
- } else if (IsSendingUsageRequests() && !ShouldSendUsageRequests()) {
- StopSendingUsageRequests();
- }
-}
-
-void Service::MaybeEmitDataPlansUpdate() {
- DCHECK(policy_ != NULL);
- if (policy_->ShouldEmitDataPlansUpdate(data_plans_)) {
- DLOG(INFO) << path_ << ": MaybeEmitDataPlansUpdate: sending update";
- parent_->EmitDataPlansUpdate(*this);
- } else {
- DLOG(INFO) << path_ << ": MaybeEmitDataPlansUpdate: not sending update";
- }
+Service* Service::NewService(ServiceManager * const parent,
+ DBus::Connection& connection, // NOLINT
+ const DBus::Path& path) {
+ DCHECK(parent != NULL);
+ return new(std::nothrow) ServiceImpl(parent, connection, path);
}
} // namespace cashew
« no previous file with comments | « src/service.h ('k') | src/service_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698