summaryrefslogtreecommitdiffstats
path: root/chromeos/network/shill_property_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos/network/shill_property_handler.cc')
-rw-r--r--chromeos/network/shill_property_handler.cc137
1 files changed, 103 insertions, 34 deletions
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc
index 43483b8..f611813 100644
--- a/chromeos/network/shill_property_handler.cc
+++ b/chromeos/network/shill_property_handler.cc
@@ -14,6 +14,7 @@
#include "chromeos/dbus/shill_device_client.h"
#include "chromeos/dbus/shill_ipconfig_client.h"
#include "chromeos/dbus/shill_manager_client.h"
+#include "chromeos/dbus/shill_profile_client.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state.h"
@@ -113,10 +114,15 @@ ShillPropertyHandler::~ShillPropertyHandler() {
}
void ShillPropertyHandler::Init() {
+ UpdateManagerProperties();
+ shill_manager_->AddPropertyChangedObserver(this);
+}
+
+void ShillPropertyHandler::UpdateManagerProperties() {
+ NET_LOG_EVENT("UpdateManagerProperties", "");
shill_manager_->GetProperties(
base::Bind(&ShillPropertyHandler::ManagerPropertiesCallback,
AsWeakPtr()));
- shill_manager_->AddPropertyChangedObserver(this);
}
bool ShillPropertyHandler::IsTechnologyAvailable(
@@ -151,7 +157,7 @@ void ShillPropertyHandler::SetTechnologyEnabled(
base::Bind(&ShillPropertyHandler::EnableTechnologyFailed,
AsWeakPtr(), technology, error_callback));
} else {
- // Imediately clear locally from enabled and enabling lists.
+ // Immediately clear locally from enabled and enabling lists.
enabled_technologies_.erase(technology);
enabling_technologies_.erase(technology);
shill_manager_->DisableTechnology(
@@ -191,11 +197,13 @@ void ShillPropertyHandler::ConnectToBestServices() const {
void ShillPropertyHandler::RequestProperties(ManagedState::ManagedType type,
const std::string& path) {
+ VLOG(2) << "Request Properties: " << type << " : " << path;
if (pending_updates_[type].find(path) != pending_updates_[type].end())
return; // Update already requested.
pending_updates_[type].insert(path);
- if (type == ManagedState::MANAGED_TYPE_NETWORK) {
+ if (type == ManagedState::MANAGED_TYPE_NETWORK ||
+ type == ManagedState::MANAGED_TYPE_FAVORITE) {
DBusThreadManager::Get()->GetShillServiceClient()->GetProperties(
dbus::ObjectPath(path),
base::Bind(&ShillPropertyHandler::GetPropertiesCallback,
@@ -218,16 +226,7 @@ void ShillPropertyHandler::OnPropertyChanged(const std::string& key,
NET_LOG_DEBUG("ManagerPropertyChanged", detail);
listener_->NotifyManagerPropertyChanged();
}
- // If the service or device list changed and there are no pending
- // updates, signal the state list changed callback.
- if ((key == flimflam::kServicesProperty) &&
- pending_updates_[ManagedState::MANAGED_TYPE_NETWORK].size() == 0) {
- listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_NETWORK);
- }
- if (key == flimflam::kDevicesProperty &&
- pending_updates_[ManagedState::MANAGED_TYPE_DEVICE].size() == 0) {
- listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_DEVICE);
- }
+ CheckPendingStateListUpdates(key);
}
//------------------------------------------------------------------------------
@@ -243,29 +242,53 @@ void ShillPropertyHandler::ManagerPropertiesCallback(
}
NET_LOG_EVENT("ManagerPropertiesCallback", "Success");
bool notify = false;
- bool update_service_list = false;
+ const base::Value* update_service_value = NULL;
+ const base::Value* update_service_complete_value = NULL;
for (base::DictionaryValue::Iterator iter(properties);
!iter.IsAtEnd(); iter.Advance()) {
// Defer updating Services until all other properties have been updated.
if (iter.key() == flimflam::kServicesProperty)
- update_service_list = true;
+ update_service_value = &iter.value();
+ else if (iter.key() == shill::kServiceCompleteListProperty)
+ update_service_complete_value = &iter.value();
else
notify |= ManagerPropertyChanged(iter.key(), iter.value());
}
- // Now update the service list which can safely assume other properties have
- // been initially set.
- if (update_service_list) {
- const base::Value* value = NULL;
- if (properties.GetWithoutPathExpansion(flimflam::kServicesProperty, &value))
- notify |= ManagerPropertyChanged(flimflam::kServicesProperty, *value);
+ // Update Services which can safely assume other properties have been set.
+ if (update_service_value) {
+ notify |= ManagerPropertyChanged(flimflam::kServicesProperty,
+ *update_service_value);
+ }
+ // Update ServiceCompleteList which skips entries that have already been
+ // requested for Services.
+ if (update_service_complete_value) {
+ notify |= ManagerPropertyChanged(shill::kServiceCompleteListProperty,
+ *update_service_complete_value);
}
+
if (notify)
listener_->NotifyManagerPropertyChanged();
- // If there are no pending updates, signal the state list changed callbacks.
- if (pending_updates_[ManagedState::MANAGED_TYPE_NETWORK].size() == 0)
+ CheckPendingStateListUpdates("");
+}
+
+void ShillPropertyHandler::CheckPendingStateListUpdates(
+ const std::string& key) {
+ // Once there are no pending updates, signal the state list changed callbacks.
+ if ((key.empty() || key == flimflam::kServicesProperty) &&
+ pending_updates_[ManagedState::MANAGED_TYPE_NETWORK].size() == 0) {
listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_NETWORK);
- if (pending_updates_[ManagedState::MANAGED_TYPE_DEVICE].size() == 0)
+ }
+ // Both Network update requests and Favorite update requests will affect
+ // the list of favorites, so wait for both to complete.
+ if ((key.empty() || key == shill::kServiceCompleteListProperty) &&
+ pending_updates_[ManagedState::MANAGED_TYPE_NETWORK].size() == 0 &&
+ pending_updates_[ManagedState::MANAGED_TYPE_FAVORITE].size() == 0) {
+ listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_FAVORITE);
+ }
+ if ((key.empty() || key == flimflam::kDevicesProperty) &&
+ pending_updates_[ManagedState::MANAGED_TYPE_DEVICE].size() == 0) {
listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_DEVICE);
+ }
}
bool ShillPropertyHandler::ManagerPropertyChanged(const std::string& key,
@@ -275,16 +298,24 @@ bool ShillPropertyHandler::ManagerPropertyChanged(const std::string& key,
const base::ListValue* vlist = GetListValue(key, value);
if (vlist) {
listener_->UpdateManagedList(ManagedState::MANAGED_TYPE_NETWORK, *vlist);
+ UpdateProperties(ManagedState::MANAGED_TYPE_NETWORK, *vlist);
// UpdateObserved used to use kServiceWatchListProperty for TYPE_NETWORK,
// however that prevents us from receiving Strength updates from inactive
// networks. The overhead for observing all services is not unreasonable
// (and we limit the max number of observed services to kMaxObserved).
UpdateObserved(ManagedState::MANAGED_TYPE_NETWORK, *vlist);
}
+ } else if (key == shill::kServiceCompleteListProperty) {
+ const ListValue* vlist = GetListValue(key, value);
+ if (vlist) {
+ listener_->UpdateManagedList(ManagedState::MANAGED_TYPE_FAVORITE, *vlist);
+ UpdateProperties(ManagedState::MANAGED_TYPE_FAVORITE, *vlist);
+ }
} else if (key == flimflam::kDevicesProperty) {
const base::ListValue* vlist = GetListValue(key, value);
if (vlist) {
listener_->UpdateManagedList(ManagedState::MANAGED_TYPE_DEVICE, *vlist);
+ UpdateProperties(ManagedState::MANAGED_TYPE_DEVICE, *vlist);
UpdateObserved(ManagedState::MANAGED_TYPE_DEVICE, *vlist);
}
} else if (key == flimflam::kAvailableTechnologiesProperty) {
@@ -313,12 +344,39 @@ bool ShillPropertyHandler::ManagerPropertyChanged(const std::string& key,
listener_->CheckPortalListChanged(check_portal_list);
notify_manager_changed = true;
}
+ } else {
+ VLOG(2) << "Ignored Manager Property: " << key;
}
return notify_manager_changed;
}
+void ShillPropertyHandler::UpdateProperties(ManagedState::ManagedType type,
+ const base::ListValue& entries) {
+ std::set<std::string>& requested_updates = requested_updates_[type];
+ std::set<std::string>& requested_service_updates =
+ requested_updates_[ManagedState::MANAGED_TYPE_NETWORK]; // For favorites
+ std::set<std::string> new_requested_updates;
+ VLOG(2) << "Update Properties: " << type << " Entries: " << entries.GetSize();
+ for (base::ListValue::const_iterator iter = entries.begin();
+ iter != entries.end(); ++iter) {
+ std::string path;
+ (*iter)->GetAsString(&path);
+ if (path.empty())
+ continue;
+ if (type == ManagedState::MANAGED_TYPE_FAVORITE &&
+ requested_service_updates.count(path) > 0)
+ continue; // Update already requested
+ if (requested_updates.find(path) == requested_updates.end())
+ RequestProperties(type, path);
+ new_requested_updates.insert(path);
+ }
+ requested_updates.swap(new_requested_updates);
+}
+
void ShillPropertyHandler::UpdateObserved(ManagedState::ManagedType type,
const base::ListValue& entries) {
+ DCHECK(type == ManagedState::MANAGED_TYPE_NETWORK ||
+ type == ManagedState::MANAGED_TYPE_DEVICE);
ShillPropertyObserverMap& observer_map =
(type == ManagedState::MANAGED_TYPE_NETWORK)
? observed_networks_ : observed_devices_;
@@ -333,8 +391,6 @@ void ShillPropertyHandler::UpdateObserved(ManagedState::ManagedType type,
if (iter2 != observer_map.end()) {
new_observed[path] = iter2->second;
} else {
- // Request an update.
- RequestProperties(type, path);
// Create an observer for future updates.
new_observed[path] = new ShillPropertyObserver(
type, path, base::Bind(
@@ -416,15 +472,19 @@ void ShillPropertyHandler::GetPropertiesCallback(
VLOG(2) << "GetPropertiesCallback: " << type << " : " << path;
pending_updates_[type].erase(path);
if (call_status != DBUS_METHOD_CALL_SUCCESS) {
- LOG(ERROR) << "Failed to get properties for: " << path
- << ": " << call_status;
+ NET_LOG_ERROR("Failed to get properties",
+ base::StringPrintf("%s: %d", path.c_str(), call_status));
return;
}
listener_->UpdateManagedStateProperties(type, path, properties);
-
- if (properties.HasKey(shill::kIPConfigProperty)) {
- // Since this is the first time we received properties for this network,
- // also request its IPConfig parameters.
+ // Update Favorite properties for networks in the Services list.
+ if (type == ManagedState::MANAGED_TYPE_NETWORK) {
+ listener_->UpdateManagedStateProperties(
+ ManagedState::MANAGED_TYPE_FAVORITE, path, properties);
+ }
+ // Request IPConfig parameters for networks.
+ if (type == ManagedState::MANAGED_TYPE_NETWORK &&
+ properties.HasKey(shill::kIPConfigProperty)) {
std::string ip_config_path;
if (properties.GetString(shill::kIPConfigProperty, &ip_config_path)) {
DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties(
@@ -435,8 +495,15 @@ void ShillPropertyHandler::GetPropertiesCallback(
}
// Notify the listener only when all updates for that type have completed.
- if (pending_updates_[type].size() == 0)
+ if (pending_updates_[type].size() == 0) {
listener_->ManagedStateListChanged(type);
+ // Notify that Favorites have changed when notifying for Networks if there
+ // are no additional Favorite updates pending.
+ if (type == ManagedState::MANAGED_TYPE_NETWORK &&
+ pending_updates_[ManagedState::MANAGED_TYPE_FAVORITE].size() == 0) {
+ listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_FAVORITE);
+ }
+ }
}
void ShillPropertyHandler::PropertyChangedCallback(
@@ -476,7 +543,9 @@ void ShillPropertyHandler::GetIPConfigCallback(
DBusMethodCallStatus call_status,
const base::DictionaryValue& properties) {
if (call_status != DBUS_METHOD_CALL_SUCCESS) {
- LOG(ERROR) << "Failed to get IP Config properties for: " << service_path;
+ NET_LOG_ERROR("Failed to get IP Config properties",
+ base::StringPrintf("%s: %d",
+ service_path.c_str(), call_status));
return;
}
const base::Value* ip_address;