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/public/renderer/render_thread.h"
11 #include "net/base/net_errors.h"
15 WebRTCIdentityService::RequestInfo::RequestInfo(
16 const WebRTCIdentityMsg_RequestIdentity_Params
& params
,
17 const SuccessCallback
& success_callback
,
18 const FailureCallback
& failure_callback
)
20 success_callback(success_callback
),
21 failure_callback(failure_callback
) {}
23 WebRTCIdentityService::RequestInfo::~RequestInfo() {}
25 WebRTCIdentityService::WebRTCIdentityService() : next_request_id_(1) {
26 // RenderThread::Get() could be NULL in unit tests.
27 if (RenderThread::Get())
28 RenderThread::Get()->AddObserver(this);
31 WebRTCIdentityService::~WebRTCIdentityService() {
32 // RenderThread::Get() could be NULL in unit tests.
33 if (RenderThread::Get()) {
34 RenderThread::Get()->RemoveObserver(this);
36 if (!pending_requests_
.empty()) {
37 RenderThread::Get()->Send(new WebRTCIdentityMsg_CancelRequest());
42 int WebRTCIdentityService::RequestIdentity(
44 const GURL
& first_party_for_cookies
,
45 const std::string
& identity_name
,
46 const std::string
& common_name
,
47 const SuccessCallback
& success_callback
,
48 const FailureCallback
& failure_callback
) {
49 int request_id
= next_request_id_
++;
51 WebRTCIdentityMsg_RequestIdentity_Params params
;
52 params
.request_id
= request_id
;
54 params
.first_party_for_cookies
= first_party_for_cookies
;
55 params
.identity_name
= identity_name
;
56 params
.common_name
= common_name
;
58 RequestInfo
request_info(params
, success_callback
, failure_callback
);
60 pending_requests_
.push_back(request_info
);
61 if (pending_requests_
.size() == 1)
62 SendRequest(request_info
);
67 void WebRTCIdentityService::CancelRequest(int request_id
) {
68 std::deque
<RequestInfo
>::iterator it
;
69 for (it
= pending_requests_
.begin(); it
!= pending_requests_
.end(); ++it
) {
70 if (it
->params
.request_id
!= request_id
)
72 if (it
!= pending_requests_
.begin()) {
73 pending_requests_
.erase(it
);
75 Send(new WebRTCIdentityMsg_CancelRequest());
76 OnOutstandingRequestReturned();
82 bool WebRTCIdentityService::Send(IPC::Message
* message
) {
83 // Unit tests should override this method to avoid null-ptr-deref.
84 return RenderThread::Get()->Send(message
);
87 bool WebRTCIdentityService::OnControlMessageReceived(
88 const IPC::Message
& message
) {
90 IPC_BEGIN_MESSAGE_MAP(WebRTCIdentityService
, message
)
91 IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_IdentityReady
, OnIdentityReady
)
92 IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_RequestFailed
, OnRequestFailed
)
93 IPC_MESSAGE_UNHANDLED(handled
= false)
99 void WebRTCIdentityService::OnIdentityReady(int request_id
,
100 const std::string
& certificate
,
101 const std::string
& private_key
) {
102 // The browser process may have sent the response before it receives the
103 // message to cancel the request. So we need to check if the returned response
104 // matches the request on the top of the queue.
105 if (pending_requests_
.empty() ||
106 pending_requests_
.front().params
.request_id
!= request_id
)
109 pending_requests_
.front().success_callback
.Run(certificate
, private_key
);
110 OnOutstandingRequestReturned();
113 void WebRTCIdentityService::OnRequestFailed(int request_id
, int error
) {
114 // The browser process may have sent the response before it receives the
115 // message to cancel the request. So we need to check if the returned response
116 // matches the request on the top of the queue.
117 if (pending_requests_
.empty() ||
118 pending_requests_
.front().params
.request_id
!= request_id
)
121 pending_requests_
.front().failure_callback
.Run(error
);
122 OnOutstandingRequestReturned();
125 void WebRTCIdentityService::SendRequest(const RequestInfo
& request_info
) {
126 if (!Send(new WebRTCIdentityMsg_RequestIdentity(request_info
.params
))) {
127 base::ThreadTaskRunnerHandle::Get()->PostTask(
129 base::Bind(&WebRTCIdentityService::OnRequestFailed
,
130 base::Unretained(this), request_info
.params
.request_id
,
131 net::ERR_UNEXPECTED
));
135 void WebRTCIdentityService::OnOutstandingRequestReturned() {
136 pending_requests_
.pop_front();
138 if (!pending_requests_
.empty())
139 SendRequest(pending_requests_
.front());
142 } // namespace content