blob: 47d39b7cb0e7b8a5bf4a8b56048eb25154fbbc9d [file] [log] [blame]
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/pc/ortcfactory.h"
#include <string>
#include <utility> // For std::move.
#include "webrtc/base/bind.h"
#include "webrtc/base/asyncpacketsocket.h"
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
#include "webrtc/p2p/base/udptransport.h"
namespace webrtc {
// static
std::unique_ptr<OrtcFactoryInterface> OrtcFactoryInterface::Create(
rtc::Thread* network_thread,
rtc::Thread* signaling_thread,
rtc::NetworkManager* network_manager,
rtc::PacketSocketFactory* socket_factory) {
// Hop to signaling thread if needed.
if (signaling_thread && !signaling_thread->IsCurrent()) {
return signaling_thread->Invoke<std::unique_ptr<OrtcFactoryInterface>>(
RTC_FROM_HERE,
rtc::Bind(&OrtcFactoryInterface::Create, network_thread,
signaling_thread, network_manager, socket_factory));
}
OrtcFactory* new_factory =
new OrtcFactory(network_thread, signaling_thread,
network_manager, socket_factory);
// Return a proxy so that any calls on the returned object (including
// destructor) happen on the signaling thread.
return OrtcFactoryProxy::Create(new_factory->signaling_thread(),
new_factory->network_thread(), new_factory);
}
OrtcFactory::OrtcFactory(rtc::Thread* network_thread,
rtc::Thread* signaling_thread,
rtc::NetworkManager* network_manager,
rtc::PacketSocketFactory* socket_factory)
: network_thread_(network_thread),
signaling_thread_(signaling_thread),
network_manager_(network_manager),
socket_factory_(socket_factory) {
if (!network_thread_) {
owned_network_thread_ = rtc::Thread::CreateWithSocketServer();
owned_network_thread_->Start();
network_thread_ = owned_network_thread_.get();
}
// The worker thread is created internally because it's an implementation
// detail, and consumers of the API don't need to really know about it.
owned_worker_thread_ = rtc::Thread::Create();
owned_worker_thread_->Start();
if (signaling_thread_) {
RTC_DCHECK_RUN_ON(signaling_thread_);
} else {
signaling_thread_ = rtc::Thread::Current();
if (!signaling_thread_) {
// If this thread isn't already wrapped by an rtc::Thread, create a
// wrapper and own it in this class.
signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
wraps_signaling_thread_ = true;
}
}
if (!network_manager_) {
owned_network_manager_.reset(new rtc::BasicNetworkManager());
network_manager_ = owned_network_manager_.get();
}
if (!socket_factory_) {
owned_socket_factory_.reset(
new rtc::BasicPacketSocketFactory(network_thread_));
socket_factory_ = owned_socket_factory_.get();
}
}
OrtcFactory::~OrtcFactory() {
RTC_DCHECK_RUN_ON(signaling_thread_);
if (wraps_signaling_thread_) {
rtc::ThreadManager::Instance()->UnwrapCurrentThread();
}
}
std::unique_ptr<UdpTransportInterface> OrtcFactory::CreateUdpTransport(
int family,
uint16_t min_port,
uint16_t max_port) {
if (!network_thread_->IsCurrent()) {
RTC_DCHECK_RUN_ON(signaling_thread_);
return network_thread_->Invoke<std::unique_ptr<UdpTransportInterface>>(
RTC_FROM_HERE, rtc::Bind(&OrtcFactory::CreateUdpTransport, this, family,
min_port, max_port));
}
std::unique_ptr<rtc::AsyncPacketSocket> socket(
socket_factory_->CreateUdpSocket(
rtc::SocketAddress(rtc::GetAnyIP(family), 0), min_port, max_port));
if (!socket) {
LOG(LS_WARNING) << "Local socket allocation failure.";
return nullptr;
}
LOG(LS_INFO) << "Created UDP socket with address "
<< socket->GetLocalAddress().ToSensitiveString() << ".";
// Use proxy so that calls to the returned object are invoked on the network
// thread.
return UdpTransportProxy::Create(
signaling_thread_, network_thread_,
new cricket::UdpTransport(std::string(), std::move(socket)));
}
} // namespace webrtc