diff options
author | jiayl@chromium.org <jiayl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-20 03:42:57 +0000 |
---|---|---|
committer | jiayl@chromium.org <jiayl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-20 03:42:57 +0000 |
commit | 921480f6d54a82a3819d308ed32548a3afba676b (patch) | |
tree | fe99793a80634f89eaef8cd6fc15d6ff7850e394 /content/renderer | |
parent | d2cf063e9e649cf4741725196451821d4d6d266a (diff) | |
download | chromium_src-921480f6d54a82a3819d308ed32548a3afba676b.zip chromium_src-921480f6d54a82a3819d308ed32548a3afba676b.tar.gz chromium_src-921480f6d54a82a3819d308ed32548a3afba676b.tar.bz2 |
Creates a WebRTCIdentityService instance per peer connection and passes it to libjingle.
Also adds a per renderer object WebRTCIdentityProxy to queue the pending requests and makes sure only one outstanding request at a time for a renderer. The requests are queued on the renderer side instead of the browser side to avoid a potential memory exhaustion attack by an evil renderer.
Removes request_id from the IPC as it's unnecessary now.
Renames WebRTCIdentityServiceHost to WebRTCIdentityProxyHost and adds unittest.
BUG=
Review URL: https://chromiumcodereview.appspot.com/19392004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212728 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer')
-rw-r--r-- | content/renderer/media/media_stream_dependency_factory.cc | 14 | ||||
-rw-r--r-- | content/renderer/media/peer_connection_identity_service.cc | 59 | ||||
-rw-r--r-- | content/renderer/media/peer_connection_identity_service.h | 49 | ||||
-rw-r--r-- | content/renderer/media/webrtc_identity_service.cc | 136 | ||||
-rw-r--r-- | content/renderer/media/webrtc_identity_service.h | 86 | ||||
-rw-r--r-- | content/renderer/media/webrtc_identity_service_unittest.cc | 210 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.cc | 3 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.h | 9 |
8 files changed, 500 insertions, 66 deletions
diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc index f15f103..27a0b2a 100644 --- a/content/renderer/media/media_stream_dependency_factory.cc +++ b/content/renderer/media/media_stream_dependency_factory.cc @@ -11,6 +11,7 @@ #include "base/synchronization/waitable_event.h" #include "content/public/common/content_switches.h" #include "content/renderer/media/media_stream_source_extra_data.h" +#include "content/renderer/media/peer_connection_identity_service.h" #include "content/renderer/media/rtc_media_constraints.h" #include "content/renderer/media/rtc_peer_connection_handler.h" #include "content/renderer/media/rtc_video_capturer.h" @@ -567,9 +568,16 @@ MediaStreamDependencyFactory::CreatePeerConnection( network_manager_, socket_factory_.get(), web_frame); - return pc_factory_->CreatePeerConnection( - ice_servers, constraints, pa_factory.get(), NULL, observer) - .get(); + + PeerConnectionIdentityService* identity_service = + new PeerConnectionIdentityService(GURL(web_frame->document().url().spec()) + .GetOrigin()); + + return pc_factory_->CreatePeerConnection(ice_servers, + constraints, + pa_factory.get(), + identity_service, + observer).get(); } scoped_refptr<webrtc::MediaStreamInterface> diff --git a/content/renderer/media/peer_connection_identity_service.cc b/content/renderer/media/peer_connection_identity_service.cc new file mode 100644 index 0000000..f7bc856 --- /dev/null +++ b/content/renderer/media/peer_connection_identity_service.cc @@ -0,0 +1,59 @@ +// Copyright 2013 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/media/peer_connection_identity_service.h" + +#include "content/renderer/media/webrtc_identity_service.h" +#include "content/renderer/render_thread_impl.h" + +namespace content { + +PeerConnectionIdentityService::PeerConnectionIdentityService(const GURL& origin) + : origin_(origin), pending_observer_(NULL), pending_request_id_(0) {} + +PeerConnectionIdentityService::~PeerConnectionIdentityService() { + if (pending_observer_) + RenderThreadImpl::current()->get_webrtc_identity_service() + ->CancelRequest(pending_request_id_); +} + +bool PeerConnectionIdentityService::RequestIdentity( + const std::string& identity_name, + const std::string& common_name, + webrtc::DTLSIdentityRequestObserver* observer) { + DCHECK(observer); + if (pending_observer_) + return false; + + pending_observer_ = observer; + pending_request_id_ = RenderThreadImpl::current() + ->get_webrtc_identity_service()->RequestIdentity( + origin_, + identity_name, + common_name, + base::Bind(&PeerConnectionIdentityService::OnIdentityReady, + base::Unretained(this)), + base::Bind(&PeerConnectionIdentityService::OnRequestFailed, + base::Unretained(this))); + return true; +} + +void PeerConnectionIdentityService::OnIdentityReady( + const std::string& certificate, + const std::string& private_key) { + pending_observer_->OnSuccess(certificate, private_key); + ResetPendingRequest(); +} + +void PeerConnectionIdentityService::OnRequestFailed(int error) { + pending_observer_->OnFailure(error); + ResetPendingRequest(); +} + +void PeerConnectionIdentityService::ResetPendingRequest() { + pending_observer_ = NULL; + pending_request_id_ = 0; +} + +} // namespace content diff --git a/content/renderer/media/peer_connection_identity_service.h b/content/renderer/media/peer_connection_identity_service.h new file mode 100644 index 0000000..a5092e3 --- /dev/null +++ b/content/renderer/media/peer_connection_identity_service.h @@ -0,0 +1,49 @@ +// Copyright 2013 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. + +#ifndef CONTENT_RENDERER_MEDIA_PEER_CONNECTION_IDENTITY_SERVICE_H_ +#define CONTENT_RENDERER_MEDIA_PEER_CONNECTION_IDENTITY_SERVICE_H_ + +#include <string> + +#include "base/basictypes.h" +#include "content/public/renderer/render_process_observer.h" +#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h" +#include "url/gurl.h" + +namespace content { + +// This class is associated with a peer connection and handles WebRTC DTLS +// identity requests by delegating to the per-renderer WebRTCIdentityProxy. +class PeerConnectionIdentityService + : public webrtc::DTLSIdentityServiceInterface { + public: + explicit PeerConnectionIdentityService(const GURL& origin); + virtual ~PeerConnectionIdentityService(); + + // webrtc::DTLSIdentityServiceInterface implementation. + virtual bool RequestIdentity( + const std::string& identity_name, + const std::string& common_name, + webrtc::DTLSIdentityRequestObserver* observer) OVERRIDE; + + private: + void OnIdentityReady(const std::string& certificate, + const std::string& private_key); + void OnRequestFailed(int error); + + void ResetPendingRequest(); + + // The origin of the DTLS connection. + GURL origin_; + talk_base::scoped_refptr<webrtc::DTLSIdentityRequestObserver> + pending_observer_; + int pending_request_id_; + + DISALLOW_COPY_AND_ASSIGN(PeerConnectionIdentityService); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_PEER_CONNECTION_IDENTITY_SERVICE_H_ diff --git a/content/renderer/media/webrtc_identity_service.cc b/content/renderer/media/webrtc_identity_service.cc index 7042c93..7e9e540 100644 --- a/content/renderer/media/webrtc_identity_service.cc +++ b/content/renderer/media/webrtc_identity_service.cc @@ -4,50 +4,89 @@ #include "content/renderer/media/webrtc_identity_service.h" -#include "base/atomic_sequence_num.h" #include "content/common/media/webrtc_identity_messages.h" #include "content/public/renderer/render_thread.h" +#include "net/base/net_errors.h" namespace content { -WebRTCIdentityService::WebRTCIdentityService(const GURL& origin) - : origin_(origin), pending_observer_(NULL), pending_request_id_(0) { - RenderThread::Get()->AddObserver(this); +WebRTCIdentityService::RequestInfo::RequestInfo( + int request_id, + const GURL& origin, + const std::string& identity_name, + const std::string& common_name, + const SuccessCallback& success_callback, + const FailureCallback& failure_callback) + : request_id(request_id), + origin(origin), + identity_name(identity_name), + common_name(common_name), + success_callback(success_callback), + failure_callback(failure_callback) {} + +WebRTCIdentityService::RequestInfo::~RequestInfo() {} + +WebRTCIdentityService::WebRTCIdentityService() : next_request_id_(1) { + // RenderThread::Get() could be NULL in unit tests. + if (RenderThread::Get()) + RenderThread::Get()->AddObserver(this); } WebRTCIdentityService::~WebRTCIdentityService() { - RenderThread::Get()->RemoveObserver(this); - if (pending_observer_) { - RenderThread::Get()->Send( - new WebRTCIdentityMsg_CancelRequest(pending_request_id_)); + // RenderThread::Get() could be NULL in unit tests. + if (RenderThread::Get()) { + RenderThread::Get()->RemoveObserver(this); + + if (!pending_requests_.empty()) { + RenderThread::Get()->Send(new WebRTCIdentityMsg_CancelRequest()); + } } } -bool WebRTCIdentityService::RequestIdentity( +int WebRTCIdentityService::RequestIdentity( + const GURL& origin, const std::string& identity_name, const std::string& common_name, - webrtc::DTLSIdentityRequestObserver* observer) { - // Static because the request id needs to be unique per renderer process - // across WebRTCIdentityService instances. - static base::AtomicSequenceNumber s_next_request_id; - - DCHECK(observer); - if (pending_observer_) - return false; - - pending_observer_ = observer; - pending_request_id_ = s_next_request_id.GetNext(); - RenderThread::Get()->Send(new WebRTCIdentityMsg_RequestIdentity( - pending_request_id_, origin_, identity_name, common_name)); - return true; + const SuccessCallback& success_callback, + const FailureCallback& failure_callback) { + int request_id = next_request_id_++; + + RequestInfo request_info(request_id, + origin, + identity_name, + common_name, + success_callback, + failure_callback); + + pending_requests_.push_back(request_info); + if (pending_requests_.size() == 1) + SendRequest(request_info); + + return request_id; +} + +void WebRTCIdentityService::CancelRequest(int request_id) { + std::deque<RequestInfo>::iterator it; + for (it = pending_requests_.begin(); it != pending_requests_.end(); ++it) { + if (it->request_id != request_id) + continue; + if (it != pending_requests_.begin()) { + pending_requests_.erase(it); + } else { + Send(new WebRTCIdentityMsg_CancelRequest()); + OnOutstandingRequestReturned(); + } + break; + } +} + +bool WebRTCIdentityService::Send(IPC::Message* message) { + // Unit tests should override this method to avoid null-ptr-deref. + return RenderThread::Get()->Send(message); } bool WebRTCIdentityService::OnControlMessageReceived( const IPC::Message& message) { - if (!pending_observer_) - return false; - - int old_pending_request_id = pending_request_id_; bool handled = true; IPC_BEGIN_MESSAGE_MAP(WebRTCIdentityService, message) IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_IdentityReady, OnIdentityReady) @@ -55,28 +94,39 @@ bool WebRTCIdentityService::OnControlMessageReceived( IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() - if (pending_request_id_ == old_pending_request_id) - handled = false; - return handled; } -void WebRTCIdentityService::OnIdentityReady(int request_id, - const std::string& certificate, +void WebRTCIdentityService::OnIdentityReady(const std::string& certificate, const std::string& private_key) { - if (request_id != pending_request_id_) - return; - pending_observer_->OnSuccess(certificate, private_key); - pending_observer_ = NULL; - pending_request_id_ = 0; + DCHECK(!pending_requests_.empty()); + pending_requests_.front().success_callback.Run(certificate, private_key); + OnOutstandingRequestReturned(); +} + +void WebRTCIdentityService::OnRequestFailed(int error) { + DCHECK(!pending_requests_.empty()); + pending_requests_.front().failure_callback.Run(error); + OnOutstandingRequestReturned(); } -void WebRTCIdentityService::OnRequestFailed(int request_id, int error) { - if (request_id != pending_request_id_) - return; - pending_observer_->OnFailure(error); - pending_observer_ = NULL; - pending_request_id_ = 0; +void WebRTCIdentityService::SendRequest(const RequestInfo& request_info) { + if (!Send(new WebRTCIdentityMsg_RequestIdentity(request_info.origin, + request_info.identity_name, + request_info.common_name))) { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&WebRTCIdentityService::OnRequestFailed, + base::Unretained(this), + net::ERR_UNEXPECTED)); + } +} + +void WebRTCIdentityService::OnOutstandingRequestReturned() { + pending_requests_.pop_front(); + + if (!pending_requests_.empty()) + SendRequest(pending_requests_.front()); } } // namespace content diff --git a/content/renderer/media/webrtc_identity_service.h b/content/renderer/media/webrtc_identity_service.h index 7ff18ba..3e6efa5 100644 --- a/content/renderer/media/webrtc_identity_service.h +++ b/content/renderer/media/webrtc_identity_service.h @@ -5,44 +5,90 @@ #ifndef CONTENT_RENDERER_MEDIA_WEBRTC_IDENTITY_SERVICE_H_ #define CONTENT_RENDERER_MEDIA_WEBRTC_IDENTITY_SERVICE_H_ +#include <deque> #include <string> #include "base/basictypes.h" +#include "base/callback.h" +#include "content/common/content_export.h" #include "content/public/renderer/render_process_observer.h" -#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h" #include "url/gurl.h" namespace content { // This class handles WebRTC DTLS identity requests by sending IPC messages to -// the browser process. -class WebRTCIdentityService : public webrtc::DTLSIdentityServiceInterface, - public RenderProcessObserver { +// the browser process. Only one request is sent to the browser at a time; other +// requests are queued and have to wait for the outstanding request to complete. +class CONTENT_EXPORT WebRTCIdentityService : public RenderProcessObserver { public: - explicit WebRTCIdentityService(const GURL& origin); + typedef base::Callback< + void(const std::string& certificate, const std::string& private_key)> + SuccessCallback; + + typedef base::Callback<void(int error)> FailureCallback; + + WebRTCIdentityService(); virtual ~WebRTCIdentityService(); - // WebRTCIdentityServiceInterface implementation. - virtual bool RequestIdentity(const std::string& identity_name, - const std::string& common_name, - webrtc::DTLSIdentityRequestObserver* observer) - OVERRIDE; + // Sends an identity request. + // + // |origin| is the origin of the caller; + // |identity_name| and |common_name| have the same meaning as in + // webrtc::DTLSIdentityServiceInterface::RequestIdentity; + // |success_callback| is the callback if the identity is successfully + // returned; + // |failure_callback| is the callback if the identity request fails. + // + // The request id is returned. It's unique within the renderer and can be used + // to cancel the request. + int RequestIdentity(const GURL& origin, + const std::string& identity_name, + const std::string& common_name, + const SuccessCallback& success_callback, + const FailureCallback& failure_callback); - private: - // RenderProcessObserver implementation. + // Cancels a previous request and the callbacks will not be called. + // If the |request_id| is not associated with the + // outstanding request or any queued request, this method does nothing. + // + // |request_id| is the request id returned from RequestIdentity. + void CancelRequest(int request_id); + + protected: + // For unittest to override. + virtual bool Send(IPC::Message* message); + // RenderProcessObserver implementation. Protected for testing. virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE; - void OnIdentityReady(int request_id, - const std::string& certificate, + private: + struct RequestInfo { + RequestInfo(int request_id, + const GURL& origin, + const std::string& identity_name, + const std::string& common_name, + const SuccessCallback& success_callback, + const FailureCallback& failure_callback); + ~RequestInfo(); + + int request_id; + GURL origin; + std::string identity_name; + std::string common_name; + SuccessCallback success_callback; + FailureCallback failure_callback; + }; + + // IPC message handlers. + void OnIdentityReady(const std::string& certificate, const std::string& private_key); + void OnRequestFailed(int error); + + void SendRequest(const RequestInfo& request_id); + void OnOutstandingRequestReturned(); - void OnRequestFailed(int request_id, int error); + std::deque<RequestInfo> pending_requests_; + int next_request_id_; - // The origin of the DTLS connection. - GURL origin_; - talk_base::scoped_refptr<webrtc::DTLSIdentityRequestObserver> - pending_observer_; - int pending_request_id_; DISALLOW_COPY_AND_ASSIGN(WebRTCIdentityService); }; diff --git a/content/renderer/media/webrtc_identity_service_unittest.cc b/content/renderer/media/webrtc_identity_service_unittest.cc new file mode 100644 index 0000000..d6bd169 --- /dev/null +++ b/content/renderer/media/webrtc_identity_service_unittest.cc @@ -0,0 +1,210 @@ +// Copyright 2013 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 <deque> + +#include "content/common/media/webrtc_identity_messages.h" +#include "content/renderer/media/webrtc_identity_service.h" +#include "ipc/ipc_message.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +static const char FAKE_ORIGIN[] = "http://fake.com"; +static const char FAKE_IDENTITY_NAME[] = "fake identity"; +static const char FAKE_COMMON_NAME[] = "fake common name"; +static const char FAKE_CERTIFICATE[] = "fake cert"; +static const char FAKE_PRIVATE_KEY[] = "fake private key"; +static const int FAKE_ERROR = 100; + +class WebRTCIdentityServiceForTest : public WebRTCIdentityService { + public: + virtual bool Send(IPC::Message* message) OVERRIDE { + messages_.push_back(*message); + delete message; + return true; + } + + virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE { + return WebRTCIdentityService::OnControlMessageReceived(message); + } + + IPC::Message GetLastMessage() { return messages_.back(); } + + int GetNumberOfMessages() { return messages_.size(); } + + void ClearMessages() { messages_.clear(); } + + private: + std::deque<IPC::Message> messages_; +}; + +class WebRTCIdentityServiceTest : public ::testing::Test { + public: + WebRTCIdentityServiceTest() + : service_(new WebRTCIdentityServiceForTest()), last_error_(0) {} + + protected: + void OnIdentityReady(const std::string& cert, const std::string& key) { + last_certificate_ = cert; + last_private_key_ = key; + } + + void OnRequestFailed(int error) { last_error_ = error; } + + void ResetRequestResult() { + last_certificate_ = ""; + last_private_key_ = ""; + last_error_ = 0; + } + + int RequestIdentity() { + return service_->RequestIdentity( + GURL(FAKE_ORIGIN), + FAKE_IDENTITY_NAME, + FAKE_COMMON_NAME, + base::Bind(&WebRTCIdentityServiceTest::OnIdentityReady, + base::Unretained(this)), + base::Bind(&WebRTCIdentityServiceTest::OnRequestFailed, + base::Unretained(this))); + } + + scoped_ptr<WebRTCIdentityServiceForTest> service_; + std::string last_certificate_; + std::string last_private_key_; + int last_error_; +}; + +} // namespace + +TEST_F(WebRTCIdentityServiceTest, TestSendRequest) { + RequestIdentity(); + + IPC::Message ipc = service_->GetLastMessage(); + EXPECT_EQ(ipc.type(), WebRTCIdentityMsg_RequestIdentity::ID); +} + +TEST_F(WebRTCIdentityServiceTest, TestSuccessCallback) { + RequestIdentity(); + + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_IdentityReady(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY)); + EXPECT_EQ(FAKE_CERTIFICATE, last_certificate_); + EXPECT_EQ(FAKE_PRIVATE_KEY, last_private_key_); +} + +TEST_F(WebRTCIdentityServiceTest, TestFailureCallback) { + RequestIdentity(); + + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_RequestFailed(FAKE_ERROR)); + EXPECT_EQ(FAKE_ERROR, last_error_); +} + +TEST_F(WebRTCIdentityServiceTest, TestCancelRequest) { + int request_id = RequestIdentity(); + service_->ClearMessages(); + + service_->CancelRequest(request_id); + + IPC::Message ipc = service_->GetLastMessage(); + EXPECT_EQ(ipc.type(), WebRTCIdentityMsg_CancelRequest::ID); +} + +TEST_F(WebRTCIdentityServiceTest, TestQueuedRequestSentAfterSuccess) { + RequestIdentity(); + RequestIdentity(); + EXPECT_EQ(1, service_->GetNumberOfMessages()); + service_->ClearMessages(); + + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_IdentityReady(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY)); + + IPC::Message ipc = service_->GetLastMessage(); + EXPECT_EQ(ipc.type(), WebRTCIdentityMsg_RequestIdentity::ID); +} + +TEST_F(WebRTCIdentityServiceTest, TestQueuedRequestSentAfterFailure) { + RequestIdentity(); + RequestIdentity(); + EXPECT_EQ(1, service_->GetNumberOfMessages()); + service_->ClearMessages(); + + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_RequestFailed(FAKE_ERROR)); + + IPC::Message ipc = service_->GetLastMessage(); + EXPECT_EQ(ipc.type(), WebRTCIdentityMsg_RequestIdentity::ID); +} + +TEST_F(WebRTCIdentityServiceTest, TestQueuedRequestSentAfterCancelOutstanding) { + int outstand_request_id = RequestIdentity(); + RequestIdentity(); + + EXPECT_EQ(1, service_->GetNumberOfMessages()); + service_->ClearMessages(); + + service_->CancelRequest(outstand_request_id); + + // Should have two messages sent: one for cancelling the outstanding request, + // one for requesting the queued request. + EXPECT_EQ(2, service_->GetNumberOfMessages()); + IPC::Message ipc = service_->GetLastMessage(); + EXPECT_EQ(ipc.type(), WebRTCIdentityMsg_RequestIdentity::ID); +} + +TEST_F(WebRTCIdentityServiceTest, TestCancelQueuedRequest) { + RequestIdentity(); + int queued_request_id = RequestIdentity(); + EXPECT_EQ(1, service_->GetNumberOfMessages()); + service_->ClearMessages(); + + service_->CancelRequest(queued_request_id); + + // Verifies that the queued request is not sent after the outstanding request + // returns. + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_IdentityReady(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY)); + + EXPECT_EQ(0, service_->GetNumberOfMessages()); +} + +TEST_F(WebRTCIdentityServiceTest, TestQueuedRequestSuccessCallback) { + RequestIdentity(); + RequestIdentity(); + + // Completes the outstanding request. + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_IdentityReady(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY)); + EXPECT_EQ(FAKE_CERTIFICATE, last_certificate_); + EXPECT_EQ(FAKE_PRIVATE_KEY, last_private_key_); + + ResetRequestResult(); + + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_IdentityReady(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY)); + EXPECT_EQ(FAKE_CERTIFICATE, last_certificate_); + EXPECT_EQ(FAKE_PRIVATE_KEY, last_private_key_); +} + +TEST_F(WebRTCIdentityServiceTest, TestQueuedRequestFailureCallback) { + RequestIdentity(); + RequestIdentity(); + + // Completes the outstanding request. + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_IdentityReady(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY)); + EXPECT_EQ(FAKE_CERTIFICATE, last_certificate_); + EXPECT_EQ(FAKE_PRIVATE_KEY, last_private_key_); + + ResetRequestResult(); + + service_->OnControlMessageReceived( + WebRTCIdentityHostMsg_RequestFailed(FAKE_ERROR)); + EXPECT_EQ(FAKE_ERROR, last_error_); +} + +} // namespace content diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 18218a7..3ce5a94 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -72,6 +72,7 @@ #include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include "content/renderer/media/video_capture_impl_manager.h" #include "content/renderer/media/video_capture_message_filter.h" +#include "content/renderer/media/webrtc_identity_service.h" #include "content/renderer/memory_benchmarking_extension.h" #include "content/renderer/p2p/socket_dispatcher.h" #include "content/renderer/plugin_channel_host.h" @@ -376,6 +377,8 @@ void RenderThreadImpl::Init() { p2p_socket_dispatcher_ = new P2PSocketDispatcher(GetIOMessageLoopProxy().get()); AddFilter(p2p_socket_dispatcher_.get()); + + webrtc_identity_service_.reset(new WebRTCIdentityService()); #endif // defined(ENABLE_WEBRTC) vc_manager_ = new VideoCaptureImplManager(); AddFilter(vc_manager_->video_capture_message_filter()); diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 561fcf6..54d60698 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h @@ -90,6 +90,7 @@ class RenderProcessObserver; class VideoCaptureImplManager; class WebDatabaseObserverImpl; class WebGraphicsContext3DCommandBufferImpl; +class WebRTCIdentityService; // The RenderThreadImpl class represents a background thread where RenderView // instances live. The RenderThread supports an API that is used by its @@ -287,6 +288,12 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, void PreCacheFontCharacters(const LOGFONT& log_font, const string16& str); #endif +#if defined(ENABLE_WEBRTC) + WebRTCIdentityService* get_webrtc_identity_service() { + return webrtc_identity_service_.get(); + } +#endif + // For producing custom V8 histograms. Custom histograms are produced if all // RenderViews share the same host, and the host is in the pre-specified set // of hosts we want to produce custom diagrams for. The name for a custom @@ -477,6 +484,8 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, scoped_ptr<base::MemoryPressureListener> memory_pressure_listener_; + scoped_ptr<WebRTCIdentityService> webrtc_identity_service_; + DISALLOW_COPY_AND_ASSIGN(RenderThreadImpl); }; |