| Index: content/renderer/media/rtc_certificate_generator.cc
|
| diff --git a/content/renderer/media/rtc_certificate_generator.cc b/content/renderer/media/rtc_certificate_generator.cc
|
| index 94b94fb1c899520cd8520b5bde5b9b1c9ebc4e6a..9b889b4ef8b2b92a1e66b691c45abd0b07d5513b 100644
|
| --- a/content/renderer/media/rtc_certificate_generator.cc
|
| +++ b/content/renderer/media/rtc_certificate_generator.cc
|
| @@ -9,12 +9,11 @@
|
|
|
| #include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| #include "content/renderer/media/peer_connection_identity_store.h"
|
| #include "content/renderer/media/rtc_certificate.h"
|
| #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
|
| #include "content/renderer/render_thread_impl.h"
|
| -#include "third_party/webrtc/base/rtccertificate.h"
|
| -#include "third_party/webrtc/base/scoped_ref_ptr.h"
|
| #include "url/gurl.h"
|
|
|
| namespace content {
|
| @@ -35,7 +34,9 @@ rtc::KeyParams WebRTCKeyParamsToKeyParams(
|
| }
|
| }
|
|
|
| -// Observer used by RTCCertificateGenerator::generateCertificate.
|
| +// Observer used by RTCCertificateGenerator::generateCertificate, and handler
|
| +// of an identity request using |PeerConnectionIdentityStore|. An observer
|
| +// instance is only valid for one request.
|
| class RTCCertificateIdentityObserver
|
| : public webrtc::DtlsIdentityRequestObserver {
|
| public:
|
| @@ -44,26 +45,40 @@ class RTCCertificateIdentityObserver
|
| const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread)
|
| : main_thread_(main_thread),
|
| signaling_thread_(signaling_thread),
|
| - observer_(nullptr) {
|
| + request_identity_called_(false),
|
| + request_event_(false, false) {
|
| DCHECK(main_thread_);
|
| DCHECK(signaling_thread_);
|
| }
|
| ~RTCCertificateIdentityObserver() override {}
|
|
|
| - // Perform |store|->RequestIdentity with this identity observer and ensure
|
| - // that this identity observer is not deleted until the request has completed
|
| - // by holding on to a reference to itself for the duration of the request.
|
| + void WaitForRequest() const {
|
| + request_event_.Wait();
|
| + }
|
| +
|
| + // Thread safety: Make sure you have waited for the request to completed
|
| + // before you obtain the result. See |WaitForRequest|. Alternatively the
|
| + // result is returned to the |observer|, no waiting involved.
|
| + const scoped_refptr<rtc::RTCCertificate>& result() const {
|
| + return result_;
|
| + }
|
| +
|
| + // Perform |store|->RequestIdentity with |this| identity observer and ensure
|
| + // that |this| identity observer is not deleted until the request has
|
| + // completed by holding on to a reference to itself for the duration of the
|
| + // request. The |observer| is optional, see |request_event| and |Result|.
|
| + // |RequestIdentity| can only be called once per observer instance.
|
| void RequestIdentity(
|
| - const blink::WebRTCKeyParams& key_params,
|
| + const rtc::KeyParams& key_params,
|
| const GURL& url,
|
| const GURL& first_party_for_cookies,
|
| const rtc::Optional<uint64_t>& expires_ms,
|
| std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
|
| DCHECK(main_thread_->BelongsToCurrentThread());
|
| - DCHECK(!observer_) << "Already have a RequestIdentity in progress.";
|
| + DCHECK(!request_identity_called_) << "Only one RequestIdentity is allowed.";
|
| + request_identity_called_ = true;
|
| key_params_ = key_params;
|
| observer_ = std::move(observer);
|
| - DCHECK(observer_);
|
| // Identity request must be performed on the WebRTC signaling thread.
|
| signaling_thread_->PostTask(FROM_HERE, base::Bind(
|
| &RTCCertificateIdentityObserver::RequestIdentityOnWebRtcSignalingThread,
|
| @@ -79,16 +94,14 @@ class RTCCertificateIdentityObserver
|
| std::unique_ptr<PeerConnectionIdentityStore> store(
|
| new PeerConnectionIdentityStore(main_thread_, signaling_thread_, url,
|
| first_party_for_cookies));
|
| - // Request identity with |this| as the observer. OnSuccess/OnFailure will be
|
| - // called asynchronously.
|
| - store->RequestIdentity(WebRTCKeyParamsToKeyParams(key_params_),
|
| - expires_ms, this);
|
| + // Request identity with |this| as the observer. |OnSuccess|/|OnFailure|
|
| + // will be called asynchronously.
|
| + store->RequestIdentity(key_params_, expires_ms, this);
|
| }
|
|
|
| // webrtc::DtlsIdentityRequestObserver implementation.
|
| void OnFailure(int error) override {
|
| DCHECK(signaling_thread_->BelongsToCurrentThread());
|
| - DCHECK(observer_);
|
| main_thread_->PostTask(FROM_HERE, base::Bind(
|
| &RTCCertificateIdentityObserver::DoCallbackOnMainThread,
|
| this, nullptr));
|
| @@ -108,25 +121,28 @@ class RTCCertificateIdentityObserver
|
| }
|
| void OnSuccess(std::unique_ptr<rtc::SSLIdentity> identity) override {
|
| DCHECK(signaling_thread_->BelongsToCurrentThread());
|
| - DCHECK(observer_);
|
| rtc::scoped_refptr<rtc::RTCCertificate> certificate =
|
| rtc::RTCCertificate::Create(std::move(identity));
|
| - main_thread_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&RTCCertificateIdentityObserver::DoCallbackOnMainThread,
|
| - this, base::Passed(base::WrapUnique(
|
| - new RTCCertificate(certificate)))));
|
| + result_ = certificate;
|
| + request_event_.Signal();
|
| + if (observer_) {
|
| + main_thread_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RTCCertificateIdentityObserver::DoCallbackOnMainThread,
|
| + this, certificate));
|
| + }
|
| }
|
|
|
| void DoCallbackOnMainThread(
|
| - std::unique_ptr<blink::WebRTCCertificate> certificate) {
|
| + rtc::scoped_refptr<rtc::RTCCertificate> certificate) {
|
| DCHECK(main_thread_->BelongsToCurrentThread());
|
| DCHECK(observer_);
|
| - if (certificate)
|
| - observer_->onSuccess(std::move(certificate));
|
| - else
|
| + if (certificate) {
|
| + observer_->onSuccess(std::unique_ptr<blink::WebRTCCertificate>(
|
| + new RTCCertificate(certificate)));
|
| + } else {
|
| observer_->onError();
|
| - observer_.reset();
|
| + }
|
| }
|
|
|
| // The main thread is the renderer thread.
|
| @@ -134,8 +150,11 @@ class RTCCertificateIdentityObserver
|
| // The signaling thread is a WebRTC thread used to invoke
|
| // PeerConnectionIdentityStore::RequestIdentity on, as is required.
|
| const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
|
| - blink::WebRTCKeyParams key_params_;
|
| + bool request_identity_called_;
|
| + rtc::KeyParams key_params_;
|
| std::unique_ptr<blink::WebRTCCertificateCallback> observer_;
|
| + mutable base::WaitableEvent request_event_;
|
| + scoped_refptr<rtc::RTCCertificate> result_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(RTCCertificateIdentityObserver);
|
| };
|
| @@ -185,13 +204,41 @@ void RTCCertificateGenerator::generateCertificateWithOptionalExpiration(
|
| new rtc::RefCountedObject<RTCCertificateIdentityObserver>(
|
| main_thread, signaling_thread));
|
| // |identity_observer| lives until request has completed.
|
| - identity_observer->RequestIdentity(key_params, url, first_party_for_cookies,
|
| - expires_ms, std::move(observer));
|
| + identity_observer->RequestIdentity(
|
| + WebRTCKeyParamsToKeyParams(key_params), url, first_party_for_cookies,
|
| + expires_ms, std::move(observer));
|
| #else
|
| observer->onError();
|
| #endif
|
| }
|
|
|
| +scoped_refptr<rtc::RTCCertificate>
|
| +RTCCertificateGenerator::generateCertificateAndWait(
|
| + const rtc::KeyParams& key_params,
|
| + const rtc::Optional<uint64_t>& expires_ms) {
|
| +#if defined(ENABLE_WEBRTC)
|
| + const scoped_refptr<base::SingleThreadTaskRunner> main_thread =
|
| + base::ThreadTaskRunnerHandle::Get();
|
| +
|
| + PeerConnectionDependencyFactory* pc_dependency_factory =
|
| + RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
|
| + pc_dependency_factory->EnsureInitialized();
|
| + const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread =
|
| + pc_dependency_factory->GetWebRtcSignalingThread();
|
| +
|
| + scoped_refptr<RTCCertificateIdentityObserver> identity_observer(
|
| + new rtc::RefCountedObject<RTCCertificateIdentityObserver>(
|
| + main_thread, signaling_thread));
|
| + // Don't care about URL origin parameters, using empty URL.
|
| + identity_observer->RequestIdentity(key_params, GURL(), GURL(), expires_ms,
|
| + nullptr);
|
| + identity_observer->WaitForRequest();
|
| + return identity_observer->result();
|
| +#else
|
| + return nullptr;
|
| +#endif
|
| +}
|
| +
|
| bool RTCCertificateGenerator::isSupportedKeyParams(
|
| const blink::WebRTCKeyParams& key_params) {
|
| return WebRTCKeyParamsToKeyParams(key_params).IsValid();
|
|
|