summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-03 10:45:58 +0000
committerstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-03 10:45:58 +0000
commitce21fc613336439b575823b7e223b3bf9f36da0c (patch)
tree1a7ccf12cd2a74f2b352acc8ac9a6acde9aefef6
parent4b95f6f0055436bb5d33091182a4f58df9d6501d (diff)
downloadchromium_src-ce21fc613336439b575823b7e223b3bf9f36da0c.zip
chromium_src-ce21fc613336439b575823b7e223b3bf9f36da0c.tar.gz
chromium_src-ce21fc613336439b575823b7e223b3bf9f36da0c.tar.bz2
Support network Favorite/Preferred list and removal
This CL tracks Manager.ServiceCompleteList to provide a list of favorite/preferred networks to the UI. It uses Service.GetLoadableProfileEntries to remove preferred services. A test UI is provided in the status area (behind a flag). Stub behavior is updated to enable testing the UI on Linux. BUG=251922 Review URL: https://chromiumcodereview.appspot.com/17778003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209950 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/system/chromeos/network/network_state_notifier_unittest.cc3
-rw-r--r--chrome/browser/chromeos/extensions/networking_private_apitest.cc11
-rw-r--r--chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc9
-rw-r--r--chrome/browser/chromeos/proxy_config_service_impl_unittest.cc2
-rw-r--r--chromeos/chromeos.gyp2
-rw-r--r--chromeos/dbus/dbus_thread_manager.cc3
-rw-r--r--chromeos/dbus/shill_manager_client.h1
-rw-r--r--chromeos/dbus/shill_manager_client_stub.cc18
-rw-r--r--chromeos/dbus/shill_manager_client_stub.h1
-rw-r--r--chromeos/dbus/shill_profile_client.h14
-rw-r--r--chromeos/dbus/shill_profile_client_stub.cc10
-rw-r--r--chromeos/dbus/shill_profile_client_stub.h1
-rw-r--r--chromeos/dbus/shill_service_client.h2
-rw-r--r--chromeos/dbus/shill_service_client_stub.cc19
-rw-r--r--chromeos/dbus/shill_service_client_stub.h2
-rw-r--r--chromeos/network/favorite_state.cc30
-rw-r--r--chromeos/network/favorite_state.h41
-rw-r--r--chromeos/network/managed_network_configuration_handler_unittest.cc4
-rw-r--r--chromeos/network/managed_state.cc9
-rw-r--r--chromeos/network/managed_state.h3
-rw-r--r--chromeos/network/network_configuration_handler.cc4
-rw-r--r--chromeos/network/network_handler.cc1
-rw-r--r--chromeos/network/network_profile_handler.cc14
-rw-r--r--chromeos/network/network_profile_handler.h7
-rw-r--r--chromeos/network/network_state_handler.cc51
-rw-r--r--chromeos/network/network_state_handler.h25
-rw-r--r--chromeos/network/network_state_handler_unittest.cc38
-rw-r--r--chromeos/network/shill_property_handler.cc137
-rw-r--r--chromeos/network/shill_property_handler.h41
-rw-r--r--chromeos/network/shill_property_handler_unittest.cc126
30 files changed, 528 insertions, 101 deletions
diff --git a/ash/system/chromeos/network/network_state_notifier_unittest.cc b/ash/system/chromeos/network/network_state_notifier_unittest.cc
index 009274c..2f681bc 100644
--- a/ash/system/chromeos/network/network_state_notifier_unittest.cc
+++ b/ash/system/chromeos/network/network_state_notifier_unittest.cc
@@ -68,10 +68,11 @@ class NetworkStateNotifierTest : public AshTestBase {
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
service_test->ClearServices();
const bool add_to_watchlist = true;
+ const bool add_to_visible = true;
// Create wifi and cellular networks and set to online.
service_test->AddService("wifi1", "wifi1",
flimflam::kTypeWifi, flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
RunAllPendingInMessageLoop();
}
diff --git a/chrome/browser/chromeos/extensions/networking_private_apitest.cc b/chrome/browser/chromeos/extensions/networking_private_apitest.cc
index 29368f3..0cb874a 100644
--- a/chrome/browser/chromeos/extensions/networking_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/networking_private_apitest.cc
@@ -118,13 +118,14 @@ class ExtensionNetworkingPrivateApiTest :
flimflam::kTypeCellular, "stub_cellular_device1");
const bool add_to_watchlist = true;
+ const bool add_to_visible = true;
service_test->AddService("stub_ethernet", "eth0",
flimflam::kTypeEthernet, flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService("stub_wifi1", "wifi1",
flimflam::kTypeWifi, flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->SetServiceProperty("stub_wifi1",
flimflam::kSecurityProperty,
base::StringValue(flimflam::kSecurityWep));
@@ -139,7 +140,7 @@ class ExtensionNetworkingPrivateApiTest :
service_test->AddService("stub_wifi2", "wifi2_PSK",
flimflam::kTypeWifi, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->SetServiceProperty("stub_wifi2",
flimflam::kGuidProperty,
base::StringValue("stub_wifi2"));
@@ -165,7 +166,7 @@ class ExtensionNetworkingPrivateApiTest :
service_test->AddService("stub_cellular1", "cellular1",
flimflam::kTypeCellular, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->SetServiceProperty(
"stub_cellular1",
flimflam::kNetworkTechnologyProperty,
@@ -182,7 +183,7 @@ class ExtensionNetworkingPrivateApiTest :
service_test->AddService("stub_vpn1", "vpn1",
flimflam::kTypeVPN,
flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
content::RunAllPendingInMessageLoop();
}
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 6b497dd..16994e8 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -190,23 +190,24 @@ class NetworkPortalDetectorImplTest
ShillServiceClient::TestInterface* service_test =
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
service_test->ClearServices();
+ const bool add_to_visible = true;
const bool add_to_watchlist = true;
service_test->AddService(kStubEthernet,
kStubEthernet,
flimflam::kTypeEthernet, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService(kStubWireless1,
kStubWireless1,
flimflam::kTypeWifi, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService(kStubWireless2,
kStubWireless2,
flimflam::kTypeWifi, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService(kStubCellular,
kStubCellular,
flimflam::kTypeCellular, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
}
void SetupNetworkHandler() {
diff --git a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
index ccc3cdb..feffd4d 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
@@ -245,7 +245,7 @@ class ProxyConfigServiceImplTest : public testing::Test {
service_test->AddService("stub_wifi2", "wifi2_PSK",
flimflam::kTypeWifi, flimflam::kStateOnline,
- true /* add to watchlist */);
+ true /* visible */, true /* watch */);
service_test->SetServiceProperty("stub_wifi2",
flimflam::kGuidProperty,
base::StringValue("stub_wifi2"));
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index 3eef745..2c98c71 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -221,6 +221,8 @@
'network/cros_network_functions.h',
'network/device_state.cc',
'network/device_state.h',
+ 'network/favorite_state.cc',
+ 'network/favorite_state.h',
'network/geolocation_handler.cc',
'network/geolocation_handler.h',
'network/managed_network_configuration_handler.cc',
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index 66f4baf..4559dc5 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -103,7 +103,8 @@ class DBusThreadManagerImpl : public DBusThreadManager {
DebugDaemonClient::Create(client_type_, system_bus_.get()));
// Construction order of the Stub implementations of the Shill clients
- // matters; stub clients may depend only on clients previously constructed.
+ // matters; stub clients may only have construction dependencies on clients
+ // previously constructed.
shill_manager_client_.reset(
ShillManagerClient::Create(client_type_override_, system_bus_.get()));
shill_device_client_.reset(
diff --git a/chromeos/dbus/shill_manager_client.h b/chromeos/dbus/shill_manager_client.h
index e9fca9c..0a2b9b06 100644
--- a/chromeos/dbus/shill_manager_client.h
+++ b/chromeos/dbus/shill_manager_client.h
@@ -66,6 +66,7 @@ class CHROMEOS_EXPORT ShillManagerClient {
// Add/Remove/ClearService should only be called from ShillServiceClient.
virtual void AddManagerService(const std::string& service_path,
+ bool add_to_visible_list,
bool add_to_watch_list) = 0;
virtual void RemoveManagerService(const std::string& service_path) = 0;
virtual void ClearManagerServices() = 0;
diff --git a/chromeos/dbus/shill_manager_client_stub.cc b/chromeos/dbus/shill_manager_client_stub.cc
index 82eac3b..36f02939 100644
--- a/chromeos/dbus/shill_manager_client_stub.cc
+++ b/chromeos/dbus/shill_manager_client_stub.cc
@@ -213,7 +213,8 @@ void ShillManagerClientStub::ConfigureService(
// Add a new service to the service client stub because none exists, yet.
service_client->AddServiceWithIPConfig(service_path, guid, type,
flimflam::kStateIdle, ipconfig_path,
- true); // Add service to watch list.
+ true /* visible */,
+ true /* watch */);
existing_properties = service_client->GetServiceProperties(service_path);
}
@@ -398,13 +399,17 @@ void ShillManagerClientStub::MoveServiceToIndex(
}
void ShillManagerClientStub::AddManagerService(const std::string& service_path,
+ bool add_to_visible_list,
bool add_to_watch_list) {
- if (GetListProperty(flimflam::kServicesProperty)->AppendIfNotPresent(
+ // Always add to ServiceCompleteListProperty.
+ GetListProperty(shill::kServiceCompleteListProperty)->AppendIfNotPresent(
+ base::Value::CreateStringValue(service_path));
+ // If visible, add to Services and notify if new.
+ if (add_to_visible_list &&
+ GetListProperty(flimflam::kServicesProperty)->AppendIfNotPresent(
base::Value::CreateStringValue(service_path))) {
CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
}
- GetListProperty(shill::kServiceCompleteListProperty)->AppendIfNotPresent(
- base::Value::CreateStringValue(service_path));
if (add_to_watch_list)
AddServiceToWatchList(service_path);
}
@@ -478,14 +483,11 @@ void ShillManagerClientStub::PassStubProperties(
const DictionaryValueCallback& callback) const {
scoped_ptr<base::DictionaryValue> stub_properties(
stub_properties_.DeepCopy());
- // Remove disabled services from the list
+ // Remove disabled services from the list.
stub_properties->SetWithoutPathExpansion(
flimflam::kServicesProperty,
GetEnabledServiceList(flimflam::kServicesProperty));
stub_properties->SetWithoutPathExpansion(
- shill::kServiceCompleteListProperty,
- GetEnabledServiceList(shill::kServiceCompleteListProperty));
- stub_properties->SetWithoutPathExpansion(
flimflam::kServiceWatchListProperty,
GetEnabledServiceList(flimflam::kServiceWatchListProperty));
callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
diff --git a/chromeos/dbus/shill_manager_client_stub.h b/chromeos/dbus/shill_manager_client_stub.h
index 53863a2..569dd4f 100644
--- a/chromeos/dbus/shill_manager_client_stub.h
+++ b/chromeos/dbus/shill_manager_client_stub.h
@@ -93,6 +93,7 @@ class ShillManagerClientStub : public ShillManagerClient,
size_t index,
bool add_to_watch_list) OVERRIDE;
virtual void AddManagerService(const std::string& service_path,
+ bool add_to_visible_list,
bool add_to_watch_list) OVERRIDE;
virtual void RemoveManagerService(const std::string& service_path) OVERRIDE;
virtual void ClearManagerServices() OVERRIDE;
diff --git a/chromeos/dbus/shill_profile_client.h b/chromeos/dbus/shill_profile_client.h
index b93f335..bf81afb 100644
--- a/chromeos/dbus/shill_profile_client.h
+++ b/chromeos/dbus/shill_profile_client.h
@@ -43,16 +43,30 @@ class CHROMEOS_EXPORT ShillProfileClient {
// Interface for setting up services for testing. Accessed through
// GetTestInterface(), only implemented in the stub implementation.
+ // TODO(stevenjb): remove dependencies on entry_path -> service_path
+ // mappings in some of the TestInterface implementations.
class TestInterface {
public:
virtual void AddProfile(const std::string& profile_path,
const std::string& userhash) = 0;
+
+ // Adds an entry to the profile only. |entry_path| corresponds to a
+ // 'service_path' and a corresponding entry will be added to
+ // ShillManagerClient ServiceCompleteList. No checking or updating of
+ // ShillServiceClient is performed.
virtual void AddEntry(const std::string& profile_path,
const std::string& entry_path,
const base::DictionaryValue& properties) = 0;
+
+ // Adds a service to the profile, copying properties from the
+ // ShillServiceClient entry (which must be present). Also sets the Profile
+ // property of the service in ShillServiceClient.
virtual bool AddService(const std::string& profile_path,
const std::string& service_path) = 0;
+ // Sets |profiles| to the current list of profile paths.
+ virtual void GetProfilePaths(std::vector<std::string>* profiles) = 0;
+
protected:
virtual ~TestInterface() {}
};
diff --git a/chromeos/dbus/shill_profile_client_stub.cc b/chromeos/dbus/shill_profile_client_stub.cc
index b906d6d..c3cdf32 100644
--- a/chromeos/dbus/shill_profile_client_stub.cc
+++ b/chromeos/dbus/shill_profile_client_stub.cc
@@ -149,6 +149,8 @@ void ShillProfileClientStub::AddEntry(const std::string& profile_path,
DCHECK(profile);
profile->entries.SetWithoutPathExpansion(entry_path,
properties.DeepCopy());
+ DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
+ AddManagerService(entry_path, false /* visible */, false /* watch */);
}
bool ShillProfileClientStub::AddService(const std::string& profile_path,
@@ -186,6 +188,14 @@ bool ShillProfileClientStub::AddService(const std::string& profile_path,
return true;
}
+void ShillProfileClientStub::GetProfilePaths(
+ std::vector<std::string>* profiles) {
+ for (ProfileMap::iterator iter = profiles_.begin();
+ iter != profiles_.end(); ++iter) {
+ profiles->push_back(iter->first);
+ }
+}
+
ShillProfileClientStub::ProfileProperties* ShillProfileClientStub::GetProfile(
const dbus::ObjectPath& profile_path,
const ErrorCallback& error_callback) {
diff --git a/chromeos/dbus/shill_profile_client_stub.h b/chromeos/dbus/shill_profile_client_stub.h
index fd6ef24d..92e9baa 100644
--- a/chromeos/dbus/shill_profile_client_stub.h
+++ b/chromeos/dbus/shill_profile_client_stub.h
@@ -50,6 +50,7 @@ class ShillProfileClientStub : public ShillProfileClient,
const base::DictionaryValue& properties) OVERRIDE;
virtual bool AddService(const std::string& profile_path,
const std::string& service_path) OVERRIDE;
+ virtual void GetProfilePaths(std::vector<std::string>* profiles) OVERRIDE;
private:
struct ProfileProperties;
diff --git a/chromeos/dbus/shill_service_client.h b/chromeos/dbus/shill_service_client.h
index 3a3b3fa..4050c63 100644
--- a/chromeos/dbus/shill_service_client.h
+++ b/chromeos/dbus/shill_service_client.h
@@ -48,12 +48,14 @@ class CHROMEOS_EXPORT ShillServiceClient {
const std::string& name,
const std::string& type,
const std::string& state,
+ bool add_to_visible_list,
bool add_to_watch_list) = 0;
virtual void AddServiceWithIPConfig(const std::string& service_path,
const std::string& name,
const std::string& type,
const std::string& state,
const std::string& ipconfig_path,
+ bool add_to_visible_list,
bool add_to_watch_list) = 0;
virtual void RemoveService(const std::string& service_path) = 0;
virtual void SetServiceProperty(const std::string& service_path,
diff --git a/chromeos/dbus/shill_service_client_stub.cc b/chromeos/dbus/shill_service_client_stub.cc
index a1c56e9..3559ee4 100644
--- a/chromeos/dbus/shill_service_client_stub.cc
+++ b/chromeos/dbus/shill_service_client_stub.cc
@@ -326,9 +326,10 @@ void ShillServiceClientStub::AddService(const std::string& service_path,
const std::string& name,
const std::string& type,
const std::string& state,
+ bool add_to_visible_list,
bool add_to_watch_list) {
AddServiceWithIPConfig(service_path, name, type, state, "",
- add_to_watch_list);
+ add_to_visible_list, add_to_watch_list);
}
void ShillServiceClientStub::AddServiceWithIPConfig(
@@ -337,9 +338,10 @@ void ShillServiceClientStub::AddServiceWithIPConfig(
const std::string& type,
const std::string& state,
const std::string& ipconfig_path,
+ bool add_to_visible_list,
bool add_to_watch_list) {
DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
- AddManagerService(service_path, add_to_watch_list);
+ AddManagerService(service_path, add_to_visible_list, add_to_watch_list);
base::DictionaryValue* properties =
GetModifiableServiceProperties(service_path);
@@ -391,6 +393,7 @@ void ShillServiceClientStub::ClearServices() {
}
void ShillServiceClientStub::SetDefaultProperties() {
+ const bool add_to_visible = true;
const bool add_to_watchlist = true;
if (!CommandLine::ForCurrentProcess()->HasSwitch(
@@ -398,13 +401,13 @@ void ShillServiceClientStub::SetDefaultProperties() {
AddService("eth1", "eth1",
flimflam::kTypeEthernet,
flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
}
AddService("wifi1", "wifi1",
flimflam::kTypeWifi,
flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
SetServiceProperty("wifi1",
flimflam::kSecurityProperty,
base::StringValue(flimflam::kSecurityWep));
@@ -412,7 +415,7 @@ void ShillServiceClientStub::SetDefaultProperties() {
AddService("wifi2", "wifi2_PSK",
flimflam::kTypeWifi,
flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
SetServiceProperty("wifi2",
flimflam::kSecurityProperty,
base::StringValue(flimflam::kSecurityPsk));
@@ -424,7 +427,7 @@ void ShillServiceClientStub::SetDefaultProperties() {
AddService("cellular1", "cellular1",
flimflam::kTypeCellular,
flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
base::StringValue technology_value(flimflam::kNetworkTechnologyGsm);
SetServiceProperty("cellular1",
flimflam::kNetworkTechnologyProperty,
@@ -439,12 +442,12 @@ void ShillServiceClientStub::SetDefaultProperties() {
AddService("vpn1", "vpn1",
flimflam::kTypeVPN,
flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
AddService("vpn2", "vpn2",
flimflam::kTypeVPN,
flimflam::kStateOffline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
}
void ShillServiceClientStub::NotifyObserversPropertyChanged(
diff --git a/chromeos/dbus/shill_service_client_stub.h b/chromeos/dbus/shill_service_client_stub.h
index ee8d713..64f7f12 100644
--- a/chromeos/dbus/shill_service_client_stub.h
+++ b/chromeos/dbus/shill_service_client_stub.h
@@ -76,12 +76,14 @@ class ShillServiceClientStub : public ShillServiceClient,
const std::string& name,
const std::string& type,
const std::string& state,
+ bool add_to_visible_list,
bool add_to_watch_list) OVERRIDE;
virtual void AddServiceWithIPConfig(const std::string& service_path,
const std::string& name,
const std::string& type,
const std::string& state,
const std::string& ipconfig_path,
+ bool add_to_visible_list,
bool add_to_watch_list) OVERRIDE;
virtual void RemoveService(const std::string& service_path) OVERRIDE;
virtual void SetServiceProperty(const std::string& service_path,
diff --git a/chromeos/network/favorite_state.cc b/chromeos/network/favorite_state.cc
new file mode 100644
index 0000000..7f8bb31
--- /dev/null
+++ b/chromeos/network/favorite_state.cc
@@ -0,0 +1,30 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/network/favorite_state.h"
+
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+FavoriteState::FavoriteState(const std::string& path)
+ : ManagedState(MANAGED_TYPE_FAVORITE, path) {
+}
+
+FavoriteState::~FavoriteState() {
+}
+
+bool FavoriteState::PropertyChanged(const std::string& key,
+ const base::Value& value) {
+ if (ManagedStatePropertyChanged(key, value))
+ return true;
+ if (key == flimflam::kProfileProperty)
+ return GetStringValue(key, value, &profile_path_);
+ return false;
+}
+
+} // namespace chromeos
diff --git a/chromeos/network/favorite_state.h b/chromeos/network/favorite_state.h
new file mode 100644
index 0000000..54b8919
--- /dev/null
+++ b/chromeos/network/favorite_state.h
@@ -0,0 +1,41 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_NETWORK_FAVORITE_STATE_H_
+#define CHROMEOS_NETWORK_FAVORITE_STATE_H_
+
+#include "chromeos/network/managed_state.h"
+
+namespace chromeos {
+
+// A simple class to provide essential information for Services created
+// by Shill corresponding to Profile Entries (i.e. 'preferred' or 'favorite'
+// networks).
+// Note: NetworkStateHandler will store an entry for each member of
+// Manager.ServiceCompleteList, even for visible entries that are not
+// favorites. This is necessary to avoid unnecessarily re-requesting entries,
+// and to limit the code complexity. The is_favorite() accessor is used to skip
+// entries that are not actually favorites.
+class CHROMEOS_EXPORT FavoriteState : public ManagedState {
+ public:
+ explicit FavoriteState(const std::string& path);
+ virtual ~FavoriteState();
+
+ // ManagedState overrides
+ virtual bool PropertyChanged(const std::string& key,
+ const base::Value& value) OVERRIDE;
+
+ // Accessors
+ const std::string& profile_path() const { return profile_path_; }
+ bool is_favorite() const { return !profile_path_.empty(); }
+
+ private:
+ std::string profile_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(FavoriteState);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_NETWORK_FAVORITE_STATE_H_
diff --git a/chromeos/network/managed_network_configuration_handler_unittest.cc b/chromeos/network/managed_network_configuration_handler_unittest.cc
index 2b4d0be..f47d2cb 100644
--- a/chromeos/network/managed_network_configuration_handler_unittest.cc
+++ b/chromeos/network/managed_network_configuration_handler_unittest.cc
@@ -132,7 +132,9 @@ class ShillProfileTestClient {
class TestNetworkProfileHandler : public NetworkProfileHandler {
public:
- TestNetworkProfileHandler() {}
+ TestNetworkProfileHandler() {
+ Init(NULL /* No NetworkStateHandler */);
+ }
virtual ~TestNetworkProfileHandler() {}
void AddProfileForTest(const NetworkProfile& profile) {
diff --git a/chromeos/network/managed_state.cc b/chromeos/network/managed_state.cc
index 340b858..655e576 100644
--- a/chromeos/network/managed_state.cc
+++ b/chromeos/network/managed_state.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/values.h"
#include "chromeos/network/device_state.h"
+#include "chromeos/network/favorite_state.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
@@ -26,6 +27,8 @@ ManagedState* ManagedState::Create(ManagedType type, const std::string& path) {
switch (type) {
case MANAGED_TYPE_NETWORK:
return new NetworkState(path);
+ case MANAGED_TYPE_FAVORITE:
+ return new FavoriteState(path);
case MANAGED_TYPE_DEVICE:
return new DeviceState(path);
}
@@ -44,6 +47,12 @@ DeviceState* ManagedState::AsDeviceState() {
return NULL;
}
+FavoriteState* ManagedState::AsFavoriteState() {
+ if (managed_type() == MANAGED_TYPE_FAVORITE)
+ return static_cast<FavoriteState*>(this);
+ return NULL;
+}
+
void ManagedState::InitialPropertiesReceived() {
}
diff --git a/chromeos/network/managed_state.h b/chromeos/network/managed_state.h
index 4374e3c..93d39bb 100644
--- a/chromeos/network/managed_state.h
+++ b/chromeos/network/managed_state.h
@@ -18,6 +18,7 @@ class Value;
namespace chromeos {
class DeviceState;
+class FavoriteState;
class NetworkState;
// Base class for states managed by NetworkStateManger which are associated
@@ -26,6 +27,7 @@ class ManagedState {
public:
enum ManagedType {
MANAGED_TYPE_NETWORK,
+ MANAGED_TYPE_FAVORITE,
MANAGED_TYPE_DEVICE
};
@@ -39,6 +41,7 @@ class ManagedState {
// NULL if it is not.
NetworkState* AsNetworkState();
DeviceState* AsDeviceState();
+ FavoriteState* AsFavoriteState();
// Called by NetworkStateHandler when a property was received. The return
// value indicates if the state changed and is used to reduce the number of
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc
index 812aa5f..1a5ba93 100644
--- a/chromeos/network/network_configuration_handler.cc
+++ b/chromeos/network/network_configuration_handler.cc
@@ -184,8 +184,8 @@ class NetworkConfigurationHandler::ProfileEntryDeleter
// Run the callback if this is the last pending deletion.
if (!callback_.is_null())
callback_.Run();
- // TODO(stevenjb): Request NetworkStateHandler manager update to update
- // ServiceCompleteList once FavoriteStates are implemented.
+ // Request NetworkStateHandler manager update to update ServiceCompleteList.
+ owner_->network_state_handler_->UpdateManagerProperties();
owner_->ProfileEntryDeleterCompleted(service_path_); // Deletes this.
}
diff --git a/chromeos/network/network_handler.cc b/chromeos/network/network_handler.cc
index 5bc9a0a..fbe0d4b 100644
--- a/chromeos/network/network_handler.cc
+++ b/chromeos/network/network_handler.cc
@@ -41,6 +41,7 @@ NetworkHandler::~NetworkHandler() {
void NetworkHandler::Init() {
network_state_handler_->InitShillPropertyHandler();
+ network_profile_handler_->Init(network_state_handler_.get());
network_configuration_handler_->Init(network_state_handler_.get());
managed_network_configuration_handler_->Init(
network_state_handler_.get(),
diff --git a/chromeos/network/network_profile_handler.cc b/chromeos/network/network_profile_handler.cc
index de92798..96d7f37 100644
--- a/chromeos/network/network_profile_handler.cc
+++ b/chromeos/network/network_profile_handler.cc
@@ -13,6 +13,7 @@
#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/shill_profile_client.h"
#include "chromeos/network/network_profile_observer.h"
+#include "chromeos/network/network_state_handler.h"
#include "dbus/object_path.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
@@ -126,6 +127,11 @@ void NetworkProfileHandler::OnPropertyChanged(const std::string& name,
*it),
base::Bind(&LogProfileRequestError, *it));
}
+
+ // When the profile list changes, ServiceCompleteList may also change, so
+ // trigger a Manager update to request the updated list.
+ if (network_state_handler_)
+ network_state_handler_->UpdateManagerProperties();
}
void NetworkProfileHandler::GetProfilePropertiesCallback(
@@ -180,7 +186,13 @@ const NetworkProfile* NetworkProfileHandler::GetProfileForUserhash(
}
NetworkProfileHandler::NetworkProfileHandler()
- : weak_ptr_factory_(this) {
+ : network_state_handler_(NULL),
+ weak_ptr_factory_(this) {
+}
+
+void NetworkProfileHandler::Init(NetworkStateHandler* network_state_handler) {
+ network_state_handler_ = network_state_handler;
+
DBusThreadManager::Get()->GetShillManagerClient()->
AddPropertyChangedObserver(this);
diff --git a/chromeos/network/network_profile_handler.h b/chromeos/network/network_profile_handler.h
index f175876..cf35b21 100644
--- a/chromeos/network/network_profile_handler.h
+++ b/chromeos/network/network_profile_handler.h
@@ -25,6 +25,7 @@ class DictionaryValue;
namespace chromeos {
class NetworkProfileObserver;
+class NetworkStateHandler;
class CHROMEOS_EXPORT NetworkProfileHandler
: public ShillPropertyChangedObserver {
@@ -55,14 +56,18 @@ class CHROMEOS_EXPORT NetworkProfileHandler
friend class NetworkHandler;
NetworkProfileHandler();
+ // Add ShillManagerClient property observer and request initial list.
+ // Sets |network_state_handler_| for triggering Manager updates (can be NULL).
+ void Init(NetworkStateHandler* network_state_handler);
+
void AddProfile(const NetworkProfile& profile);
void RemoveProfile(const std::string& profile_path);
private:
+ NetworkStateHandler* network_state_handler_;
ProfileList profiles_;
ObserverList<NetworkProfileObserver> observers_;
- protected:
// For Shill client callbacks
base::WeakPtrFactory<NetworkProfileHandler> weak_ptr_factory_;
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index 05807fd..6118955 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -12,6 +12,7 @@
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chromeos/network/device_state.h"
+#include "chromeos/network/favorite_state.h"
#include "chromeos/network/managed_state.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state.h"
@@ -114,6 +115,11 @@ void NetworkStateHandler::RemoveObserver(
"NetworkStateHandler::RemoveObserver", "");
}
+void NetworkStateHandler::UpdateManagerProperties() {
+ NET_LOG_USER("UpdateManagerProperties", "");
+ shill_property_handler_->UpdateManagerProperties();
+}
+
NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState(
const std::string& type) const {
std::string technology = GetTechnologyForType(type);
@@ -268,6 +274,28 @@ void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const {
}
}
+void NetworkStateHandler::GetFavoriteList(FavoriteStateList* list) const {
+ DCHECK(list);
+ FavoriteStateList result;
+ list->clear();
+ for (ManagedStateList::const_iterator iter = favorite_list_.begin();
+ iter != favorite_list_.end(); ++iter) {
+ const FavoriteState* favorite = (*iter)->AsFavoriteState();
+ DCHECK(favorite);
+ if (favorite->is_favorite())
+ list->push_back(favorite);
+ }
+}
+
+const FavoriteState* NetworkStateHandler::GetFavoriteState(
+ const std::string& service_path) const {
+ ManagedState* managed =
+ GetModifiableManagedState(&favorite_list_, service_path);
+ if (!managed)
+ return NULL;
+ return managed->AsFavoriteState();
+}
+
void NetworkStateHandler::RequestScan() const {
NET_LOG_USER("RequestScan", "");
shill_property_handler_->RequestScan();
@@ -342,7 +370,8 @@ void NetworkStateHandler::GetNetworkStatePropertiesForTest(
void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
const base::ListValue& entries) {
ManagedStateList* managed_list = GetManagedList(type);
- VLOG(2) << "UpdateManagedList: " << type;
+ NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type),
+ base::StringPrintf("%"PRIuS, entries.GetSize()));
// Create a map of existing entries.
std::map<std::string, ManagedState*> managed_map;
for (ManagedStateList::iterator iter = managed_list->begin();
@@ -412,8 +441,12 @@ void NetworkStateHandler::UpdateManagedStateProperties(
NetworkState* network = managed->AsNetworkState();
DCHECK(network);
// Signal connection state changed after all properties have been updated.
- if (ConnectionStateChanged(network, prev_connection_state))
+ if (ConnectionStateChanged(network, prev_connection_state)) {
OnNetworkConnectionStateChanged(network);
+ // If the network did not already have a profile entry, refresh favorites.
+ if (network->profile_path().empty())
+ UpdateManagerProperties();
+ }
NetworkPropertiesUpdated(network);
}
managed->set_update_requested(false);
@@ -423,6 +456,13 @@ void NetworkStateHandler::UpdateNetworkServiceProperty(
const std::string& service_path,
const std::string& key,
const base::Value& value) {
+ // Update any associated FavoriteState.
+ ManagedState* favorite =
+ GetModifiableManagedState(&favorite_list_, service_path);
+ if (favorite)
+ favorite->PropertyChanged(key, value);
+
+ // Update the NetworkState.
NetworkState* network = GetModifiableNetworkState(service_path);
if (!network)
return;
@@ -494,6 +534,11 @@ void NetworkStateHandler::ManagedStateListChanged(
// The list order may have changed, so check if the default network changed.
if (CheckDefaultNetworkChanged())
OnDefaultNetworkChanged();
+ } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) {
+ NET_LOG_DEBUG("FavoriteListChanged",
+ base::StringPrintf("Size:%"PRIuS, favorite_list_.size()));
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
+ NetworkListChanged());
} else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
NET_LOG_DEBUG("DeviceListChanged",
base::StringPrintf("Size:%"PRIuS, device_list_.size()));
@@ -541,6 +586,8 @@ NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
switch (type) {
case ManagedState::MANAGED_TYPE_NETWORK:
return &network_list_;
+ case ManagedState::MANAGED_TYPE_FAVORITE:
+ return &favorite_list_;
case ManagedState::MANAGED_TYPE_DEVICE:
return &device_list_;
}
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h
index 4518634..d9bb1d2 100644
--- a/chromeos/network/network_state_handler.h
+++ b/chromeos/network/network_state_handler.h
@@ -61,6 +61,7 @@ class CHROMEOS_EXPORT NetworkStateHandler
public:
typedef std::vector<ManagedState*> ManagedStateList;
typedef std::vector<const NetworkState*> NetworkStateList;
+ typedef std::vector<const FavoriteState*> FavoriteStateList;
enum TechnologyState {
TECHNOLOGY_UNAVAILABLE,
@@ -78,6 +79,11 @@ class CHROMEOS_EXPORT NetworkStateHandler
void RemoveObserver(NetworkStateHandlerObserver* observer,
const tracked_objects::Location& from_here);
+ // Requests all Manager properties, specifically to update the complete
+ // list of services which determines the list of Favorites. This should be
+ // called any time a new service is configured or a Profile is loaded.
+ void UpdateManagerProperties();
+
// Returns the state for technology |type|. kMatchTypeMobile (only) is
// also supported.
TechnologyState GetTechnologyState(const std::string& type) const;
@@ -140,6 +146,16 @@ class CHROMEOS_EXPORT NetworkStateHandler
// only on the UI thread).
void GetNetworkList(NetworkStateList* list) const;
+ // Sets |list| to contain the list of favorite (aka "preferred") networks.
+ // See GetNetworkList() for usage, and notes for |favorite_list_|.
+ // Favorites that are visible have the same path() as the entries in
+ // GetNetworkList(), so GetNetworkState() can be used to determine if a
+ // favorite is visible and retrieve the complete properties (and vice-versa).
+ void GetFavoriteList(FavoriteStateList* list) const;
+
+ // Finds and returns a favorite state by |service_path| or NULL if not found.
+ const FavoriteState* GetFavoriteState(const std::string& service_path) const;
+
// Requests a network scan. This may trigger updates to the network
// list, which will trigger the appropriate observer calls.
void RequestScan() const;
@@ -287,8 +303,15 @@ class CHROMEOS_EXPORT NetworkStateHandler
// Observer list
ObserverList<NetworkStateHandlerObserver> observers_;
- // Lists of managed states
+ // List of managed network states
ManagedStateList network_list_;
+
+ // List of managed favorite states; this list includes all entries in
+ // Manager.ServiceCompleteList, but only entries with a non-empty Profile
+ // property are returned in GetFavoriteList().
+ ManagedStateList favorite_list_;
+
+ // List of managed device states
ManagedStateList device_list_;
// Keeps track of the default network for notifying observers when it changes.
diff --git a/chromeos/network/network_state_handler_unittest.cc b/chromeos/network/network_state_handler_unittest.cc
index 004893c..3a8b819 100644
--- a/chromeos/network/network_state_handler_unittest.cc
+++ b/chromeos/network/network_state_handler_unittest.cc
@@ -15,6 +15,7 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_device_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_state.h"
#include "chromeos/network/network_state_handler_observer.h"
@@ -43,7 +44,8 @@ class TestObserver : public chromeos::NetworkStateHandlerObserver {
: handler_(handler),
manager_changed_count_(0),
network_count_(0),
- default_network_change_count_(0) {
+ default_network_change_count_(0),
+ favorite_count_(0) {
}
virtual ~TestObserver() {
@@ -61,6 +63,9 @@ class TestObserver : public chromeos::NetworkStateHandlerObserver {
default_network_ = "";
default_network_connection_state_ = "";
}
+ NetworkStateHandler::FavoriteStateList favorites;
+ handler_->GetFavoriteList(&favorites);
+ favorite_count_ = favorites.size();
}
virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
@@ -90,6 +95,7 @@ class TestObserver : public chromeos::NetworkStateHandlerObserver {
std::string default_network_connection_state() {
return default_network_connection_state_;
}
+ size_t favorite_count() { return favorite_count_; }
int PropertyUpdatesForService(const std::string& service_path) {
return property_updates_[service_path];
@@ -111,6 +117,7 @@ class TestObserver : public chromeos::NetworkStateHandlerObserver {
size_t default_network_change_count_;
std::string default_network_;
std::string default_network_connection_state_;
+ size_t favorite_count_;
std::map<std::string, int> property_updates_;
std::map<std::string, int> connection_state_changes_;
std::map<std::string, std::string> network_connection_state_;
@@ -163,23 +170,24 @@ class NetworkStateHandlerTest : public testing::Test {
ShillServiceClient::TestInterface* service_test =
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
service_test->ClearServices();
+ const bool add_to_visible = true;
const bool add_to_watchlist = true;
service_test->AddService(kShillManagerClientStubDefaultService,
kShillManagerClientStubDefaultService,
flimflam::kTypeEthernet, flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService(kShillManagerClientStubDefaultWireless,
kShillManagerClientStubDefaultWireless,
flimflam::kTypeWifi, flimflam::kStateOnline,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService(kShillManagerClientStubWireless2,
kShillManagerClientStubWireless2,
flimflam::kTypeWifi, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
service_test->AddService(kShillManagerClientStubCellular,
kShillManagerClientStubCellular,
flimflam::kTypeCellular, flimflam::kStateIdle,
- add_to_watchlist);
+ add_to_visible, add_to_watchlist);
}
base::MessageLoopForUI message_loop_;
@@ -191,7 +199,6 @@ class NetworkStateHandlerTest : public testing::Test {
};
TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) {
- EXPECT_EQ(1u, test_observer_->manager_changed_count());
// Ensure that the network list is the expected size.
const size_t kNumShillManagerClientStubImplServices = 4;
EXPECT_EQ(kNumShillManagerClientStubImplServices,
@@ -213,7 +220,8 @@ TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) {
}
TEST_F(NetworkStateHandlerTest, TechnologyChanged) {
- EXPECT_EQ(1u, test_observer_->manager_changed_count());
+ // There may be several manager changes during initialization.
+ size_t initial_changed_count = test_observer_->manager_changed_count();
// Enable a technology.
EXPECT_NE(NetworkStateHandler::TECHNOLOGY_ENABLED,
network_state_handler_->GetTechnologyState(flimflam::kTypeWimax));
@@ -221,13 +229,13 @@ TEST_F(NetworkStateHandlerTest, TechnologyChanged) {
flimflam::kTypeWimax, true, network_handler::ErrorCallback());
// The technology state should immediately change to ENABLING and we should
// receive a manager changed callback.
- EXPECT_EQ(2u, test_observer_->manager_changed_count());
+ EXPECT_EQ(initial_changed_count + 1, test_observer_->manager_changed_count());
EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLING,
network_state_handler_->GetTechnologyState(flimflam::kTypeWimax));
message_loop_.RunUntilIdle();
// Ensure we receive another manager changed callbacks when the technology
// becomes enabled.
- EXPECT_EQ(3u, test_observer_->manager_changed_count());
+ EXPECT_EQ(initial_changed_count + 2, test_observer_->manager_changed_count());
EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLED,
network_state_handler_->GetTechnologyState(flimflam::kTypeWimax));
}
@@ -285,6 +293,18 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) {
EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1));
}
+TEST_F(NetworkStateHandlerTest, FavoriteState) {
+ // Set the profile entry of a service
+ const std::string wifi1 = kShillManagerClientStubDefaultWireless;
+ ShillProfileClient::TestInterface* profile_test =
+ DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
+ EXPECT_TRUE(profile_test->AddService("/profile/default", wifi1));
+ message_loop_.RunUntilIdle();
+ network_state_handler_->UpdateManagerProperties();
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(1u, test_observer_->favorite_count());
+}
+
TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
// Change a network state.
ShillServiceClient::TestInterface* service_test =
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;
diff --git a/chromeos/network/shill_property_handler.h b/chromeos/network/shill_property_handler.h
index 32f9f0a..bfb8eaa 100644
--- a/chromeos/network/shill_property_handler.h
+++ b/chromeos/network/shill_property_handler.h
@@ -91,9 +91,14 @@ class CHROMEOS_EXPORT ShillPropertyHandler
explicit ShillPropertyHandler(Listener* listener);
virtual ~ShillPropertyHandler();
- // Sends an initial property request and sets up the observer.
+ // Sets up the observer and calls UpdateManagerProperties().
void Init();
+ // Requests all Manager properties. Called from Init() and any time
+ // properties that do not signal changes might have been updated (e.g.
+ // ServiceCompleteList).
+ void UpdateManagerProperties();
+
// Returns true if |technology| is available, enabled, etc.
bool IsTechnologyAvailable(const std::string& technology) const;
bool IsTechnologyEnabled(const std::string& technology) const;
@@ -101,7 +106,7 @@ class CHROMEOS_EXPORT ShillPropertyHandler
bool IsTechnologyUninitialized(const std::string& technology) const;
// Asynchronously sets the enabled state for |technology|.
- // Note: Modifes Manager state. Calls |error_callback| on failure.
+ // Note: Modifies Manager state. Calls |error_callback| on failure.
void SetTechnologyEnabled(
const std::string& technology,
bool enabled,
@@ -125,14 +130,33 @@ class CHROMEOS_EXPORT ShillPropertyHandler
const base::Value& value) OVERRIDE;
private:
+ typedef std::map<ManagedState::ManagedType, std::set<std::string> >
+ TypeRequestMap;
+
// Callback for dbus method fetching properties.
void ManagerPropertiesCallback(DBusMethodCallStatus call_status,
const base::DictionaryValue& properties);
+
+ // Notifies the listener when a ManagedStateList has changed and all pending
+ // updates have been received. |key| can either identify the list that
+ // has changed or an empty string if multiple lists may have changed.
+ void CheckPendingStateListUpdates(const std::string& key);
+
// Called form OnPropertyChanged() and ManagerPropertiesCallback().
// Returns true if observers should be notified.
bool ManagerPropertyChanged(const std::string& key,
const base::Value& value);
+ // Requests properties for new entries in the list for |type| as follows:
+ // * Any new Device objects for MANAGED_TYPE_DEVICE
+ // * Any new Service objects for MANAGED_TYPE_NETWORK
+ // * Additional new Service objects for MANAGED_TYPE_FAVORITE that were not
+ // requested for MANAGED_TYPE_NETWORK (i.e. only request objects once).
+ // For this to avoid duplicate requests, this must be called with
+ // MANAGED_TYPE_NETWORK before MANAGED_TYPE_FAVORITE.
+ void UpdateProperties(ManagedState::ManagedType type,
+ const base::ListValue& entries);
+
// Updates the Shill property observers to observe any entries for |type|.
void UpdateObserved(ManagedState::ManagedType type,
const base::ListValue& entries);
@@ -164,9 +188,6 @@ class CHROMEOS_EXPORT ShillPropertyHandler
void NetworkServicePropertyChangedCallback(const std::string& path,
const std::string& key,
const base::Value& value);
- void NetworkDevicePropertyChangedCallback(const std::string& path,
- const std::string& key,
- const base::Value& value);
// Callback for getting the IPConfig property of a Network. Handled here
// instead of in NetworkState so that all asynchronous requests are done
@@ -175,6 +196,10 @@ class CHROMEOS_EXPORT ShillPropertyHandler
DBusMethodCallStatus call_status,
const base::DictionaryValue& properties);
+ void NetworkDevicePropertyChangedCallback(const std::string& path,
+ const std::string& key,
+ const base::Value& value);
+
// Pointer to containing class (owns this)
Listener* listener_;
@@ -182,7 +207,11 @@ class CHROMEOS_EXPORT ShillPropertyHandler
ShillManagerClient* shill_manager_;
// Pending update list for each managed state type
- std::map<ManagedState::ManagedType, std::set<std::string> > pending_updates_;
+ TypeRequestMap pending_updates_;
+
+ // List of states for which properties have been requested, for each managed
+ // state type
+ TypeRequestMap requested_updates_;
// List of network services with Shill property changed observers
ShillPropertyObserverMap observed_networks_;
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc
index 362b219..9d5b55b 100644
--- a/chromeos/network/shill_property_handler_unittest.cc
+++ b/chromeos/network/shill_property_handler_unittest.cc
@@ -16,6 +16,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 "dbus/object_path.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -47,7 +48,7 @@ class TestListener : public internal::ShillPropertyHandler::Listener {
ManagedState::ManagedType type,
const std::string& path,
const base::DictionaryValue& properties) OVERRIDE {
- AddPropertyUpdate(GetTypeString(type), path);
+ AddInitialPropertyUpdate(GetTypeString(type), path);
}
virtual void ProfileListChanged() OVERRIDE {
@@ -86,6 +87,10 @@ class TestListener : public internal::ShillPropertyHandler::Listener {
std::map<std::string, int>& property_updates(const std::string& type) {
return property_updates_[type];
}
+ std::map<std::string, int>& initial_property_updates(
+ const std::string& type) {
+ return initial_property_updates_[type];
+ }
int list_updates(const std::string& type) { return list_updates_[type]; }
int manager_updates() { return manager_updates_; }
int errors() { return errors_; }
@@ -94,6 +99,8 @@ class TestListener : public internal::ShillPropertyHandler::Listener {
std::string GetTypeString(ManagedState::ManagedType type) {
if (type == ManagedState::MANAGED_TYPE_NETWORK) {
return flimflam::kServicesProperty;
+ } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) {
+ return shill::kServiceCompleteListProperty;
} else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
return flimflam::kDevicesProperty;
}
@@ -120,6 +127,13 @@ class TestListener : public internal::ShillPropertyHandler::Listener {
property_updates(type)[path] += 1;
}
+ void AddInitialPropertyUpdate(const std::string& type,
+ const std::string& path) {
+ if (type.empty())
+ return;
+ initial_property_updates(type)[path] += 1;
+ }
+
void AddStateListUpdate(const std::string& type) {
if (type.empty())
return;
@@ -130,6 +144,7 @@ class TestListener : public internal::ShillPropertyHandler::Listener {
std::map<std::string, std::vector<std::string> > entries_;
// Map of list-type -> map of paths -> update counts
std::map<std::string, std::map<std::string, int> > property_updates_;
+ std::map<std::string, std::map<std::string, int> > initial_property_updates_;
// Map of list-type -> list update counts
std::map<std::string, int > list_updates_;
int manager_updates_;
@@ -143,7 +158,8 @@ class ShillPropertyHandlerTest : public testing::Test {
ShillPropertyHandlerTest()
: manager_test_(NULL),
device_test_(NULL),
- service_test_(NULL) {
+ service_test_(NULL),
+ profile_test_(NULL) {
}
virtual ~ShillPropertyHandlerTest() {
}
@@ -162,6 +178,9 @@ class ShillPropertyHandlerTest : public testing::Test {
service_test_ =
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
ASSERT_TRUE(service_test_);
+ profile_test_ =
+ DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
+ ASSERT_TRUE(profile_test_);
SetupShillPropertyHandler();
message_loop_.RunUntilIdle();
}
@@ -187,7 +206,7 @@ class ShillPropertyHandlerTest : public testing::Test {
bool add_to_watch_list) {
ASSERT_TRUE(IsValidType(type));
service_test_->AddService(id, id, type, state,
- add_to_watch_list);
+ true /* visible */, add_to_watch_list);
}
void AddServiceWithIPConfig(const std::string& type,
@@ -197,7 +216,21 @@ class ShillPropertyHandlerTest : public testing::Test {
bool add_to_watch_list) {
ASSERT_TRUE(IsValidType(type));
service_test_->AddServiceWithIPConfig(id, id, type, state,
- ipconfig_path, add_to_watch_list);
+ ipconfig_path,
+ true /* visible */,
+ add_to_watch_list);
+ }
+
+ void AddServiceToProfile(const std::string& type,
+ const std::string& id,
+ bool visible) {
+ service_test_->AddService(id, id, type, flimflam::kStateIdle,
+ visible, false /* watch */);
+ std::vector<std::string> profiles;
+ profile_test_->GetProfilePaths(&profiles);
+ ASSERT_TRUE(profiles.size() > 0);
+ base::DictionaryValue properties; // Empty entry
+ profile_test_->AddService(profiles[0], id);
}
void RemoveService(const std::string& id) {
@@ -246,6 +279,7 @@ class ShillPropertyHandlerTest : public testing::Test {
ShillManagerClient::TestInterface* manager_test_;
ShillDeviceClient::TestInterface* device_test_;
ShillServiceClient::TestInterface* service_test_;
+ ShillProfileClient::TestInterface* profile_test_;
private:
DISALLOW_COPY_AND_ASSIGN(ShillPropertyHandlerTest);
@@ -333,8 +367,8 @@ TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServicePropertyChanged) {
EXPECT_EQ(kNumShillManagerClientStubImplServices + 1,
listener_->entries(flimflam::kServicesProperty).size());
// Service receives an initial property update.
- EXPECT_EQ(1, listener_->
- property_updates(flimflam::kServicesProperty)[kTestServicePath]);
+ EXPECT_EQ(1, listener_->initial_property_updates(
+ flimflam::kServicesProperty)[kTestServicePath]);
// Change a property.
base::FundamentalValue scan_interval(3);
DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
@@ -344,8 +378,8 @@ TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServicePropertyChanged) {
base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
message_loop_.RunUntilIdle();
// Property change triggers an update.
- EXPECT_EQ(2, listener_->
- property_updates(flimflam::kServicesProperty)[kTestServicePath]);
+ EXPECT_EQ(1, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath]);
// Add the existing service to the watch list.
AddService(flimflam::kTypeWifi, kTestServicePath,
@@ -365,8 +399,8 @@ TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServicePropertyChanged) {
base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
message_loop_.RunUntilIdle();
// Property change should trigger another update.
- EXPECT_EQ(3, listener_->
- property_updates(flimflam::kServicesProperty)[kTestServicePath]);
+ EXPECT_EQ(2, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath]);
// Remove a service
RemoveService(kTestServicePath);
@@ -404,8 +438,8 @@ TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerIPConfigPropertyChanged) {
flimflam::kStateIdle, true);
message_loop_.RunUntilIdle();
// This is the initial property update.
- EXPECT_EQ(1, listener_->
- property_updates(flimflam::kServicesProperty)[kTestServicePath1]);
+ EXPECT_EQ(1, listener_->initial_property_updates(
+ flimflam::kServicesProperty)[kTestServicePath1]);
DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
dbus::ObjectPath(kTestServicePath1),
shill::kIPConfigProperty,
@@ -414,8 +448,8 @@ TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerIPConfigPropertyChanged) {
message_loop_.RunUntilIdle();
// IPConfig property change on the service should trigger property updates for
// IP Address and DNS.
- EXPECT_EQ(3, listener_->
- property_updates(flimflam::kServicesProperty)[kTestServicePath1]);
+ EXPECT_EQ(2, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath1]);
// Now, Add a new watched service with the IPConfig already set.
const std::string kTestServicePath2("test_wifi_service2");
@@ -424,8 +458,68 @@ TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerIPConfigPropertyChanged) {
message_loop_.RunUntilIdle();
// A watched service with the IPConfig property already set must
// trigger property updates for IP Address and DNS when added.
- EXPECT_EQ(3, listener_->
- property_updates(flimflam::kServicesProperty)[kTestServicePath2]);
+ EXPECT_EQ(2, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath2]);
+}
+
+TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServiceCompleteList) {
+ // Initial list updates.
+ EXPECT_EQ(1, listener_->list_updates(flimflam::kServicesProperty));
+ EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
+
+ // Add a new entry to the profile only; should trigger a single list update
+ // for both Services and ServiceCompleteList, and a single property update
+ // for ServiceCompleteList.
+ const std::string kTestServicePath1("stub_wifi_profile_only1");
+ AddServiceToProfile(flimflam::kTypeWifi, kTestServicePath1, false);
+ shill_property_handler_->UpdateManagerProperties();
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(2, listener_->list_updates(flimflam::kServicesProperty));
+ EXPECT_EQ(2, listener_->list_updates(shill::kServiceCompleteListProperty));
+ EXPECT_EQ(0, listener_->initial_property_updates(
+ flimflam::kServicesProperty)[kTestServicePath1]);
+ EXPECT_EQ(1, listener_->initial_property_updates(
+ shill::kServiceCompleteListProperty)[kTestServicePath1]);
+ EXPECT_EQ(0, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath1]);
+ EXPECT_EQ(0, listener_->property_updates(
+ shill::kServiceCompleteListProperty)[kTestServicePath1]);
+
+ // Add a new entry to the services and the profile; should also trigger a
+ // single list update for both Services and ServiceCompleteList, and should
+ // trigger tow property updates for Services (one when the Profile propety
+ // changes, and one for the Request) and one ServiceCompleteList change for
+ // the Request.
+ const std::string kTestServicePath2("stub_wifi_profile_only2");
+ AddServiceToProfile(flimflam::kTypeWifi, kTestServicePath2, true);
+ shill_property_handler_->UpdateManagerProperties();
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(3, listener_->list_updates(flimflam::kServicesProperty));
+ EXPECT_EQ(3, listener_->list_updates(shill::kServiceCompleteListProperty));
+ EXPECT_EQ(1, listener_->initial_property_updates(
+ flimflam::kServicesProperty)[kTestServicePath2]);
+ EXPECT_EQ(1, listener_->initial_property_updates(
+ shill::kServiceCompleteListProperty)[kTestServicePath2]);
+ // Expect one property update for the Profile property of the Network.
+ EXPECT_EQ(1, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath2]);
+ EXPECT_EQ(0, listener_->property_updates(
+ shill::kServiceCompleteListProperty)[kTestServicePath2]);
+
+ // Change a property of a Network in a Profile.
+ base::FundamentalValue scan_interval(3);
+ DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
+ dbus::ObjectPath(kTestServicePath2),
+ flimflam::kScanIntervalProperty,
+ scan_interval,
+ base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
+ message_loop_.RunUntilIdle();
+ // Property change should trigger an update for the Network only; no
+ // property updates pushed by Shill affect Favorites.
+ EXPECT_EQ(2, listener_->property_updates(
+ flimflam::kServicesProperty)[kTestServicePath2]);
+ EXPECT_EQ(0, listener_->property_updates(
+ shill::kServiceCompleteListProperty)[kTestServicePath2]);
}
} // namespace chromeos