1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/media/webrtc_identity_service.h"
7 #include "base/location.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "content/common/media/webrtc_identity_messages.h"
11 #include "content/public/renderer/render_thread.h"
12 #include "net/base/net_errors.h"
16 WebRTCIdentityService::RequestInfo::RequestInfo(
19 const std::string
& identity_name
,
20 const std::string
& common_name
,
21 const SuccessCallback
& success_callback
,
22 const FailureCallback
& failure_callback
)
23 : request_id(request_id
),
25 identity_name(identity_name
),
26 common_name(common_name
),
27 success_callback(success_callback
),
28 failure_callback(failure_callback
) {}
30 WebRTCIdentityService::RequestInfo::~RequestInfo() {}
32 WebRTCIdentityService::WebRTCIdentityService() : next_request_id_(1) {
33 // RenderThread::Get() could be NULL in unit tests.
34 if (RenderThread::Get())
35 RenderThread::Get()->AddObserver(this);
38 WebRTCIdentityService::~WebRTCIdentityService() {
39 // RenderThread::Get() could be NULL in unit tests.
40 if (RenderThread::Get()) {
41 RenderThread::Get()->RemoveObserver(this);
43 if (!pending_requests_
.empty()) {
44 RenderThread::Get()->Send(new WebRTCIdentityMsg_CancelRequest());
49 int WebRTCIdentityService::RequestIdentity(
51 const std::string
& identity_name
,
52 const std::string
& common_name
,
53 const SuccessCallback
& success_callback
,
54 const FailureCallback
& failure_callback
) {
55 int request_id
= next_request_id_
++;
57 RequestInfo
request_info(request_id
,
64 pending_requests_
.push_back(request_info
);
65 if (pending_requests_
.size() == 1)
66 SendRequest(request_info
);
71 void WebRTCIdentityService::CancelRequest(int request_id
) {
72 std::deque
<RequestInfo
>::iterator it
;
73 for (it
= pending_requests_
.begin(); it
!= pending_requests_
.end(); ++it
) {
74 if (it
->request_id
!= request_id
)
76 if (it
!= pending_requests_
.begin()) {
77 pending_requests_
.erase(it
);
79 Send(new WebRTCIdentityMsg_CancelRequest());
80 OnOutstandingRequestReturned();
86 bool WebRTCIdentityService::Send(IPC::Message
* message
) {
87 // Unit tests should override this method to avoid null-ptr-deref.
88 return RenderThread::Get()->Send(message
);
91 bool WebRTCIdentityService::OnControlMessageReceived(
92 const IPC::Message
& message
) {
94 IPC_BEGIN_MESSAGE_MAP(WebRTCIdentityService
, message
)
95 IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_IdentityReady
, OnIdentityReady
)
96 IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_RequestFailed
, OnRequestFailed
)
97 IPC_MESSAGE_UNHANDLED(handled
= false)
103 void WebRTCIdentityService::OnIdentityReady(int request_id
,
104 const std::string
& certificate
,
105 const std::string
& private_key
) {
106 // The browser process may have sent the response before it receives the
107 // message to cancel the request. So we need to check if the returned response
108 // matches the request on the top of the queue.
109 if (pending_requests_
.empty() ||
110 pending_requests_
.front().request_id
!= request_id
)
113 pending_requests_
.front().success_callback
.Run(certificate
, private_key
);
114 OnOutstandingRequestReturned();
117 void WebRTCIdentityService::OnRequestFailed(int request_id
, int error
) {
118 // The browser process may have sent the response before it receives the
119 // message to cancel the request. So we need to check if the returned response
120 // matches the request on the top of the queue.
121 if (pending_requests_
.empty() ||
122 pending_requests_
.front().request_id
!= request_id
)
125 pending_requests_
.front().failure_callback
.Run(error
);
126 OnOutstandingRequestReturned();
129 void WebRTCIdentityService::SendRequest(const RequestInfo
& request_info
) {
130 if (!Send(new WebRTCIdentityMsg_RequestIdentity(request_info
.request_id
,
132 request_info
.identity_name
,
133 request_info
.common_name
))) {
134 base::ThreadTaskRunnerHandle::Get()->PostTask(
135 FROM_HERE
, base::Bind(&WebRTCIdentityService::OnRequestFailed
,
136 base::Unretained(this), request_info
.request_id
,
137 net::ERR_UNEXPECTED
));
141 void WebRTCIdentityService::OnOutstandingRequestReturned() {
142 pending_requests_
.pop_front();
144 if (!pending_requests_
.empty())
145 SendRequest(pending_requests_
.front());
148 } // namespace content