blob: c29fdda3a9c0ae97f103992fe6e5b03b52d13f0c [file] [log] [blame]
// Copyright (c) 2012 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 "content/renderer/p2p/socket_dispatcher.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "content/child/child_process.h"
#include "content/child/child_thread_impl.h"
#include "content/public/common/service_names.mojom.h"
#include "content/renderer/p2p/network_list_observer.h"
#include "content/renderer/p2p/socket_client_impl.h"
#include "content/renderer/render_view_impl.h"
#include "services/network/public/cpp/p2p_param_traits.h"
#include "services/service_manager/public/cpp/connector.h"
namespace content {
P2PSocketDispatcher::P2PSocketDispatcher()
: main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
network_list_observers_(
new base::ObserverListThreadSafe<NetworkListObserver>()),
network_notification_client_binding_(this) {
}
P2PSocketDispatcher::~P2PSocketDispatcher() {
}
void P2PSocketDispatcher::AddNetworkListObserver(
NetworkListObserver* network_list_observer) {
network_list_observers_->AddObserver(network_list_observer);
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&P2PSocketDispatcher::RequestNetworkEventsIfNecessary,
this));
}
void P2PSocketDispatcher::RemoveNetworkListObserver(
NetworkListObserver* network_list_observer) {
network_list_observers_->RemoveObserver(network_list_observer);
}
scoped_refptr<network::mojom::ThreadSafeP2PSocketManagerPtr>
P2PSocketDispatcher::GetP2PSocketManager() {
base::AutoLock lock(p2p_socket_manager_lock_);
if (!thread_safe_p2p_socket_manager_) {
network::mojom::P2PSocketManagerPtr p2p_socket_manager;
p2p_socket_manager_request_ = mojo::MakeRequest(&p2p_socket_manager);
p2p_socket_manager.set_connection_error_handler(base::BindOnce(
&P2PSocketDispatcher::OnConnectionError, base::Unretained(this)));
thread_safe_p2p_socket_manager_ =
network::mojom::ThreadSafeP2PSocketManagerPtr::Create(
std::move(p2p_socket_manager));
}
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&P2PSocketDispatcher::RequestInterfaceIfNecessary, this));
return thread_safe_p2p_socket_manager_;
}
void P2PSocketDispatcher::NetworkListChanged(
const std::vector<net::NetworkInterface>& networks,
const net::IPAddress& default_ipv4_local_address,
const net::IPAddress& default_ipv6_local_address) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
networks_ = networks;
default_ipv4_local_address_ = default_ipv4_local_address;
default_ipv6_local_address_ = default_ipv6_local_address;
network_list_observers_->Notify(
FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks,
default_ipv4_local_address, default_ipv6_local_address);
}
void P2PSocketDispatcher::RequestInterfaceIfNecessary() {
if (!p2p_socket_manager_request_.is_pending())
return;
ChildThreadImpl::current()->GetConnector()->BindInterface(
mojom::kBrowserServiceName, std::move(p2p_socket_manager_request_));
}
void P2PSocketDispatcher::RequestNetworkEventsIfNecessary() {
if (network_notification_client_binding_.is_bound()) {
network_list_observers_->Notify(
FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks_,
default_ipv4_local_address_, default_ipv6_local_address_);
} else {
network::mojom::P2PNetworkNotificationClientPtr network_notification_client;
network_notification_client_binding_.Bind(
mojo::MakeRequest(&network_notification_client));
GetP2PSocketManager()->get()->StartNetworkNotifications(
std::move(network_notification_client));
}
}
void P2PSocketDispatcher::OnConnectionError() {
base::AutoLock lock(p2p_socket_manager_lock_);
thread_safe_p2p_socket_manager_.reset();
}
} // namespace content