0

Diagnostics: Add NetworkHealthProvider mojo interface

- Adds new NetworkHealthProvider mojo interface
- Adds NetworkListObserver and implements
  NetworkListObserver.OnNetworkListChanged
- Tests for new observer

Bug: 1197335
Test: ./out/Default/chromeos_components_unittests --gtest_filter=NetworkHealthProvider*
Change-Id: I1d301bf742a4c53b0e82150fafad0e163a2f77a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2888405
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Commit-Queue: Michael Checo <michaelcheco@google.com>
Cr-Commit-Position: refs/heads/master@{#886553}
This commit is contained in:
Michael Checo
2021-05-26 01:32:17 +00:00
committed by Chromium LUCI CQ
parent 2a732fd702
commit d4da940008
5 changed files with 182 additions and 6 deletions

@ -34,6 +34,10 @@ bool IsSupportedNetworkType(network_mojom::NetworkType type) {
}
}
bool IsNetworkOnline(network_mojom::ConnectionStateType connection_state) {
return connection_state == network_mojom::ConnectionStateType::kOnline;
}
} // namespace
NetworkProperties::NetworkProperties(
@ -72,16 +76,22 @@ void NetworkHealthProvider::OnNetworkCertificatesChanged() {}
void NetworkHealthProvider::OnActiveNetworkStateListReceived(
std::vector<network_mojom::NetworkStatePropertiesPtr> networks) {
network_properties_map_.clear();
active_guid_.clear();
for (auto& network : networks) {
if (IsSupportedNetworkType(network->type)) {
const std::string guid = mojo::Clone(network->guid);
network_mojom::ConnectionStateType connection_state =
mojo::Clone(network->connection_state);
network_properties_map_.emplace(guid, std::move(network));
if (IsNetworkOnline(connection_state)) {
active_guid_ = guid;
}
// This method depends on the |network_properties_map_| being populated
// before being called.
GetManagedPropertiesForNetwork(guid);
}
}
// TODO(michaelcheco): Call Mojo API here.
NotifyNetworkListObservers();
}
void NetworkHealthProvider::OnDeviceStateListReceived(
@ -94,7 +104,7 @@ void NetworkHealthProvider::OnDeviceStateListReceived(
}
}
std::vector<std::string> NetworkHealthProvider::GetNetworkGuidListForTesting() {
std::vector<std::string> NetworkHealthProvider::GetNetworkGuidList() {
std::vector<std::string> network_guids;
network_guids.reserve(network_properties_map_.size());
for (const auto& entry : network_properties_map_) {
@ -132,5 +142,19 @@ void NetworkHealthProvider::OnManagedPropertiesReceived(
network_props_iter->second.managed_properties = std::move(managed_properties);
}
void NetworkHealthProvider::ObserveNetworkList(
mojo::PendingRemote<mojom::NetworkListObserver> observer) {
network_list_observers_.Add(std::move(observer));
NotifyNetworkListObservers();
}
void NetworkHealthProvider::NotifyNetworkListObservers() {
auto network_guid_list = GetNetworkGuidList();
for (auto& observer : network_list_observers_) {
observer->OnNetworkListChanged(mojo::Clone(network_guid_list),
active_guid_);
}
}
} // namespace diagnostics
} // namespace chromeos

@ -9,9 +9,12 @@
#include <string>
#include <vector>
#include "chromeos/components/diagnostics_ui/mojom/network_health_provider.mojom.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/remote_set.h"
namespace chromeos {
namespace diagnostics {
@ -33,7 +36,8 @@ using DeviceMap = std::map<network_config::mojom::NetworkType,
network_config::mojom::DeviceStatePropertiesPtr>;
class NetworkHealthProvider
: public network_config::mojom::CrosNetworkConfigObserver {
: public network_config::mojom::CrosNetworkConfigObserver,
public mojom::NetworkHealthProvider {
public:
NetworkHealthProvider();
@ -42,6 +46,10 @@ class NetworkHealthProvider
~NetworkHealthProvider() override;
// mojom::NetworkHealthProvider
void ObserveNetworkList(
mojo::PendingRemote<mojom::NetworkListObserver> observer) override;
// CrosNetworkConfigObserver
void OnNetworkStateListChanged() override;
void OnDeviceStateListChanged() override;
@ -53,7 +61,7 @@ class NetworkHealthProvider
void OnVpnProvidersChanged() override;
void OnNetworkCertificatesChanged() override;
std::vector<std::string> GetNetworkGuidListForTesting();
std::vector<std::string> GetNetworkGuidList();
const DeviceMap& GetDeviceTypeMapForTesting();
@ -76,6 +84,11 @@ class NetworkHealthProvider
// Gets ManagedProperties for a network |guid| from CrosNetworkConfig.
void GetManagedPropertiesForNetwork(const std::string& guid);
// Gets a list of network guids as well as the guid of the currently active
// network (if one exists) and uses |network_list_observer_| to send the
// result to each observer.
void NotifyNetworkListObservers();
// Map of networks that are active and of a supported
// type (Ethernet, WiFi, Cellular).
NetworkPropertiesMap network_properties_map_;
@ -84,6 +97,9 @@ class NetworkHealthProvider
// for a network.
DeviceMap device_type_map_;
// Guid for the currently active network (if one exists).
std::string active_guid_;
// Remote for sending requests to the CrosNetworkConfig service.
mojo::Remote<network_config::mojom::CrosNetworkConfig>
remote_cros_network_config_;
@ -91,6 +107,10 @@ class NetworkHealthProvider
// Receiver for the CrosNetworkConfigObserver events.
mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver>
cros_network_config_observer_receiver_{this};
// Remotes for tracking observers that will be notified of changes to the
// list of active networks.
mojo::RemoteSet<mojom::NetworkListObserver> network_list_observers_;
};
} // namespace diagnostics

@ -27,6 +27,7 @@
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
@ -44,6 +45,28 @@ void ValidateManagedPropertiesSet(
EXPECT_EQ(managed_properties_guid, guid);
}
struct FakeNetworkListObserver : public mojom::NetworkListObserver {
void OnNetworkListChanged(const std::vector<std::string>& network_guids,
const std::string& active_guid) override {
fake_network_guids = std::move(network_guids);
fake_active_guid = active_guid;
network_list_changed_event_received_ = true;
}
mojo::PendingRemote<mojom::NetworkListObserver> pending_remote() {
return receiver.BindNewPipeAndPassRemote();
}
bool network_list_changed_event_received() {
return network_list_changed_event_received_;
}
std::vector<std::string> fake_network_guids;
std::string fake_active_guid;
bool network_list_changed_event_received_ = false;
mojo::Receiver<mojom::NetworkListObserver> receiver{this};
};
} // namespace
class NetworkHealthProviderTest : public testing::Test {
@ -170,7 +193,7 @@ TEST_F(NetworkHealthProviderTest, MultipleConnectedNetworksStoredInActiveList) {
SetupEthernetNetwork();
const std::vector<std::string>& network_guid_list =
network_health_provider_->GetNetworkGuidListForTesting();
network_health_provider_->GetNetworkGuidList();
ASSERT_EQ(2u, network_guid_list.size());
ASSERT_TRUE(base::Contains(network_guid_list, "wifi1_guid"));
ASSERT_TRUE(base::Contains(network_guid_list, "eth_guid"));
@ -181,7 +204,7 @@ TEST_F(NetworkHealthProviderTest, UnsupportedNetworkTypeIgnored) {
SetupVPNNetwork();
const std::vector<std::string>& network_guid_list =
network_health_provider_->GetNetworkGuidListForTesting();
network_health_provider_->GetNetworkGuidList();
ASSERT_TRUE(network_guid_list.empty());
}
@ -250,5 +273,89 @@ TEST_F(NetworkHealthProviderTest, ManagedPropertiesSetForMultipleNetwork) {
ValidateManagedPropertiesSet(network_properties_map, "eth_guid");
}
TEST_F(NetworkHealthProviderTest, NetworkListObserverSingleNetwork) {
ResetDevicesAndServices();
FakeNetworkListObserver fake_network_list_observer;
network_health_provider_->ObserveNetworkList(
fake_network_list_observer.pending_remote());
SetupEthernetNetwork();
std::vector<std::string> expected = {"eth_guid"};
EXPECT_EQ(1U, fake_network_list_observer.fake_network_guids.size());
EXPECT_EQ(fake_network_list_observer.fake_network_guids, expected);
EXPECT_EQ(fake_network_list_observer.fake_active_guid, "eth_guid");
EXPECT_EQ(fake_network_list_observer.network_list_changed_event_received(),
true);
}
TEST_F(NetworkHealthProviderTest, NetworkListObserverNoActiveNetwork) {
ResetDevicesAndServices();
FakeNetworkListObserver fake_network_list_observer;
network_health_provider_->ObserveNetworkList(
fake_network_list_observer.pending_remote());
SetupWiFiNetwork();
std::vector<std::string> expected = {"wifi1_guid"};
EXPECT_EQ(1U, fake_network_list_observer.fake_network_guids.size());
EXPECT_EQ(fake_network_list_observer.fake_network_guids, expected);
EXPECT_EQ(0U, fake_network_list_observer.fake_active_guid.size());
EXPECT_EQ(fake_network_list_observer.fake_active_guid, "");
EXPECT_EQ(fake_network_list_observer.network_list_changed_event_received(),
true);
}
TEST_F(NetworkHealthProviderTest, NetworkListObserverMultipleNetworks) {
ResetDevicesAndServices();
FakeNetworkListObserver fake_network_list_observer;
network_health_provider_->ObserveNetworkList(
fake_network_list_observer.pending_remote());
SetupEthernetNetwork();
SetupWiFiNetwork();
std::vector<std::string> expected = {"eth_guid", "wifi1_guid"};
EXPECT_EQ(2U, fake_network_list_observer.fake_network_guids.size());
EXPECT_EQ(fake_network_list_observer.fake_network_guids, expected);
EXPECT_EQ(fake_network_list_observer.fake_active_guid, "eth_guid");
EXPECT_EQ(fake_network_list_observer.network_list_changed_event_received(),
true);
}
TEST_F(NetworkHealthProviderTest, NetworkListObserverNoNetworks) {
ResetDevicesAndServices();
FakeNetworkListObserver fake_network_list_observer;
network_health_provider_->ObserveNetworkList(
fake_network_list_observer.pending_remote());
std::vector<std::string> expected;
EXPECT_EQ(0U, fake_network_list_observer.fake_network_guids.size());
EXPECT_EQ(fake_network_list_observer.fake_network_guids, expected);
EXPECT_EQ(0U, fake_network_list_observer.fake_active_guid.size());
EXPECT_EQ(fake_network_list_observer.fake_active_guid, "");
}
TEST_F(NetworkHealthProviderTest, ActiveGuidResetsWhenConnectionStateChanges) {
ResetDevicesAndServices();
FakeNetworkListObserver fake_network_list_observer;
network_health_provider_->ObserveNetworkList(
fake_network_list_observer.pending_remote());
SetupEthernetNetwork();
std::vector<std::string> expected = {"eth_guid"};
EXPECT_EQ(1U, fake_network_list_observer.fake_network_guids.size());
EXPECT_EQ(fake_network_list_observer.fake_network_guids, expected);
EXPECT_EQ(fake_network_list_observer.fake_active_guid, "eth_guid");
EXPECT_EQ(fake_network_list_observer.network_list_changed_event_received(),
true);
ResetDevicesAndServices();
EXPECT_EQ(0U, fake_network_list_observer.fake_active_guid.size());
EXPECT_EQ(fake_network_list_observer.fake_active_guid, "");
}
} // namespace diagnostics
} // namespace chromeos

@ -7,6 +7,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
sources = [
"input_data_provider.mojom",
"network_health_provider.mojom",
"system_data_provider.mojom",
"system_routine_controller.mojom",
]

@ -0,0 +1,24 @@
// Copyright 2021 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.
module chromeos.diagnostics.mojom;
import "mojo/public/mojom/base/string16.mojom";
// Implemented by clients that wish to receive a list of guids representing
// active networks as well as the guid for the network that is currently
// online.
interface NetworkListObserver {
// Fired when the list of active networks provided by CrosNetworkConfig
// changes.
OnNetworkListChanged(array<string> network_guids, string active_guid);
};
// Enables clients to receive networking information for WiFi, Ethernet,
// and Cellular connections. Implemented in the browser process and called
// by the Diagnostics SWA (a renderer process).
interface NetworkHealthProvider {
// Registers an observer to be notified on changes to active networks.
ObserveNetworkList(pending_remote<NetworkListObserver> observer);
};