Index: remoting/protocol/ice_transport_factory.cc |
diff --git a/remoting/protocol/ice_transport_factory.cc b/remoting/protocol/ice_transport_factory.cc |
index 1cca9bedeb415bf12be027b12594ec8f5bf88d91..a4bc94dbe95dc7d36fabfc8b9b5f0a24f5d7f85f 100644 |
--- a/remoting/protocol/ice_transport_factory.cc |
+++ b/remoting/protocol/ice_transport_factory.cc |
@@ -4,33 +4,90 @@ |
#include "remoting/protocol/ice_transport_factory.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/thread_task_runner_handle.h" |
#include "remoting/protocol/ice_transport_session.h" |
-#include "remoting/protocol/libjingle_transport_factory.h" |
#include "third_party/webrtc/p2p/client/httpportallocator.h" |
namespace remoting { |
namespace protocol { |
+// Get fresh STUN/Relay configuration every hour. |
+static const int kJingleInfoUpdatePeriodSeconds = 3600; |
+ |
IceTransportFactory::IceTransportFactory( |
SignalStrategy* signal_strategy, |
scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator, |
const NetworkSettings& network_settings, |
TransportRole role) |
- : libjingle_transport_factory_( |
- new LibjingleTransportFactory(signal_strategy, |
- port_allocator.Pass(), |
- network_settings, |
- role)) {} |
-IceTransportFactory::~IceTransportFactory() {} |
- |
-void IceTransportFactory::PrepareTokens() { |
- libjingle_transport_factory_->PrepareTokens(); |
+ : signal_strategy_(signal_strategy), |
+ port_allocator_(port_allocator.Pass()), |
+ network_settings_(network_settings), |
+ role_(role) {} |
+ |
+IceTransportFactory::~IceTransportFactory() { |
+ // This method may be called in response to a libjingle signal, so |
+ // libjingle objects must be deleted asynchronously. |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
+ base::ThreadTaskRunnerHandle::Get(); |
+ task_runner->DeleteSoon(FROM_HERE, port_allocator_.release()); |
} |
scoped_ptr<TransportSession> |
IceTransportFactory::CreateTransportSession() { |
- return make_scoped_ptr( |
- new IceTransportSession(libjingle_transport_factory_.get())); |
+ scoped_ptr<IceTransportSession> result( |
+ new IceTransportSession(port_allocator_.get(), network_settings_, role_)); |
+ |
+ EnsureFreshJingleInfo(); |
+ |
+ // If there is a pending |jingle_info_request_| delay starting the new |
+ // transport until the request is finished. |
+ if (jingle_info_request_) { |
+ on_jingle_info_callbacks_.push_back(result->GetCanStartClosure()); |
+ } else { |
+ result->GetCanStartClosure().Run(); |
+ } |
+ |
+ return result.Pass(); |
+} |
+ |
+void IceTransportFactory::EnsureFreshJingleInfo() { |
+ uint32 stun_or_relay_flags = NetworkSettings::NAT_TRAVERSAL_STUN | |
+ NetworkSettings::NAT_TRAVERSAL_RELAY; |
+ if (!(network_settings_.flags & stun_or_relay_flags) || |
+ jingle_info_request_) { |
+ return; |
+ } |
+ |
+ if (last_jingle_info_update_time_.is_null() || |
+ base::TimeTicks::Now() - last_jingle_info_update_time_ > |
+ base::TimeDelta::FromSeconds(kJingleInfoUpdatePeriodSeconds)) { |
+ jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); |
+ jingle_info_request_->Send(base::Bind( |
+ &IceTransportFactory::OnJingleInfo, base::Unretained(this))); |
+ } |
+} |
+ |
+void IceTransportFactory::OnJingleInfo( |
+ const std::string& relay_token, |
+ const std::vector<std::string>& relay_hosts, |
+ const std::vector<rtc::SocketAddress>& stun_hosts) { |
+ if (!relay_token.empty() && !relay_hosts.empty()) { |
+ port_allocator_->SetRelayHosts(relay_hosts); |
+ port_allocator_->SetRelayToken(relay_token); |
+ } |
+ if (!stun_hosts.empty()) { |
+ port_allocator_->SetStunHosts(stun_hosts); |
+ } |
+ |
+ jingle_info_request_.reset(); |
+ if ((!relay_token.empty() && !relay_hosts.empty()) || !stun_hosts.empty()) |
+ last_jingle_info_update_time_ = base::TimeTicks::Now(); |
+ |
+ while (!on_jingle_info_callbacks_.empty()) { |
+ on_jingle_info_callbacks_.begin()->Run(); |
+ on_jingle_info_callbacks_.pop_front(); |
+ } |
} |
} // namespace protocol |