OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/renderer/media/webrtc_identity_service.h" | |
6 | |
7 #include "base/location.h" | |
8 #include "base/single_thread_task_runner.h" | |
9 #include "base/threading/thread_task_runner_handle.h" | |
10 #include "content/public/renderer/render_thread.h" | |
11 #include "net/base/net_errors.h" | |
12 | |
13 namespace content { | |
14 | |
15 WebRTCIdentityService::RequestInfo::RequestInfo( | |
16 const WebRTCIdentityMsg_RequestIdentity_Params& params, | |
17 const SuccessCallback& success_callback, | |
18 const FailureCallback& failure_callback) | |
19 : params(params), | |
20 success_callback(success_callback), | |
21 failure_callback(failure_callback) {} | |
22 | |
23 WebRTCIdentityService::RequestInfo::RequestInfo(const RequestInfo& other) = | |
24 default; | |
25 | |
26 WebRTCIdentityService::RequestInfo::~RequestInfo() {} | |
27 | |
28 WebRTCIdentityService::WebRTCIdentityService() : next_request_id_(1) { | |
29 // RenderThread::Get() could be NULL in unit tests. | |
30 if (RenderThread::Get()) | |
31 RenderThread::Get()->AddObserver(this); | |
32 } | |
33 | |
34 WebRTCIdentityService::~WebRTCIdentityService() { | |
35 // RenderThread::Get() could be NULL in unit tests. | |
36 if (RenderThread::Get()) { | |
37 RenderThread::Get()->RemoveObserver(this); | |
38 | |
39 if (!pending_requests_.empty()) { | |
40 RenderThread::Get()->Send(new WebRTCIdentityMsg_CancelRequest()); | |
41 } | |
42 } | |
43 } | |
44 | |
45 int WebRTCIdentityService::RequestIdentity( | |
46 const GURL& url, | |
47 const GURL& first_party_for_cookies, | |
48 const std::string& identity_name, | |
49 const std::string& common_name, | |
50 const SuccessCallback& success_callback, | |
51 const FailureCallback& failure_callback) { | |
52 int request_id = next_request_id_++; | |
53 | |
54 WebRTCIdentityMsg_RequestIdentity_Params params; | |
55 params.request_id = request_id; | |
56 params.url = url; | |
57 params.first_party_for_cookies = first_party_for_cookies; | |
58 params.identity_name = identity_name; | |
59 params.common_name = common_name; | |
60 | |
61 RequestInfo request_info(params, success_callback, failure_callback); | |
62 | |
63 pending_requests_.push_back(request_info); | |
64 if (pending_requests_.size() == 1) | |
65 SendRequest(request_info); | |
66 | |
67 return request_id; | |
68 } | |
69 | |
70 void WebRTCIdentityService::CancelRequest(int request_id) { | |
71 std::deque<RequestInfo>::iterator it; | |
72 for (it = pending_requests_.begin(); it != pending_requests_.end(); ++it) { | |
73 if (it->params.request_id != request_id) | |
74 continue; | |
75 if (it != pending_requests_.begin()) { | |
76 pending_requests_.erase(it); | |
77 } else { | |
78 Send(new WebRTCIdentityMsg_CancelRequest()); | |
79 OnOutstandingRequestReturned(); | |
80 } | |
81 break; | |
82 } | |
83 } | |
84 | |
85 bool WebRTCIdentityService::Send(IPC::Message* message) { | |
86 // Unit tests should override this method to avoid null-ptr-deref. | |
87 return RenderThread::Get()->Send(message); | |
88 } | |
89 | |
90 bool WebRTCIdentityService::OnControlMessageReceived( | |
91 const IPC::Message& message) { | |
92 bool handled = true; | |
93 IPC_BEGIN_MESSAGE_MAP(WebRTCIdentityService, message) | |
94 IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_IdentityReady, OnIdentityReady) | |
95 IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_RequestFailed, OnRequestFailed) | |
96 IPC_MESSAGE_UNHANDLED(handled = false) | |
97 IPC_END_MESSAGE_MAP() | |
98 | |
99 return handled; | |
100 } | |
101 | |
102 void WebRTCIdentityService::OnIdentityReady(int request_id, | |
103 const std::string& certificate, | |
104 const std::string& private_key) { | |
105 // The browser process may have sent the response before it receives the | |
106 // message to cancel the request. So we need to check if the returned response | |
107 // matches the request on the top of the queue. | |
108 if (pending_requests_.empty() || | |
109 pending_requests_.front().params.request_id != request_id) | |
110 return; | |
111 | |
112 pending_requests_.front().success_callback.Run(certificate, private_key); | |
113 OnOutstandingRequestReturned(); | |
114 } | |
115 | |
116 void WebRTCIdentityService::OnRequestFailed(int request_id, int error) { | |
117 // The browser process may have sent the response before it receives the | |
118 // message to cancel the request. So we need to check if the returned response | |
119 // matches the request on the top of the queue. | |
120 if (pending_requests_.empty() || | |
121 pending_requests_.front().params.request_id != request_id) | |
122 return; | |
123 | |
124 pending_requests_.front().failure_callback.Run(error); | |
125 OnOutstandingRequestReturned(); | |
126 } | |
127 | |
128 void WebRTCIdentityService::SendRequest(const RequestInfo& request_info) { | |
129 if (!Send(new WebRTCIdentityMsg_RequestIdentity(request_info.params))) { | |
130 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
131 FROM_HERE, | |
132 base::Bind(&WebRTCIdentityService::OnRequestFailed, | |
133 base::Unretained(this), request_info.params.request_id, | |
134 net::ERR_UNEXPECTED)); | |
135 } | |
136 } | |
137 | |
138 void WebRTCIdentityService::OnOutstandingRequestReturned() { | |
139 pending_requests_.pop_front(); | |
140 | |
141 if (!pending_requests_.empty()) | |
142 SendRequest(pending_requests_.front()); | |
143 } | |
144 | |
145 } // namespace content | |
OLD | NEW |