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 <string>
6
7 #include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h"
8
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/supports_user_data.h"
12 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
13 #include "chrome/browser/extensions/extension_tab_util.h"
14 #include "chrome/browser/media/webrtc_logging_handler_host.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/web_contents.h"
19 #include "extensions/common/error_utils.h"
20
21 using content::BrowserThread;
22
23 namespace extensions {
24
25 namespace SetMetaData = api::webrtc_logging_private::SetMetaData;
26 namespace Start = api::webrtc_logging_private::Start;
27 namespace SetUploadOnRenderClose =
28 api::webrtc_logging_private::SetUploadOnRenderClose;
29 namespace Stop = api::webrtc_logging_private::Stop;
30 namespace Upload = api::webrtc_logging_private::Upload;
31 namespace Discard = api::webrtc_logging_private::Discard;
32 namespace StartRtpDump = api::webrtc_logging_private::StartRtpDump;
33 namespace StopRtpDump = api::webrtc_logging_private::StopRtpDump;
34
35 using api::webrtc_logging_private::MetaDataEntry;
36
37 content::RenderProcessHost*
RphFromTabIdAndSecurityOrigin(int tab_id,const std::string & security_origin)38 WebrtcLoggingPrivateTabIdFunction::RphFromTabIdAndSecurityOrigin(
39 int tab_id, const std::string& security_origin) {
40 content::WebContents* contents = NULL;
41 if (!ExtensionTabUtil::GetTabById(
42 tab_id, GetProfile(), true, NULL, NULL, &contents, NULL)) {
43 error_ = extensions::ErrorUtils::FormatErrorMessage(
44 extensions::tabs_constants::kTabNotFoundError,
45 base::IntToString(tab_id));
46 return NULL;
47 }
48 if (!contents) {
49 error_ = extensions::ErrorUtils::FormatErrorMessage(
50 "Web contents for tab not found",
51 base::IntToString(tab_id));
52 return NULL;
53 }
54 if (contents->GetURL().GetOrigin().spec() != security_origin) {
55 error_ = extensions::ErrorUtils::FormatErrorMessage(
56 "Invalid security origin",
57 base::IntToString(tab_id));
58 return NULL;
59 }
60 return contents->GetRenderProcessHost();
61 }
62
63 WebrtcLoggingPrivateSetMetaDataFunction::
WebrtcLoggingPrivateSetMetaDataFunction()64 WebrtcLoggingPrivateSetMetaDataFunction() {}
65
66 WebrtcLoggingPrivateSetMetaDataFunction::
~WebrtcLoggingPrivateSetMetaDataFunction()67 ~WebrtcLoggingPrivateSetMetaDataFunction() {}
68
RunAsync()69 bool WebrtcLoggingPrivateSetMetaDataFunction::RunAsync() {
70 scoped_ptr<SetMetaData::Params> params(SetMetaData::Params::Create(*args_));
71 EXTENSION_FUNCTION_VALIDATE(params.get());
72
73 content::RenderProcessHost* host =
74 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
75 if (!host)
76 return false;
77
78 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
79 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
80
81 std::map<std::string, std::string> meta_data;
82 for (std::vector<linked_ptr<MetaDataEntry> >::const_iterator it =
83 params->meta_data.begin(); it != params->meta_data.end(); ++it) {
84 meta_data[(*it)->key] = (*it)->value;
85 }
86
87 WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
88 &WebrtcLoggingPrivateSetMetaDataFunction::SetMetaDataCallback, this);
89
90 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
91 &WebRtcLoggingHandlerHost::SetMetaData, webrtc_logging_handler_host,
92 meta_data, callback));
93
94 return true;
95 }
96
SetMetaDataCallback(bool success,const std::string & error_message)97 void WebrtcLoggingPrivateSetMetaDataFunction::SetMetaDataCallback(
98 bool success, const std::string& error_message) {
99 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
100 if (!success)
101 SetError(error_message);
102 SendResponse(success);
103 }
104
WebrtcLoggingPrivateStartFunction()105 WebrtcLoggingPrivateStartFunction::WebrtcLoggingPrivateStartFunction() {}
106
~WebrtcLoggingPrivateStartFunction()107 WebrtcLoggingPrivateStartFunction::~WebrtcLoggingPrivateStartFunction() {}
108
RunAsync()109 bool WebrtcLoggingPrivateStartFunction::RunAsync() {
110 scoped_ptr<Start::Params> params(Start::Params::Create(*args_));
111 EXTENSION_FUNCTION_VALIDATE(params.get());
112
113 content::RenderProcessHost* host =
114 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
115 if (!host)
116 return false;
117
118 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
119 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
120
121 WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
122 &WebrtcLoggingPrivateStartFunction::StartCallback, this);
123
124 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
125 &WebRtcLoggingHandlerHost::StartLogging, webrtc_logging_handler_host,
126 callback));
127
128 return true;
129 }
130
StartCallback(bool success,const std::string & error_message)131 void WebrtcLoggingPrivateStartFunction::StartCallback(
132 bool success, const std::string& error_message) {
133 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
134 if (!success)
135 SetError(error_message);
136 SendResponse(success);
137 }
138
139 WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::
WebrtcLoggingPrivateSetUploadOnRenderCloseFunction()140 WebrtcLoggingPrivateSetUploadOnRenderCloseFunction() {}
141
142 WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::
~WebrtcLoggingPrivateSetUploadOnRenderCloseFunction()143 ~WebrtcLoggingPrivateSetUploadOnRenderCloseFunction() {}
144
RunAsync()145 bool WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::RunAsync() {
146 scoped_ptr<SetUploadOnRenderClose::Params> params(
147 SetUploadOnRenderClose::Params::Create(*args_));
148 EXTENSION_FUNCTION_VALIDATE(params.get());
149
150 content::RenderProcessHost* host =
151 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
152 if (!host)
153 return false;
154
155 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
156 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
157
158 webrtc_logging_handler_host->set_upload_log_on_render_close(
159 params->should_upload);
160
161 return true;
162 }
163
WebrtcLoggingPrivateStopFunction()164 WebrtcLoggingPrivateStopFunction::WebrtcLoggingPrivateStopFunction() {}
165
~WebrtcLoggingPrivateStopFunction()166 WebrtcLoggingPrivateStopFunction::~WebrtcLoggingPrivateStopFunction() {}
167
RunAsync()168 bool WebrtcLoggingPrivateStopFunction::RunAsync() {
169 scoped_ptr<Stop::Params> params(Stop::Params::Create(*args_));
170 EXTENSION_FUNCTION_VALIDATE(params.get());
171
172 content::RenderProcessHost* host =
173 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
174 if (!host)
175 return false;
176
177 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
178 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
179
180 WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
181 &WebrtcLoggingPrivateStopFunction::StopCallback, this);
182
183 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
184 &WebRtcLoggingHandlerHost::StopLogging, webrtc_logging_handler_host,
185 callback));
186
187 return true;
188 }
189
StopCallback(bool success,const std::string & error_message)190 void WebrtcLoggingPrivateStopFunction::StopCallback(
191 bool success, const std::string& error_message) {
192 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
193 if (!success)
194 SetError(error_message);
195 SendResponse(success);
196 }
197
WebrtcLoggingPrivateUploadFunction()198 WebrtcLoggingPrivateUploadFunction::WebrtcLoggingPrivateUploadFunction() {}
199
~WebrtcLoggingPrivateUploadFunction()200 WebrtcLoggingPrivateUploadFunction::~WebrtcLoggingPrivateUploadFunction() {}
201
RunAsync()202 bool WebrtcLoggingPrivateUploadFunction::RunAsync() {
203 scoped_ptr<Upload::Params> params(Upload::Params::Create(*args_));
204 EXTENSION_FUNCTION_VALIDATE(params.get());
205
206 content::RenderProcessHost* host =
207 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
208 if (!host)
209 return false;
210
211 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
212 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
213
214 WebRtcLoggingHandlerHost::UploadDoneCallback callback = base::Bind(
215 &WebrtcLoggingPrivateUploadFunction::UploadCallback, this);
216
217 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
218 &WebRtcLoggingHandlerHost::UploadLog, webrtc_logging_handler_host,
219 callback));
220
221 return true;
222 }
223
UploadCallback(bool success,const std::string & report_id,const std::string & error_message)224 void WebrtcLoggingPrivateUploadFunction::UploadCallback(
225 bool success, const std::string& report_id,
226 const std::string& error_message) {
227 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
228 if (success) {
229 api::webrtc_logging_private::UploadResult result;
230 result.report_id = report_id;
231 SetResult(result.ToValue().release());
232 } else {
233 SetError(error_message);
234 }
235 SendResponse(success);
236 }
237
WebrtcLoggingPrivateDiscardFunction()238 WebrtcLoggingPrivateDiscardFunction::WebrtcLoggingPrivateDiscardFunction() {}
239
~WebrtcLoggingPrivateDiscardFunction()240 WebrtcLoggingPrivateDiscardFunction::~WebrtcLoggingPrivateDiscardFunction() {}
241
RunAsync()242 bool WebrtcLoggingPrivateDiscardFunction::RunAsync() {
243 scoped_ptr<Discard::Params> params(Discard::Params::Create(*args_));
244 EXTENSION_FUNCTION_VALIDATE(params.get());
245
246 content::RenderProcessHost* host =
247 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
248 if (!host)
249 return false;
250
251 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
252 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
253
254 WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
255 &WebrtcLoggingPrivateDiscardFunction::DiscardCallback, this);
256
257 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
258 &WebRtcLoggingHandlerHost::DiscardLog, webrtc_logging_handler_host,
259 callback));
260
261 return true;
262 }
263
DiscardCallback(bool success,const std::string & error_message)264 void WebrtcLoggingPrivateDiscardFunction::DiscardCallback(
265 bool success, const std::string& error_message) {
266 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
267 if (!success)
268 SetError(error_message);
269 SendResponse(success);
270 }
271
272 WebrtcLoggingPrivateStartRtpDumpFunction::
WebrtcLoggingPrivateStartRtpDumpFunction()273 WebrtcLoggingPrivateStartRtpDumpFunction() {}
274
275 WebrtcLoggingPrivateStartRtpDumpFunction::
~WebrtcLoggingPrivateStartRtpDumpFunction()276 ~WebrtcLoggingPrivateStartRtpDumpFunction() {}
277
RunAsync()278 bool WebrtcLoggingPrivateStartRtpDumpFunction::RunAsync() {
279 scoped_ptr<StartRtpDump::Params> params(StartRtpDump::Params::Create(*args_));
280 EXTENSION_FUNCTION_VALIDATE(params.get());
281
282 if (!params->incoming && !params->outgoing) {
283 StartRtpDumpCallback(false, "Either incoming or outgoing must be true.");
284 return true;
285 }
286
287 RtpDumpType type =
288 (params->incoming && params->outgoing)
289 ? RTP_DUMP_BOTH
290 : (params->incoming ? RTP_DUMP_INCOMING : RTP_DUMP_OUTGOING);
291
292 content::RenderProcessHost* host =
293 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
294 if (!host)
295 return false;
296
297 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
298 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
299
300 WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
301 &WebrtcLoggingPrivateStartRtpDumpFunction::StartRtpDumpCallback, this);
302
303 // This call cannot fail.
304 content::RenderProcessHost::WebRtcStopRtpDumpCallback stop_callback =
305 host->StartRtpDump(params->incoming,
306 params->outgoing,
307 base::Bind(&WebRtcLoggingHandlerHost::OnRtpPacket,
308 webrtc_logging_handler_host));
309
310 BrowserThread::PostTask(BrowserThread::IO,
311 FROM_HERE,
312 base::Bind(&WebRtcLoggingHandlerHost::StartRtpDump,
313 webrtc_logging_handler_host,
314 type,
315 callback,
316 stop_callback));
317 return true;
318 }
319
StartRtpDumpCallback(bool success,const std::string & error_message)320 void WebrtcLoggingPrivateStartRtpDumpFunction::StartRtpDumpCallback(
321 bool success,
322 const std::string& error_message) {
323 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
324 if (!success)
325 SetError(error_message);
326 SendResponse(success);
327 }
328
329 WebrtcLoggingPrivateStopRtpDumpFunction::
WebrtcLoggingPrivateStopRtpDumpFunction()330 WebrtcLoggingPrivateStopRtpDumpFunction() {}
331
332 WebrtcLoggingPrivateStopRtpDumpFunction::
~WebrtcLoggingPrivateStopRtpDumpFunction()333 ~WebrtcLoggingPrivateStopRtpDumpFunction() {}
334
RunAsync()335 bool WebrtcLoggingPrivateStopRtpDumpFunction::RunAsync() {
336 scoped_ptr<StopRtpDump::Params> params(StopRtpDump::Params::Create(*args_));
337 EXTENSION_FUNCTION_VALIDATE(params.get());
338
339 if (!params->incoming && !params->outgoing) {
340 StopRtpDumpCallback(false, "Either incoming or outgoing must be true.");
341 return true;
342 }
343
344 RtpDumpType type =
345 (params->incoming && params->outgoing)
346 ? RTP_DUMP_BOTH
347 : (params->incoming ? RTP_DUMP_INCOMING : RTP_DUMP_OUTGOING);
348
349 content::RenderProcessHost* host =
350 RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
351 if (!host)
352 return false;
353
354 scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
355 base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
356
357 WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
358 &WebrtcLoggingPrivateStopRtpDumpFunction::StopRtpDumpCallback, this);
359
360 BrowserThread::PostTask(BrowserThread::IO,
361 FROM_HERE,
362 base::Bind(&WebRtcLoggingHandlerHost::StopRtpDump,
363 webrtc_logging_handler_host,
364 type,
365 callback));
366 return true;
367 }
368
StopRtpDumpCallback(bool success,const std::string & error_message)369 void WebrtcLoggingPrivateStopRtpDumpFunction::StopRtpDumpCallback(
370 bool success,
371 const std::string& error_message) {
372 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
373 if (!success)
374 SetError(error_message);
375 SendResponse(success);
376 }
377
378 } // namespace extensions
379