summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpneubeck@chromium.org <pneubeck@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-19 21:31:34 +0000
committerpneubeck@chromium.org <pneubeck@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-19 21:31:34 +0000
commit21dc5ec7a3c65a78bb6e4047eba6ddac68d9e2e7 (patch)
tree580714e1a5bb49aea0d49f9acf7e27af4ca07e1e
parent511833408f73cacc044db20a5e8bb57bdc329e14 (diff)
downloadchromium_src-21dc5ec7a3c65a78bb6e4047eba6ddac68d9e2e7.zip
chromium_src-21dc5ec7a3c65a78bb6e4047eba6ddac68d9e2e7.tar.gz
chromium_src-21dc5ec7a3c65a78bb6e4047eba6ddac68d9e2e7.tar.bz2
Fixed proxy settings in case of simultaneously active device and user ONC policy.
This fix required the following changes: - Let Shill emit profile and proxy config changes. (see https://gerrit.chromium.org/gerrit/#/c/37935/) The active network's changes are automatically picked up by ProxyConfigTracker. - Make NetworkConfigurationUpdater an observer of the Manager's profile list (by implementing the new NetworkLibrary::NetworkProfileObserver class), so that the user policy is applied _after_ Shill has pushed the user profile. - Ensure in the NetworkConfigurationUpdater that the device policy is always overwritten by the user policy (if the former is applied, also apply the latter). Apart from that, I cleaned up the code a little bit. E.g. the following members of NetworkLibrary were unused: - FindRememberedNetworkByUniqueId - SetNetworkProfile - remembered_network_unique_id_map_ BUG=157642 TEST= - Setup both policies for the same SSID with different proxy settings. - Check that after login the right proxy is used. - Toggle AutoConnect of the device policy and reload the policy while still logged in. - Check that still the right proxy is used. Review URL: https://chromiumcodereview.appspot.com/11365225 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168608 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/cros/cros_mock.cc4
-rw-r--r--chrome/browser/chromeos/cros/mock_network_library.h6
-rw-r--r--chrome/browser/chromeos/cros/network_library.h20
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_base.cc120
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_base.h17
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_cros.cc59
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_cros.h10
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_stub.cc4
-rw-r--r--chrome/browser/policy/network_configuration_updater.cc86
-rw-r--r--chrome/browser/policy/network_configuration_updater.h44
-rw-r--r--chrome/browser/policy/network_configuration_updater_unittest.cc123
11 files changed, 278 insertions, 215 deletions
diff --git a/chrome/browser/chromeos/cros/cros_mock.cc b/chrome/browser/chromeos/cros/cros_mock.cc
index 116f8f9..675542c 100644
--- a/chrome/browser/chromeos/cros/cros_mock.cc
+++ b/chrome/browser/chromeos/cros/cros_mock.cc
@@ -72,12 +72,16 @@ void CrosMock::SetStatusAreaMocksExpectations() {
void CrosMock::SetNetworkLibraryStatusAreaExpectations() {
// We don't care how often these are called, just set their return values:
+ EXPECT_CALL(*mock_network_library_, AddNetworkProfileObserver(_))
+ .Times(AnyNumber());
EXPECT_CALL(*mock_network_library_, AddNetworkManagerObserver(_))
.Times(AnyNumber());
EXPECT_CALL(*mock_network_library_, AddNetworkDeviceObserver(_, _))
.Times(AnyNumber());
EXPECT_CALL(*mock_network_library_, AddCellularDataPlanObserver(_))
.Times(AnyNumber());
+ EXPECT_CALL(*mock_network_library_, RemoveNetworkProfileObserver(_))
+ .Times(AnyNumber());
EXPECT_CALL(*mock_network_library_, RemoveNetworkManagerObserver(_))
.Times(AnyNumber());
EXPECT_CALL(*mock_network_library_, RemoveNetworkDeviceObserver(_, _))
diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h
index 558d204..cc444769 100644
--- a/chrome/browser/chromeos/cros/mock_network_library.h
+++ b/chrome/browser/chromeos/cros/mock_network_library.h
@@ -20,6 +20,8 @@ class MockNetworkLibrary : public NetworkLibrary {
MOCK_METHOD0(Init, void(void));
MOCK_CONST_METHOD0(IsCros, bool(void));
+ MOCK_METHOD1(AddNetworkProfileObserver, void(NetworkProfileObserver*));
+ MOCK_METHOD1(RemoveNetworkProfileObserver, void(NetworkProfileObserver*));
MOCK_METHOD1(AddNetworkManagerObserver, void(NetworkManagerObserver*));
MOCK_METHOD1(RemoveNetworkManagerObserver, void(NetworkManagerObserver*));
MOCK_METHOD2(AddNetworkObserver, void(const std::string&, NetworkObserver*));
@@ -95,8 +97,6 @@ class MockNetworkLibrary : public NetworkLibrary {
MOCK_CONST_METHOD1(FindVirtualNetworkByPath,
VirtualNetwork*(const std::string&));
MOCK_CONST_METHOD1(FindRememberedNetworkByPath, Network*(const std::string&));
- MOCK_CONST_METHOD1(FindRememberedNetworkByUniqueId,
- Network*(const std::string&));
MOCK_CONST_METHOD1(FindOncForNetwork,
const base::DictionaryValue*(
const std::string& unique_id));
@@ -145,8 +145,6 @@ class MockNetworkLibrary : public NetworkLibrary {
MOCK_METHOD1(DisconnectFromNetwork, void(const Network*));
MOCK_METHOD1(ForgetNetwork, void(const std::string&));
- MOCK_METHOD2(SetNetworkProfile, void(const std::string&,
- NetworkProfileType));
MOCK_CONST_METHOD0(GetCellularHomeCarrierId, const std::string&(void));
MOCK_CONST_METHOD0(ethernet_available, bool(void));
diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h
index 93b1286..73e710e 100644
--- a/chrome/browser/chromeos/cros/network_library.h
+++ b/chrome/browser/chromeos/cros/network_library.h
@@ -1263,13 +1263,21 @@ class NetworkLibrary {
USE_DHCP_GATEWAY),
};
+ class NetworkProfileObserver {
+ public:
+ // Called when the list of network profiles was changed.
+ virtual void OnProfileListChanged() = 0;
+ protected:
+ virtual ~NetworkProfileObserver() {}
+ };
+
class NetworkManagerObserver {
public:
// Called when the state of the network manager has changed,
// for example, networks have appeared or disappeared.
virtual void OnNetworkManagerChanged(NetworkLibrary* obj) = 0;
protected:
- virtual ~NetworkManagerObserver() { }
+ virtual ~NetworkManagerObserver() {}
};
class NetworkObserver {
@@ -1334,6 +1342,10 @@ class NetworkLibrary {
// Returns true if libcros was loaded instead of stubbed out.
virtual bool IsCros() const = 0;
+ virtual void AddNetworkProfileObserver(NetworkProfileObserver* observer) = 0;
+ virtual void RemoveNetworkProfileObserver(
+ NetworkProfileObserver* observer) = 0;
+
virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) = 0;
virtual void RemoveNetworkManagerObserver(
NetworkManagerObserver* observer) = 0;
@@ -1514,8 +1526,6 @@ class NetworkLibrary {
// Return a pointer to the remembered network, if it exists, or NULL.
virtual Network* FindRememberedNetworkByPath(
const std::string& path) const = 0;
- virtual Network* FindRememberedNetworkByUniqueId(
- const std::string& unique_id) const = 0;
// Return a pointer to the ONC dictionary for a network identified by unique
// ID. Returns NULL if there is no ONC dictionary available for that network.
@@ -1596,10 +1606,6 @@ class NetworkLibrary {
// Return true if a profile matching |type| is loaded.
virtual bool HasProfileType(NetworkProfileType type) const = 0;
- // Move the network to the shared/global profile.
- virtual void SetNetworkProfile(const std::string& service_path,
- NetworkProfileType type) = 0;
-
// Returns false if there is no way to connect to this network, even with
// user input (e.g. it requires a user profile but none is available).
virtual bool CanConnectToNetwork(const Network* network) const = 0;
diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.cc b/chrome/browser/chromeos/cros/network_library_impl_base.cc
index ace8e0b..7c2427f 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_base.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_base.cc
@@ -19,7 +19,6 @@ using content::BrowserThread;
namespace chromeos {
-// Local constants.
namespace {
// Only send network change notifications to observers once every 50ms.
@@ -28,9 +27,6 @@ const int kNetworkNotifyDelayMs = 50;
// How long we should remember that cellular plan payment was received.
const int kRecentPlanPaymentHours = 6;
-////////////////////////////////////////////////////////////////////////////////
-// Misc.
-
NetworkProfileType GetProfileTypeForSource(NetworkUIData::ONCSource source) {
switch (source) {
case NetworkUIData::ONC_SOURCE_DEVICE_POLICY:
@@ -67,11 +63,13 @@ NetworkLibraryImplBase::NetworkLibraryImplBase()
}
NetworkLibraryImplBase::~NetworkLibraryImplBase() {
+ network_profile_observers_.Clear();
network_manager_observers_.Clear();
data_plan_observers_.Clear();
pin_operation_observers_.Clear();
user_action_observers_.Clear();
- DeleteNetworks();
+ STLDeleteValues(&network_map_);
+ ClearNetworks();
DeleteRememberedNetworks();
STLDeleteValues(&data_plan_map_);
STLDeleteValues(&device_map_);
@@ -83,6 +81,16 @@ NetworkLibraryImplBase::~NetworkLibraryImplBase() {
//////////////////////////////////////////////////////////////////////////////
// NetworkLibrary implementation.
+void NetworkLibraryImplBase::AddNetworkProfileObserver(
+ NetworkProfileObserver* observer) {
+ network_profile_observers_.AddObserver(observer);
+}
+
+void NetworkLibraryImplBase::RemoveNetworkProfileObserver(
+ NetworkProfileObserver* observer) {
+ network_profile_observers_.RemoveObserver(observer);
+}
+
void NetworkLibraryImplBase::AddNetworkManagerObserver(
NetworkManagerObserver* observer) {
if (!network_manager_observers_.HasObserver(observer))
@@ -579,15 +587,6 @@ Network* NetworkLibraryImplBase::FindRememberedNetworkByPath(
return NULL;
}
-Network* NetworkLibraryImplBase::FindRememberedNetworkByUniqueId(
- const std::string& unique_id) const {
- NetworkMap::const_iterator found =
- remembered_network_unique_id_map_.find(unique_id);
- if (found != remembered_network_unique_id_map_.end())
- return found->second;
- return NULL;
-}
-
const base::DictionaryValue* NetworkLibraryImplBase::FindOncForNetwork(
const std::string& unique_id) const {
NetworkOncMap::const_iterator iter = network_onc_map_.find(unique_id);
@@ -717,33 +716,6 @@ bool NetworkLibraryImplBase::HasProfileType(NetworkProfileType type) const {
return false;
}
-// Note: currently there is no way to change the profile of a network
-// unless it is visible (i.e. in network_map_). We change the profile by
-// setting the Profile property of the visible network.
-// See chromium-os:15523.
-void NetworkLibraryImplBase::SetNetworkProfile(
- const std::string& service_path, NetworkProfileType type) {
- Network* network = FindNetworkByPath(service_path);
- if (!network) {
- LOG(WARNING) << "SetNetworkProfile: Network not found: " << service_path;
- return;
- }
- if (network->profile_type() == type) {
- LOG(WARNING) << "Remembered Network: " << service_path
- << " already in profile: " << type;
- return;
- }
- if (network->RequiresUserProfile() && type == PROFILE_SHARED) {
- LOG(WARNING) << "SetNetworkProfile to Shared for non sharable network: "
- << service_path;
- return;
- }
- VLOG(1) << "Setting network: " << network->name()
- << " to profile type: " << type;
- SetProfileType(network, type);
- NotifyNetworkManagerChanged(false);
-}
-
NetworkLibraryImplBase::NetworkProfile::NetworkProfile(const std::string& p,
NetworkProfileType t)
: path(p),
@@ -1154,12 +1126,20 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob,
NetworkUIData::ONCSource source,
bool allow_web_trust_from_policy,
std::string* error) {
+ NetworkProfile* profile = GetProfileForType(GetProfileTypeForSource(source));
+ if (profile == NULL) {
+ DLOG(WARNING) << "Profile for ONC source " << source << " doesn't exist.";
+ return false;
+ }
+
OncNetworkParser parser(onc_blob, passphrase, source);
parser.set_allow_web_trust_from_policy(allow_web_trust_from_policy);
if (!parser.parse_error().empty()) {
if (error)
*error = parser.parse_error();
+ DLOG(WARNING) << "Parse error when loading from ONC source " << source
+ << ": " << *error;
return false;
}
@@ -1167,9 +1147,11 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob,
// Insert each of the available certs into the certificate DB.
if (parser.ParseCertificate(i).get() == NULL &&
!parser.parse_error().empty()) {
- DLOG(WARNING) << "Cannot parse certificate in ONC file";
if (error)
*error = parser.parse_error();
+ DLOG(WARNING) << "Error during parsing certificate at index " << i
+ << " from ONC source " << source
+ << ": " << *error;
return false;
}
}
@@ -1183,9 +1165,11 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob,
bool marked_for_removal = false;
Network* network = parser.ParseNetwork(i, &marked_for_removal);
if (!network) {
- DLOG(WARNING) << "Cannot parse network in ONC file";
if (error)
*error = parser.parse_error();
+ DLOG(WARNING) << "Error during parsing network at index " << i
+ << " from ONC source " << source
+ << ": " << *error;
return false;
}
@@ -1221,7 +1205,9 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob,
// networks that are defined in the ONC blob in |network_ids|. They're later
// used to clean out any previously-existing networks that had been configured
// through policy but are no longer specified in the updated ONC blob.
- std::string profile_path(GetProfilePath(GetProfileTypeForSource(source)));
+ VLOG(1) << "Loading ONC from source " << source << " with "
+ << parser.GetNetworkConfigsSize() << " network configs"
+ << " to profile " << profile->path;
std::set<std::string>& network_ids(network_source_map_[source]);
network_ids.clear();
for (std::vector<Network*>::iterator iter(networks.begin());
@@ -1248,8 +1234,7 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob,
}
// Set the appropriate profile for |source|.
- if (!profile_path.empty())
- dict.SetString(flimflam::kProfileProperty, profile_path);
+ dict.SetString(flimflam::kProfileProperty, profile->path);
// For Ethernet networks, apply them to the current Ethernet service.
if (network->type() == TYPE_ETHERNET) {
@@ -1507,22 +1492,8 @@ bool NetworkLibraryImplBase::ValidateAndAddRememberedNetwork(Network* network) {
} else {
NOTREACHED();
}
- // Find service path in profiles. Shill does not set the Profile
- // property for remembered networks, only active networks.
- for (NetworkProfileList::iterator iter = profile_list_.begin();
- iter != profile_list_.end(); ++iter) {
- NetworkProfile& profile = *iter;
- if (profile.services.find(network->service_path()) !=
- profile.services.end()) {
- network->set_profile_path(profile.path);
- network->set_profile_type(profile.type);
- VLOG(1) << "ValidateAndAddRememberedNetwork: " << network->service_path()
- << " profile: " << profile.path;
- break;
- }
- }
- DCHECK(!network->profile_path().empty())
- << "Service path not in any profile: " << network->service_path();
+
+ VLOG(1) << "ValidateAndAddRememberedNetwork: " << network->service_path();
return true;
}
@@ -1616,23 +1587,13 @@ void NetworkLibraryImplBase::ClearNetworks() {
virtual_networks_.clear();
}
-void NetworkLibraryImplBase::ClearRememberedNetworks() {
+void NetworkLibraryImplBase::DeleteRememberedNetworks() {
+ STLDeleteValues(&remembered_network_map_);
remembered_network_map_.clear();
- remembered_network_unique_id_map_.clear();
remembered_wifi_networks_.clear();
remembered_virtual_networks_.clear();
}
-void NetworkLibraryImplBase::DeleteNetworks() {
- STLDeleteValues(&network_map_);
- ClearNetworks();
-}
-
-void NetworkLibraryImplBase::DeleteRememberedNetworks() {
- STLDeleteValues(&remembered_network_map_);
- ClearRememberedNetworks();
-}
-
void NetworkLibraryImplBase::DeleteDevice(const std::string& device_path) {
NetworkDeviceMap::iterator found = device_map_.find(device_path);
if (found == device_map_.end()) {
@@ -1649,8 +1610,9 @@ void NetworkLibraryImplBase::DeleteDevice(const std::string& device_path) {
////////////////////////////////////////////////////////////////////////////
-void NetworkLibraryImplBase::AddProfile(
- const std::string& profile_path, NetworkProfileType profile_type) {
+void NetworkLibraryImplBase::AddProfile(const std::string& profile_path,
+ NetworkProfileType profile_type) {
+ VLOG(1) << "Adding profile " << profile_path;
profile_list_.push_back(NetworkProfile(profile_path, profile_type));
// Check to see if we connected to any networks before a user profile was
// available (i.e. before login), but unchecked the "Share" option (i.e.
@@ -1723,6 +1685,12 @@ std::string NetworkLibraryImplBase::GetProfilePath(NetworkProfileType type) {
////////////////////////////////////////////////////////////////////////////
// Notifications.
+void NetworkLibraryImplBase::NotifyNetworkProfileObservers() {
+ FOR_EACH_OBSERVER(NetworkProfileObserver,
+ network_profile_observers_,
+ OnProfileListChanged());
+}
+
// We call this any time something in NetworkLibrary changes.
// TODO(stevenjb): We should consider breaking this into multiple
// notifications, e.g. connection state, devices, services, etc.
diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.h b/chrome/browser/chromeos/cros/network_library_impl_base.h
index 62e9c67..3afb104 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_base.h
+++ b/chrome/browser/chromeos/cros/network_library_impl_base.h
@@ -64,6 +64,10 @@ class NetworkLibraryImplBase : public NetworkLibrary {
// virtual Init implemented in derived classes.
// virtual IsCros implemented in derived classes.
+ virtual void AddNetworkProfileObserver(
+ NetworkProfileObserver* observer) OVERRIDE;
+ virtual void RemoveNetworkProfileObserver(
+ NetworkProfileObserver* observer) OVERRIDE;
virtual void AddNetworkManagerObserver(
NetworkManagerObserver* observer) OVERRIDE;
virtual void RemoveNetworkManagerObserver(
@@ -173,8 +177,6 @@ class NetworkLibraryImplBase : public NetworkLibrary {
Network* FindRememberedFromNetwork(const Network* network) const;
virtual Network* FindRememberedNetworkByPath(
const std::string& path) const OVERRIDE;
- virtual Network* FindRememberedNetworkByUniqueId(
- const std::string& unique_id) const OVERRIDE;
virtual const base::DictionaryValue* FindOncForNetwork(
const std::string& unique_id) const OVERRIDE;
@@ -201,8 +203,6 @@ class NetworkLibraryImplBase : public NetworkLibrary {
// virtual GetWifiAccessPoints implemented in derived classes.
virtual bool HasProfileType(NetworkProfileType type) const OVERRIDE;
- virtual void SetNetworkProfile(const std::string& service_path,
- NetworkProfileType type) OVERRIDE;
virtual bool CanConnectToNetwork(const Network* network) const OVERRIDE;
// Connect to an existing network.
@@ -350,8 +350,6 @@ class NetworkLibraryImplBase : public NetworkLibrary {
void DeleteRememberedNetwork(const std::string& service_path);
void ClearNetworks();
- void ClearRememberedNetworks();
- void DeleteNetworks();
void DeleteRememberedNetworks();
void DeleteDevice(const std::string& device_path);
void DeleteDeviceFromDeviceObserversMap(const std::string& device_path);
@@ -365,6 +363,7 @@ class NetworkLibraryImplBase : public NetworkLibrary {
std::string GetProfilePath(NetworkProfileType type);
// Notifications.
+ void NotifyNetworkProfileObservers();
void NotifyNetworkManagerChanged(bool force_update);
void SignalNetworkManagerObservers();
void NotifyNetworkChanged(const Network* network);
@@ -378,6 +377,9 @@ class NetworkLibraryImplBase : public NetworkLibrary {
const std::string& GetTpmSlot();
const std::string& GetTpmPin();
+ // Network profile observer list.
+ ObserverList<NetworkProfileObserver> network_profile_observers_;
+
// Network manager observer list.
ObserverList<NetworkManagerObserver> network_manager_observers_;
@@ -411,9 +413,6 @@ class NetworkLibraryImplBase : public NetworkLibrary {
// A service path based map of all remembered Networks.
NetworkMap remembered_network_map_;
- // A unique_id based map of all remembered Networks.
- NetworkMap remembered_network_unique_id_map_;
-
// A list of services that we are awaiting updates for.
PriorityMap network_update_requests_;
diff --git a/chrome/browser/chromeos/cros/network_library_impl_cros.cc b/chrome/browser/chromeos/cros/network_library_impl_cros.cc
index 7bb29e8..c475cdd 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_cros.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_cros.cc
@@ -129,6 +129,8 @@ void NetworkLibraryImplCros::UpdateNetworkStatus(
LOG(WARNING) << "UpdateNetworkStatus: Error updating: "
<< path << "." << key;
}
+ if (key == flimflam::kProfileProperty)
+ SetProfileTypeFromPath(network);
// If we just connected, this may have been added to remembered list.
if (!prev_connected && network->connected())
RequestRememberedNetworksUpdate();
@@ -689,7 +691,6 @@ bool NetworkLibraryImplCros::NetworkManagerStatusChanged(
if (!value->GetAsList(&vlist))
return false;
UpdateRememberedNetworks(vlist);
- RequestRememberedNetworksUpdate();
break;
}
case PROPERTY_INDEX_SERVICES: {
@@ -974,7 +975,9 @@ void NetworkLibraryImplCros::UpdateRememberedNetworks(
const ListValue* profiles) {
VLOG(1) << "UpdateRememberedNetworks";
// Update the list of profiles.
- profile_list_.clear();
+ NetworkProfileList old_profile_list;
+ old_profile_list.swap(profile_list_);
+
for (ListValue::const_iterator iter = profiles->begin();
iter != profiles->end(); ++iter) {
std::string profile_path;
@@ -990,6 +993,13 @@ void NetworkLibraryImplCros::UpdateRememberedNetworks(
profile_type = PROFILE_USER;
AddProfile(profile_path, profile_type);
}
+ bool lists_equal = old_profile_list.size() == profile_list_.size() &&
+ std::equal(profile_list_.begin(), profile_list_.end(),
+ old_profile_list.begin(), AreProfilePathsEqual);
+
+ RequestRememberedNetworksUpdate();
+ if (!lists_equal)
+ NotifyNetworkProfileObservers();
}
void NetworkLibraryImplCros::RequestRememberedNetworksUpdate() {
@@ -1054,36 +1064,53 @@ void NetworkLibraryImplCros::UpdateProfile(
// Add service to profile list.
profile.services.insert(service_path);
// Request update for remembered network.
+ // Shill does not set the Profile property for remembered networks, but only
+ // for the active networks, so we provide |profile_path| to the callback.
CrosRequestNetworkProfileEntryProperties(
profile_path,
service_path,
base::Bind(&NetworkLibraryImplCros::RememberedNetworkServiceUpdate,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr(),
+ profile_path));
}
}
void NetworkLibraryImplCros::RememberedNetworkServiceUpdate(
+ const std::string& profile_path,
const std::string& service_path,
const base::DictionaryValue* properties) {
- if (!properties) {
- // Remembered network no longer exists.
- DeleteRememberedNetwork(service_path);
+ VLOG(2) << "RememberedNetworkServiceUpdate: profile: " << profile_path
+ << " service: " << service_path
+ << (properties == NULL ? " got removed" : " got updated");
+ if (properties) {
+ ParseRememberedNetwork(profile_path, service_path, *properties);
} else {
- ParseRememberedNetwork(service_path, *properties);
+ // Remove this service from the respective Profile::services list.
+ for (NetworkProfileList::iterator iter = profile_list_.begin();
+ iter != profile_list_.end(); ++iter) {
+ NetworkProfile& profile = *iter;
+ if (profile.path != profile_path)
+ continue;
+
+ if (profile.services.erase(service_path) != 0) {
+ VLOG(1) << "Removed service path: " << service_path
+ << " from Profile::services of: " << profile_path;
+ }
+ break;
+ }
}
}
// Returns NULL if |service_path| refers to a network that is not a
// remembered type. Called from RememberedNetworkServiceUpdate.
Network* NetworkLibraryImplCros::ParseRememberedNetwork(
- const std::string& service_path, const DictionaryValue& info) {
+ const std::string& profile_path,
+ const std::string& service_path,
+ const DictionaryValue& info) {
Network* remembered;
NetworkMap::iterator found = remembered_network_map_.find(service_path);
if (found != remembered_network_map_.end()) {
remembered = found->second;
- // Erase entry from network_unique_id_map_ in case unique id changes.
- if (!remembered->unique_id().empty())
- remembered_network_unique_id_map_.erase(remembered->unique_id());
if (remembered->network_parser())
remembered->network_parser()->UpdateNetworkFromInfo(info, remembered);
} else {
@@ -1100,9 +1127,7 @@ Network* NetworkLibraryImplCros::ParseRememberedNetwork(
}
}
- if (!remembered->unique_id().empty())
- remembered_network_unique_id_map_[remembered->unique_id()] = remembered;
-
+ remembered->set_profile_path(profile_path);
SetProfileTypeFromPath(remembered);
VLOG(2) << "ParseRememberedNetwork: " << remembered->name()
@@ -1337,4 +1362,10 @@ void NetworkLibraryImplCros::SetIPParametersCallback(
RefreshIPConfig(network);
}
+// static
+bool NetworkLibraryImplCros::AreProfilePathsEqual(const NetworkProfile& a,
+ const NetworkProfile& b) {
+ return a.path == b.path;
+}
+
} // namespace chromeos
diff --git a/chrome/browser/chromeos/cros/network_library_impl_cros.h b/chrome/browser/chromeos/cros/network_library_impl_cros.h
index 43dab41..8debe51b 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_cros.h
+++ b/chrome/browser/chromeos/cros/network_library_impl_cros.h
@@ -127,7 +127,8 @@ class NetworkLibraryImplCros : public NetworkLibraryImplBase {
void NetworkServiceUpdate(const std::string& service_path,
const base::DictionaryValue* properties);
- void RememberedNetworkServiceUpdate(const std::string& service_path,
+ void RememberedNetworkServiceUpdate(const std::string& profile_path,
+ const std::string& service_path,
const base::DictionaryValue* properties);
void NetworkDeviceUpdate(const std::string& device_path,
const base::DictionaryValue* properties);
@@ -167,7 +168,8 @@ class NetworkLibraryImplCros : public NetworkLibraryImplBase {
void RequestRememberedNetworksUpdate();
void UpdateProfile(const std::string& profile_path,
const base::DictionaryValue* properties);
- Network* ParseRememberedNetwork(const std::string& service_path,
+ Network* ParseRememberedNetwork(const std::string& profile_path,
+ const std::string& service_path,
const base::DictionaryValue& info);
// NetworkDevice list management functions.
@@ -175,6 +177,10 @@ class NetworkLibraryImplCros : public NetworkLibraryImplBase {
void ParseNetworkDevice(const std::string& device_path,
const base::DictionaryValue& info);
+ // Compare two network profiles by their path.
+ static bool AreProfilePathsEqual(const NetworkProfile& a,
+ const NetworkProfile& b);
+
// Empty device observer to ensure that device property updates are received.
class NetworkLibraryDeviceObserver : public NetworkDeviceObserver {
public:
diff --git a/chrome/browser/chromeos/cros/network_library_impl_stub.cc b/chrome/browser/chromeos/cros/network_library_impl_stub.cc
index d0bf25e..d6bc7e9 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_stub.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_stub.cc
@@ -391,8 +391,8 @@ void NetworkLibraryImplStub::AddStubRememberedNetwork(Network* network) {
if (remembered) {
remembered->set_name(network->name());
remembered->set_unique_id(network->unique_id());
- // ValidateAndAddRememberedNetwork will insert the network into the matching
- // profile and set the profile type + path.
+ // ValidateAndAddRememberedNetwork will insert the network into the right
+ // remembered_*_networks_ list and the remembered_network_map_.
if (!ValidateAndAddRememberedNetwork(remembered))
NOTREACHED();
}
diff --git a/chrome/browser/policy/network_configuration_updater.cc b/chrome/browser/policy/network_configuration_updater.cc
index 68439a3..2642e3e 100644
--- a/chrome/browser/policy/network_configuration_updater.cc
+++ b/chrome/browser/policy/network_configuration_updater.cc
@@ -23,66 +23,74 @@ NetworkConfigurationUpdater::NetworkConfigurationUpdater(
: policy_change_registrar_(
policy_service, POLICY_DOMAIN_CHROME, std::string()),
network_library_(network_library),
- allow_web_trust_(false) {
+ allow_web_trust_(false),
+ policy_service_(policy_service) {
DCHECK(network_library_);
policy_change_registrar_.Observe(
key::kDeviceOpenNetworkConfiguration,
- base::Bind(&NetworkConfigurationUpdater::ApplyNetworkConfiguration,
+ base::Bind(&NetworkConfigurationUpdater::OnPolicyChanged,
base::Unretained(this),
- chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY,
- &device_network_config_));
+ chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY));
policy_change_registrar_.Observe(
key::kOpenNetworkConfiguration,
- base::Bind(&NetworkConfigurationUpdater::ApplyNetworkConfiguration,
+ base::Bind(&NetworkConfigurationUpdater::OnPolicyChanged,
base::Unretained(this),
- chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY,
- &user_network_config_));
-
- // Apply the current values immediately.
- const PolicyMap& policies = policy_service->GetPolicies(POLICY_DOMAIN_CHROME,
- std::string());
- ApplyNetworkConfiguration(
- chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY,
- &device_network_config_,
- NULL,
- policies.GetValue(key::kDeviceOpenNetworkConfiguration));
- ApplyNetworkConfiguration(
- chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY,
- &user_network_config_,
- NULL,
- policies.GetValue(key::kOpenNetworkConfiguration));
+ chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY));
+
+ network_library_->AddNetworkProfileObserver(this);
+
+ // Apply the current policies immediately.
+ ApplyNetworkConfigurations();
}
-NetworkConfigurationUpdater::~NetworkConfigurationUpdater() {}
+NetworkConfigurationUpdater::~NetworkConfigurationUpdater() {
+ network_library_->RemoveNetworkProfileObserver(this);
+}
-void NetworkConfigurationUpdater::ApplyNetworkConfiguration(
+void NetworkConfigurationUpdater::OnProfileListChanged() {
+ VLOG(1) << "Network profile list changed, applying policies.";
+ ApplyNetworkConfigurations();
+}
+
+void NetworkConfigurationUpdater::OnPolicyChanged(
chromeos::NetworkUIData::ONCSource onc_source,
- std::string* cached_value,
const base::Value* previous,
const base::Value* current) {
+ VLOG(1) << "Policy for ONC source " << onc_source << " changed.";
+ ApplyNetworkConfigurations();
+}
+
+void NetworkConfigurationUpdater::ApplyNetworkConfigurations() {
+ ApplyNetworkConfiguration(key::kDeviceOpenNetworkConfiguration,
+ chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY);
+ ApplyNetworkConfiguration(key::kOpenNetworkConfiguration,
+ chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY);
+}
+
+void NetworkConfigurationUpdater::ApplyNetworkConfiguration(
+ const std::string& policy_key,
+ chromeos::NetworkUIData::ONCSource onc_source) {
+ VLOG(1) << "Apply policy for ONC source " << onc_source;
+ const PolicyMap& policies = policy_service_->GetPolicies(POLICY_DOMAIN_CHROME,
+ std::string());
+ const base::Value* policy_value = policies.GetValue(policy_key);
+
std::string new_network_config;
- if (current != NULL) {
+ if (policy_value != NULL) {
// If the policy is not a string, we issue a warning, but still clear the
// network configuration.
- if (!current->GetAsString(&new_network_config))
- LOG(WARNING) << "Invalid network configuration.";
+ if (!policy_value->GetAsString(&new_network_config))
+ LOG(WARNING) << "ONC policy is not a string value.";
}
- // We need to load an empty configuration to get rid of any configuration
- // that has been installed previously. An empty string also works, but
- // generates warnings and errors, which we'd like to avoid.
+ // An empty string is not a valid ONC and generates warnings and
+ // errors. Replace by a valid empty configuration.
if (new_network_config.empty())
new_network_config = kEmptyConfiguration;
- if (*cached_value != new_network_config) {
- *cached_value = new_network_config;
- std::string error;
- if (!network_library_->LoadOncNetworks(new_network_config, "", onc_source,
- allow_web_trust_, &error)) {
- LOG(WARNING) << "Network library failed to load ONC configuration:"
- << error;
- }
- }
+ std::string unused_error;
+ network_library_->LoadOncNetworks(new_network_config, "", onc_source,
+ allow_web_trust_, &unused_error);
}
} // namespace policy
diff --git a/chrome/browser/policy/network_configuration_updater.h b/chrome/browser/policy/network_configuration_updater.h
index b83818f..9b4ed5b 100644
--- a/chrome/browser/policy/network_configuration_updater.h
+++ b/chrome/browser/policy/network_configuration_updater.h
@@ -7,6 +7,8 @@
#include <string>
+#include "chrome/browser/chromeos/cros/network_constants.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/cros/network_ui_data.h"
#include "chrome/browser/policy/policy_service.h"
@@ -14,22 +16,23 @@ namespace base {
class Value;
}
-namespace chromeos {
-class NetworkLibrary;
-}
-
namespace policy {
class PolicyMap;
-// Keeps track of the network configuration policy settings and updates the
-// network definitions whenever the configuration changes.
-class NetworkConfigurationUpdater {
+// Keeps track of the network configuration policy settings and Shill's
+// profiles. Requests the NetworkLibrary to apply the ONC of the network
+// policies when necessary.
+class NetworkConfigurationUpdater
+ : public chromeos::NetworkLibrary::NetworkProfileObserver {
public:
NetworkConfigurationUpdater(PolicyService* policy_service,
chromeos::NetworkLibrary* network_library);
virtual ~NetworkConfigurationUpdater();
+ // NetworkProfileObserver overrides.
+ virtual void OnProfileListChanged() OVERRIDE;
+
// Web trust isn't given to certificates imported from ONC by default.
// Setting |allow_web_trust| to true allows giving Web trust to the
// certificates that request it.
@@ -39,13 +42,21 @@ class NetworkConfigurationUpdater {
static const char kEmptyConfiguration[];
private:
- // Extracts ONC string from |policy_map| and pushes the configuration to
- // |network_library_| if it's different from |*cached_value| (which is
- // updated).
- void ApplyNetworkConfiguration(chromeos::NetworkUIData::ONCSource onc_source,
- std::string* cached_value,
- const base::Value* previous,
- const base::Value* current);
+ // Callback that's called by |policy_service_| if the respective ONC policy
+ // changed.
+ void OnPolicyChanged(chromeos::NetworkUIData::ONCSource onc_source,
+ const base::Value* previous,
+ const base::Value* current);
+
+ // Retrieves the ONC policies from |policy_service_| and pushes the
+ // configurations to |network_library_|. Ensures that a device policy is
+ // always overwritten by a user policy.
+ void ApplyNetworkConfigurations();
+
+ // Push the policy stored at |policy_key| for |onc_source| to
+ // |network_library_|.
+ void ApplyNetworkConfiguration(const std::string& policy_key,
+ chromeos::NetworkUIData::ONCSource onc_source);
// Wraps the policy service we read network configuration from.
PolicyChangeRegistrar policy_change_registrar_;
@@ -56,9 +67,8 @@ class NetworkConfigurationUpdater {
// Whether Web trust is allowed or not.
bool allow_web_trust_;
- // Current settings.
- std::string device_network_config_;
- std::string user_network_config_;
+ // The policy service storing the ONC policies.
+ PolicyService* policy_service_;
DISALLOW_COPY_AND_ASSIGN(NetworkConfigurationUpdater);
};
diff --git a/chrome/browser/policy/network_configuration_updater_unittest.cc b/chrome/browser/policy/network_configuration_updater_unittest.cc
index d97e2b8..454d0eb 100644
--- a/chrome/browser/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/policy/network_configuration_updater_unittest.cc
@@ -13,7 +13,9 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::AtLeast;
using testing::Mock;
+using testing::Ne;
using testing::Return;
using testing::_;
@@ -22,11 +24,9 @@ namespace policy {
static const char kFakeONC[] = "{ \"GUID\": \"1234\" }";
class NetworkConfigurationUpdaterTest
- : public testing::TestWithParam<const char*> {
+ : public testing::TestWithParam<const char*>{
protected:
virtual void SetUp() OVERRIDE {
- EXPECT_CALL(network_library_, LoadOncNetworks(_, "", _, _, _))
- .WillRepeatedly(Return(true));
EXPECT_CALL(provider_, IsInitializationComplete())
.WillRepeatedly(Return(true));
provider_.Init();
@@ -60,60 +60,93 @@ TEST_P(NetworkConfigurationUpdaterTest, InitialUpdate) {
Value::CreateStringValue(kFakeONC));
provider_.UpdateChromePolicy(policy);
- EXPECT_CALL(network_library_,
- LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
- false, _))
- .WillOnce(Return(true));
+ EXPECT_CALL(network_library_, AddNetworkProfileObserver(_));
+
+ // Initially, both policies are applied.
+ EXPECT_CALL(network_library_, LoadOncNetworks(
+ kFakeONC, "", NameToONCSource(GetParam()), _, _));
+ EXPECT_CALL(network_library_, LoadOncNetworks(
+ NetworkConfigurationUpdater::kEmptyConfiguration, "",
+ Ne(NameToONCSource(GetParam())), _, _));
+
+ EXPECT_CALL(network_library_, RemoveNetworkProfileObserver(_));
- NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
+ {
+ NetworkConfigurationUpdater updater(policy_service_.get(),
+ &network_library_);
+ }
Mock::VerifyAndClearExpectations(&network_library_);
}
TEST_P(NetworkConfigurationUpdaterTest, AllowWebTrust) {
- NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
- updater.set_allow_web_trust(true);
+ {
+ EXPECT_CALL(network_library_, AddNetworkProfileObserver(_));
- EXPECT_CALL(network_library_,
- LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
- true, _))
- .WillOnce(Return(true));
+ // Initially web trust is disabled.
+ EXPECT_CALL(network_library_, LoadOncNetworks(_, _, _, false, _))
+ .Times(AtLeast(0));
+ NetworkConfigurationUpdater updater(policy_service_.get(),
+ &network_library_);
+ Mock::VerifyAndClearExpectations(&network_library_);
- PolicyMap policy;
- policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
- Value::CreateStringValue(kFakeONC));
- provider_.UpdateChromePolicy(policy);
- Mock::VerifyAndClearExpectations(&network_library_);
-}
+ // Web trust should be forwarded to LoadOncNetworks.
+ EXPECT_CALL(network_library_, LoadOncNetworks(_, _, _, true, _))
+ .Times(AtLeast(0));
-TEST_P(NetworkConfigurationUpdaterTest, PolicyChange) {
- NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
+ updater.set_allow_web_trust(true);
- // We should update if policy changes.
- EXPECT_CALL(network_library_,
- LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
- false, _))
- .WillOnce(Return(true));
- PolicyMap policy;
- policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
- Value::CreateStringValue(kFakeONC));
- provider_.UpdateChromePolicy(policy);
- Mock::VerifyAndClearExpectations(&network_library_);
+ PolicyMap policy;
+ policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ Value::CreateStringValue(kFakeONC));
+ provider_.UpdateChromePolicy(policy);
+ Mock::VerifyAndClearExpectations(&network_library_);
- // No update if the set the same value again.
- EXPECT_CALL(network_library_,
- LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
- false, _))
- .Times(0);
- provider_.UpdateChromePolicy(policy);
+ EXPECT_CALL(network_library_, RemoveNetworkProfileObserver(_));
+ }
Mock::VerifyAndClearExpectations(&network_library_);
+}
- // Another update is expected if the policy goes away.
- EXPECT_CALL(network_library_,
- LoadOncNetworks(NetworkConfigurationUpdater::kEmptyConfiguration,
- "", NameToONCSource(GetParam()), false, _))
- .WillOnce(Return(true));
- policy.Erase(GetParam());
- provider_.UpdateChromePolicy(policy);
+TEST_P(NetworkConfigurationUpdaterTest, PolicyChange) {
+ {
+ EXPECT_CALL(network_library_, AddNetworkProfileObserver(_));
+
+ // Ignore the initial updates.
+ EXPECT_CALL(network_library_, LoadOncNetworks(_, _, _, _, _))
+ .Times(AtLeast(0));
+ NetworkConfigurationUpdater updater(policy_service_.get(),
+ &network_library_);
+ Mock::VerifyAndClearExpectations(&network_library_);
+
+ // We should update if policy changes.
+ EXPECT_CALL(network_library_, LoadOncNetworks(
+ kFakeONC, "", NameToONCSource(GetParam()), _, _));
+
+ // In the current implementation, we always apply both policies.
+ EXPECT_CALL(network_library_, LoadOncNetworks(
+ NetworkConfigurationUpdater::kEmptyConfiguration, "",
+ Ne(NameToONCSource(GetParam())), _, _));
+
+ PolicyMap policy;
+ policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ Value::CreateStringValue(kFakeONC));
+ provider_.UpdateChromePolicy(policy);
+ Mock::VerifyAndClearExpectations(&network_library_);
+
+ // Another update is expected if the policy goes away. In the current
+ // implementation, we always apply both policies.
+ EXPECT_CALL(network_library_, LoadOncNetworks(
+ NetworkConfigurationUpdater::kEmptyConfiguration, "",
+ chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY, _, _));
+
+ EXPECT_CALL(network_library_, LoadOncNetworks(
+ NetworkConfigurationUpdater::kEmptyConfiguration, "",
+ chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY, _, _));
+
+ EXPECT_CALL(network_library_, RemoveNetworkProfileObserver(_));
+
+ policy.Erase(GetParam());
+ provider_.UpdateChromePolicy(policy);
+ }
Mock::VerifyAndClearExpectations(&network_library_);
}