// 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 #include #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 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 receiver) { receivers_.Add(this, std::move(receiver)); } void NetworkChangeManager::RequestNotifications( mojo::PendingRemote client_pending_remote) { mojo::Remote 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) || 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( 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& 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