diff options
Diffstat (limited to 'chromeos/network/shill_property_handler.cc')
-rw-r--r-- | chromeos/network/shill_property_handler.cc | 137 |
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; |