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
21using content::BrowserThread;
22
23namespace extensions {
24
25namespace SetMetaData = api::webrtc_logging_private::SetMetaData;
26namespace Start = api::webrtc_logging_private::Start;
27namespace SetUploadOnRenderClose =
28    api::webrtc_logging_private::SetUploadOnRenderClose;
29namespace Stop = api::webrtc_logging_private::Stop;
30namespace Upload = api::webrtc_logging_private::Upload;
31namespace Discard = api::webrtc_logging_private::Discard;
32namespace StartRtpDump = api::webrtc_logging_private::StartRtpDump;
33namespace StopRtpDump = api::webrtc_logging_private::StopRtpDump;
34
35using api::webrtc_logging_private::MetaDataEntry;
36
37content::RenderProcessHost*
38WebrtcLoggingPrivateTabIdFunction::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
63WebrtcLoggingPrivateSetMetaDataFunction::
64WebrtcLoggingPrivateSetMetaDataFunction() {}
65
66WebrtcLoggingPrivateSetMetaDataFunction::
67~WebrtcLoggingPrivateSetMetaDataFunction() {}
68
69bool 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
97void 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
105WebrtcLoggingPrivateStartFunction::WebrtcLoggingPrivateStartFunction() {}
106
107WebrtcLoggingPrivateStartFunction::~WebrtcLoggingPrivateStartFunction() {}
108
109bool 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
131void 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
139WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::
140WebrtcLoggingPrivateSetUploadOnRenderCloseFunction() {}
141
142WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::
143~WebrtcLoggingPrivateSetUploadOnRenderCloseFunction() {}
144
145bool 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
164WebrtcLoggingPrivateStopFunction::WebrtcLoggingPrivateStopFunction() {}
165
166WebrtcLoggingPrivateStopFunction::~WebrtcLoggingPrivateStopFunction() {}
167
168bool 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
190void 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
198WebrtcLoggingPrivateUploadFunction::WebrtcLoggingPrivateUploadFunction() {}
199
200WebrtcLoggingPrivateUploadFunction::~WebrtcLoggingPrivateUploadFunction() {}
201
202bool 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
224void 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
238WebrtcLoggingPrivateDiscardFunction::WebrtcLoggingPrivateDiscardFunction() {}
239
240WebrtcLoggingPrivateDiscardFunction::~WebrtcLoggingPrivateDiscardFunction() {}
241
242bool 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
264void 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
272WebrtcLoggingPrivateStartRtpDumpFunction::
273    WebrtcLoggingPrivateStartRtpDumpFunction() {}
274
275WebrtcLoggingPrivateStartRtpDumpFunction::
276    ~WebrtcLoggingPrivateStartRtpDumpFunction() {}
277
278bool 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
320void 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
329WebrtcLoggingPrivateStopRtpDumpFunction::
330    WebrtcLoggingPrivateStopRtpDumpFunction() {}
331
332WebrtcLoggingPrivateStopRtpDumpFunction::
333    ~WebrtcLoggingPrivateStopRtpDumpFunction() {}
334
335bool 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
369void 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