blob: 3009cdfc380207a10df08e52b0ef2fa77c259f34 [file] [log] [blame]
// Copyright 2017 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 "services/network/network_change_manager.h"
#include <algorithm>
#include <utility>
#include "base/bind.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_change_notifier_posix.h"
namespace network {
NetworkChangeManager::NetworkChangeManager(
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier)
: network_change_notifier_(std::move(network_change_notifier)) {
net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
connection_type_ =
mojom::ConnectionType(net::NetworkChangeNotifier::GetConnectionType());
}
NetworkChangeManager::~NetworkChangeManager() {
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}
void NetworkChangeManager::AddReceiver(
mojo::PendingReceiver<mojom::NetworkChangeManager> receiver) {
receivers_.Add(this, std::move(receiver));
}
void NetworkChangeManager::RequestNotifications(
mojo::PendingRemote<mojom::NetworkChangeManagerClient>
client_pending_remote) {
mojo::Remote<mojom::NetworkChangeManagerClient> client_remote(
std::move(client_pending_remote));
client_remote.set_disconnect_handler(base::BindOnce(
&NetworkChangeManager::NotificationPipeBroken,
// base::Unretained is safe as destruction of the
// NetworkChangeManager will also destroy the
// |clients_| list (which this object will be
// inserted into, below), which will destroy the
// client_remote, rendering this callback moot.
base::Unretained(this), base::Unretained(client_remote.get())));
client_remote->OnInitialConnectionType(connection_type_);
clients_.push_back(std::move(client_remote));
}
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID)
void NetworkChangeManager::OnNetworkChanged(
bool dns_changed,
bool ip_address_changed,
bool connection_type_changed,
mojom::ConnectionType new_connection_type,
bool connection_subtype_changed,
mojom::ConnectionSubtype new_connection_subtype) {
// network_change_notifier_ can be null in unit tests.
if (!network_change_notifier_)
return;
net::NetworkChangeNotifierPosix* notifier =
static_cast<net::NetworkChangeNotifierPosix*>(
network_change_notifier_.get());
if (dns_changed)
notifier->OnDNSChanged();
if (ip_address_changed)
notifier->OnIPAddressChanged();
if (connection_type_changed) {
notifier->OnConnectionChanged(
net::NetworkChangeNotifier::ConnectionType(new_connection_type));
}
if (connection_type_changed || connection_subtype_changed) {
notifier->OnConnectionSubtypeChanged(
net::NetworkChangeNotifier::ConnectionType(new_connection_type),
net::NetworkChangeNotifier::ConnectionSubtype(new_connection_subtype));
}
}
#endif
size_t NetworkChangeManager::GetNumClientsForTesting() const {
return clients_.size();
}
void NetworkChangeManager::NotificationPipeBroken(
mojom::NetworkChangeManagerClient* client) {
clients_.erase(std::find_if(
clients_.begin(), clients_.end(),
[client](mojo::Remote<mojom::NetworkChangeManagerClient>& remote) {
return remote.get() == client;
}));
}
void NetworkChangeManager::OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) {
connection_type_ = mojom::ConnectionType(type);
for (const auto& client : clients_) {
client->OnNetworkChanged(connection_type_);
}
}
} // namespace network