Commit 2eb17bcb authored by Haines Sy's avatar Haines Sy Committed by Commit Bot

[fuchsia] Fix NetworkChangeNotifier handling of initial state.

The NetworkChangeNotifier base class creates and initializes a
NetworkChangeCalculator which synthesizes high-level network
change notification events. Because it is created before the
derived NetworkChangeNotifierFuchsia reads the initial network
state, events must be dispatched for that initial state, for
the NetworkChangeCalculator to be up-to-date.

Bug: b/142796913
Change-Id: I51a319d0e5925721c81d7bb4b3eb15521dd1ba91
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1880449
Commit-Queue: Haines Sy <hainesy@google.com>
Reviewed-by: default avatarWez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709770}
parent 56db93f8
......@@ -50,7 +50,9 @@ NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia(
std::vector<fuchsia::netstack::RouteTableEntry> routes;
status = sync_netstack->GetRouteTable(&routes);
ZX_CHECK(status == ZX_OK, status) << "synchronous GetInterfaces()";
OnRouteTableReceived(std::move(interfaces), std::move(routes), false);
// This will Notify internal observers like the NetworkChangeCalculator
// to be properly updated.
OnRouteTableReceived(std::move(interfaces), std::move(routes));
// Re-wrap Netstack back into an asynchronous pointer.
netstack_.Bind(sync_netstack.Unbind());
......@@ -83,15 +85,13 @@ void NetworkChangeNotifierFuchsia::ProcessInterfaceList(
netstack_->GetRouteTable(
[this, interfaces = std::move(interfaces)](
std::vector<fuchsia::netstack::RouteTableEntry> route_table) mutable {
OnRouteTableReceived(std::move(interfaces), std::move(route_table),
true);
OnRouteTableReceived(std::move(interfaces), std::move(route_table));
});
}
void NetworkChangeNotifierFuchsia::OnRouteTableReceived(
std::vector<fuchsia::netstack::NetInterface> interfaces,
std::vector<fuchsia::netstack::RouteTableEntry> route_table,
bool notify_observers) {
std::vector<fuchsia::netstack::RouteTableEntry> route_table) {
// Create a set of NICs that have default routes (ie 0.0.0.0).
base::flat_set<uint32_t> default_route_ids;
for (const auto& route : route_table) {
......@@ -142,14 +142,12 @@ void NetworkChangeNotifierFuchsia::OnRouteTableReceived(
if (addresses != cached_addresses_) {
std::swap(cached_addresses_, addresses);
if (notify_observers)
NotifyObserversOfIPAddressChange();
NotifyObserversOfIPAddressChange();
}
if (connection_type != cached_connection_type_) {
base::subtle::Release_Store(&cached_connection_type_, connection_type);
if (notify_observers)
NotifyObserversOfConnectionTypeChange();
NotifyObserversOfConnectionTypeChange();
}
}
......
......@@ -51,8 +51,7 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierFuchsia
// connection type changes are detected.
void OnRouteTableReceived(
std::vector<fuchsia::netstack::NetInterface> interfaces,
std::vector<fuchsia::netstack::RouteTableEntry> table,
bool notify_observers);
std::vector<fuchsia::netstack::RouteTableEntry> table);
// Bitmap of required features for an interface to be taken into account. The
// features are defined in fuchsia::hardware::ethernet.
......
......@@ -201,6 +201,12 @@ class MockIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver {
MOCK_METHOD0(OnIPAddressChanged, void());
};
class MockNetworkChangeObserver
: public NetworkChangeNotifier::NetworkChangeObserver {
public:
MOCK_METHOD1(OnNetworkChanged, void(NetworkChangeNotifier::ConnectionType));
};
} // namespace
class NetworkChangeNotifierFuchsiaTest : public testing::Test {
......@@ -253,6 +259,8 @@ class NetworkChangeNotifierFuchsiaTest : public testing::Test {
base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
testing::StrictMock<MockConnectionTypeObserver> observer_;
testing::StrictMock<MockIPAddressObserver> ip_observer_;
testing::StrictMock<MockNetworkChangeObserver> network_change_observer_;
fuchsia::netstack::NetstackPtr netstack_ptr_;
FakeNetstackAsync netstack_;
......@@ -273,6 +281,32 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, InitialState) {
notifier_->GetCurrentConnectionType());
}
TEST_F(NetworkChangeNotifierFuchsiaTest, NotifyNetworkChangeOnInitialIPChange) {
netstack_.PushInterface(
CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp,
fuchsia::hardware::ethernet::INFO_FEATURE_WLAN,
CreateIPv4Address(169, 254, 0, 1),
CreateIPv4Address(255, 255, 255, 0), {}));
CreateNotifier();
// Add and remove network_change_observer_ since it's only used in this method
// gtest gives warnings on unused mocks if put into setup/teardown.
NetworkChangeNotifier::AddNetworkChangeObserver(&network_change_observer_);
EXPECT_CALL(network_change_observer_,
OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE));
EXPECT_CALL(network_change_observer_,
OnNetworkChanged(NetworkChangeNotifier::CONNECTION_WIFI));
EXPECT_CALL(ip_observer_, OnIPAddressChanged());
// Changing the IP address will now trigger network change as well since it is
// currently out of sync
netstack_.PushInterface(CreateNetInterface(
kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp,
fuchsia::hardware::ethernet::INFO_FEATURE_WLAN,
CreateIPv4Address(10, 0, 0, 1), CreateIPv4Address(255, 255, 0, 0), {}));
NetstackNotifyInterfacesAndWaitForGetRouteTable();
NetworkChangeNotifier::RemoveNetworkChangeObserver(&network_change_observer_);
}
TEST_F(NetworkChangeNotifierFuchsiaTest, NoChange) {
netstack_.PushInterface(
CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment