Chromium Code Reviews| Index: talk/app/webrtc/peerconnectionfactory.cc |
| diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc |
| index 3524af7932a4f92f60da84e552f742d1a2aaa7ac..7a4a54c5a3e9a7604e9ad734da3b383e74e01d1e 100644 |
| --- a/talk/app/webrtc/peerconnectionfactory.cc |
| +++ b/talk/app/webrtc/peerconnectionfactory.cc |
| @@ -49,6 +49,64 @@ |
| namespace webrtc { |
| +namespace { |
| + |
| +class BlockingIdentityRequestObserver : public DTLSIdentityRequestObserver { |
| + public: |
| + BlockingIdentityRequestObserver( |
| + rtc::scoped_refptr<DtlsCertificate>* out_certificate) |
| + : has_been_called_(false), |
| + out_certificate_(out_certificate) { |
| + DCHECK(out_certificate_); |
| + } |
| + |
| + void OnFailure(int error) override { |
| + ReturnIdentity(nullptr); |
| + } |
| + void OnSuccess(const std::string& der_cert, |
| + const std::string& der_private_key) override { |
| + std::string pem_cert = rtc::SSLIdentity::DerToPem( |
| + rtc::kPemTypeCertificate, |
| + reinterpret_cast<const unsigned char*>(der_cert.data()), |
| + der_cert.length()); |
| + std::string pem_key = rtc::SSLIdentity::DerToPem( |
| + rtc::kPemTypeRsaPrivateKey, |
| + reinterpret_cast<const unsigned char*>(der_private_key.data()), |
| + der_private_key.length()); |
| + rtc::scoped_ptr<rtc::SSLIdentity> identity( |
| + rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); |
| + OnSuccessWithIdentityObj(identity.Pass()); |
| + } |
| + void OnSuccessWithIdentityObj( |
| + rtc::scoped_ptr<rtc::SSLIdentity> identity) override { |
| + ReturnIdentity(identity.Pass()); |
| + } |
| + |
| + void WaitForIdentity() { |
| + // Process messages while waiting for |has_been_called_| to become true. |
| + // If the service generating the identity is Posting to the current thread |
| + // then processing messages is necessary for identity generation to finish |
| + // (waiting without processing would block forever). |
| + while (!has_been_called_) { |
| + rtc::Thread::Current()->ProcessMessages(1); |
| + } |
| + } |
| + |
| + private: |
| + void ReturnIdentity(rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
| + if (identity.get()) |
| + *out_certificate_ = DtlsCertificate::Create(identity.Pass()); |
| + else |
| + *out_certificate_ = nullptr; |
| + has_been_called_ = true; |
| + } |
| + |
| + volatile bool has_been_called_; |
| + rtc::scoped_refptr<DtlsCertificate>* out_certificate_; |
| +}; |
| + |
| +} // anonymous namespace |
| + |
| rtc::scoped_refptr<PeerConnectionFactoryInterface> |
| CreatePeerConnectionFactory() { |
| rtc::scoped_refptr<PeerConnectionFactory> pc_factory( |
| @@ -205,15 +263,11 @@ PeerConnectionFactory::CreatePeerConnection( |
| const PeerConnectionInterface::RTCConfiguration& configuration, |
| const MediaConstraintsInterface* constraints, |
| PortAllocatorFactoryInterface* allocator_factory, |
| - DTLSIdentityServiceInterface* dtls_identity_service, |
| + rtc::scoped_refptr<webrtc::DtlsCertificate> certificate, |
| PeerConnectionObserver* observer) { |
| DCHECK(signaling_thread_->IsCurrent()); |
| DCHECK(allocator_factory || default_allocator_factory_); |
| - if (!dtls_identity_service) { |
| - dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get()); |
| - } |
| - |
| PortAllocatorFactoryInterface* chosen_allocator_factory = |
| allocator_factory ? allocator_factory : default_allocator_factory_.get(); |
| chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask); |
| @@ -224,13 +278,44 @@ PeerConnectionFactory::CreatePeerConnection( |
| configuration, |
| constraints, |
| chosen_allocator_factory, |
| - dtls_identity_service, |
| + certificate, |
| observer)) { |
| return NULL; |
| } |
| return PeerConnectionProxy::Create(signaling_thread(), pc); |
| } |
| +rtc::scoped_refptr<PeerConnectionInterface> |
| +PeerConnectionFactory::CreatePeerConnection( |
| + const PeerConnectionInterface::RTCConfiguration& configuration, |
| + const MediaConstraintsInterface* constraints, |
| + PortAllocatorFactoryInterface* allocator_factory, |
| + DTLSIdentityServiceInterface* dtls_identity_service, |
| + PeerConnectionObserver* observer) { |
|
hbos
2015/08/04 12:50:21
This version of CreatePeerConnection uses the old
|
| + DCHECK(signaling_thread_->IsCurrent()); |
| + |
| + if (!dtls_identity_service) { |
| + dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get()); |
| + } |
| + // TODO(hbos): This certificate generation is a blocking operation and does |
| + // not inform if the generation failed (but then a null certificate will be |
| + // passed and some failure will likely occur later). This function signature |
| + // only exists temporarily as to not break Chromium. It shall be removed ASAP. |
| + rtc::scoped_refptr<DtlsCertificate> certificate; |
| + rtc::scoped_refptr<BlockingIdentityRequestObserver> cert_blocking_observer( |
| + new rtc::RefCountedObject<BlockingIdentityRequestObserver>(&certificate)); |
| + dtls_identity_service->RequestIdentity( |
| + DtlsIdentityStore::kIdentityName, DtlsIdentityStore::kIdentityName, |
| + cert_blocking_observer.get()); |
| + cert_blocking_observer->WaitForIdentity(); |
| + // Having taken ownership of |dtls_identity_service| it is up to us to delete. |
| + delete dtls_identity_service; |
| + dtls_identity_service = nullptr; |
| + |
| + return CreatePeerConnection(configuration, constraints, allocator_factory, |
| + certificate, observer); |
| +} |
| + |
| rtc::scoped_refptr<MediaStreamInterface> |
| PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) { |
| DCHECK(signaling_thread_->IsCurrent()); |