Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: chrome/browser/media/webrtc_logging_handler_host.cc

Issue 2307083002: Cleanup: move WebRTC related files from chrome/browser/media to chrome/browser/media/webrtc/ (Closed)
Patch Set: Removed file wrongly resuscitated during rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "chrome/browser/media/webrtc_logging_handler_host.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/cpu.h"
13 #include "base/files/file_util.h"
14 #include "base/logging.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/sys_info.h"
17 #include "base/time/time.h"
18 #include "build/build_config.h"
19 #include "chrome/browser/bad_message.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.h"
22 #include "chrome/browser/media/webrtc_log_list.h"
23 #include "chrome/browser/media/webrtc_log_uploader.h"
24 #include "chrome/browser/media/webrtc_rtp_dump_handler.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/common/channel_info.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/media/webrtc_logging_messages.h"
29 #include "chromeos/settings/cros_settings_names.h"
30 #include "components/prefs/pref_service.h"
31 #include "components/version_info/version_info.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/content_browser_client.h"
34 #include "content/public/browser/gpu_data_manager.h"
35 #include "content/public/browser/render_process_host.h"
36 #include "gpu/config/gpu_info.h"
37 #include "net/base/ip_address.h"
38 #include "net/url_request/url_request_context_getter.h"
39
40 #if defined(OS_LINUX)
41 #include "base/linux_util.h"
42 #endif
43
44 #if defined(OS_MACOSX)
45 #include "base/mac/mac_util.h"
46 #endif
47
48 #if defined(OS_CHROMEOS)
49 #include "chromeos/system/statistics_provider.h"
50 #endif
51
52 using base::IntToString;
53 using content::BrowserThread;
54
55 // Key used to attach the handler to the RenderProcessHost.
56 const char WebRtcLoggingHandlerHost::kWebRtcLoggingHandlerHostKey[] =
57 "kWebRtcLoggingHandlerHostKey";
58
59 namespace {
60
61 const char kLogNotStoppedOrNoLogOpen[] =
62 "Logging not stopped or no log open.";
63
64 // For privacy reasons when logging IP addresses. The returned "sensitive
65 // string" is for release builds a string with the end stripped away. Last
66 // octet for IPv4 and last 80 bits (5 groups) for IPv6. String will be
67 // "1.2.3.x" and "1.2.3::" respectively. For debug builds, the string is
68 // not stripped.
69 std::string IPAddressToSensitiveString(const net::IPAddress& address) {
70 #if defined(NDEBUG)
71 std::string sensitive_address;
72 switch (address.size()) {
73 case net::IPAddress::kIPv4AddressSize: {
74 sensitive_address = address.ToString();
75 size_t find_pos = sensitive_address.rfind('.');
76 if (find_pos == std::string::npos)
77 return std::string();
78 sensitive_address.resize(find_pos);
79 sensitive_address += ".x";
80 break;
81 }
82 case net::IPAddress::kIPv6AddressSize: {
83 // TODO(grunell): Create a string of format "1:2:3:x:x:x:x:x" to clarify
84 // that the end has been stripped out.
85 std::vector<uint8_t> bytes = address.bytes();
86 std::fill(bytes.begin() + 6, bytes.end(), 0);
87 net::IPAddress stripped_address(bytes);
88 sensitive_address = stripped_address.ToString();
89 break;
90 }
91 default: { break; }
92 }
93 return sensitive_address;
94 #else
95 return address.ToString();
96 #endif
97 }
98
99 void FormatMetaDataAsLogMessage(
100 const MetaDataMap& meta_data,
101 std::string* message) {
102 for (MetaDataMap::const_iterator it = meta_data.begin();
103 it != meta_data.end(); ++it) {
104 *message += it->first + ": " + it->second + '\n';
105 }
106 // Remove last '\n'.
107 message->resize(message->size() - 1);
108 }
109
110 } // namespace
111
112 WebRtcLogBuffer::WebRtcLogBuffer()
113 : buffer_(),
114 circular_(&buffer_[0], sizeof(buffer_), sizeof(buffer_) / 2, false),
115 read_only_(false) {
116 }
117
118 WebRtcLogBuffer::~WebRtcLogBuffer() {
119 DCHECK(read_only_ || thread_checker_.CalledOnValidThread());
120 }
121
122 void WebRtcLogBuffer::Log(const std::string& message) {
123 DCHECK(thread_checker_.CalledOnValidThread());
124 DCHECK(!read_only_);
125 circular_.Write(message.c_str(), message.length());
126 const char eol = '\n';
127 circular_.Write(&eol, 1);
128 }
129
130 PartialCircularBuffer WebRtcLogBuffer::Read() {
131 DCHECK(thread_checker_.CalledOnValidThread());
132 DCHECK(read_only_);
133 return PartialCircularBuffer(&buffer_[0], sizeof(buffer_));
134 }
135
136 void WebRtcLogBuffer::SetComplete() {
137 DCHECK(thread_checker_.CalledOnValidThread());
138 DCHECK(!read_only_) << "Already set? (programmer error)";
139 read_only_ = true;
140 // Detach from the current thread so that we can check reads on a different
141 // thread. This is to make sure that Read()s still happen on one thread only.
142 thread_checker_.DetachFromThread();
143 }
144
145 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost(
146 int render_process_id,
147 Profile* profile,
148 WebRtcLogUploader* log_uploader)
149 : BrowserMessageFilter(WebRtcLoggingMsgStart),
150 profile_(profile),
151 logging_state_(CLOSED),
152 upload_log_on_render_close_(false),
153 log_uploader_(log_uploader),
154 render_process_id_(render_process_id) {
155 DCHECK(profile_);
156 DCHECK(log_uploader_);
157 }
158
159 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {
160 // If we hit this, then we might be leaking a log reference count (see
161 // ApplyForStartLogging).
162 DCHECK_EQ(CLOSED, logging_state_);
163 }
164
165 void WebRtcLoggingHandlerHost::SetMetaData(
166 std::unique_ptr<MetaDataMap> meta_data,
167 const GenericDoneCallback& callback) {
168 DCHECK_CURRENTLY_ON(BrowserThread::IO);
169 DCHECK(!callback.is_null());
170
171 std::string error_message;
172 if (logging_state_ == CLOSED) {
173 if (!meta_data_.get())
174 meta_data_ = std::move(meta_data);
175 } else if (logging_state_ == STARTED) {
176 std::string meta_data_message;
177 FormatMetaDataAsLogMessage(*meta_data.get(), &meta_data_message);
178 LogToCircularBuffer(meta_data_message);
179 } else {
180 error_message = "Meta data must be set before stop or upload.";
181 }
182
183 if (error_message.empty() && meta_data.get()) {
184 // Keep the meta data around for uploading separately from the log.
185 for (const auto& it : *meta_data.get())
186 (*meta_data_.get())[it.first] = it.second;
187 }
188
189 FireGenericDoneCallback(callback, error_message.empty(), error_message);
190 }
191
192 void WebRtcLoggingHandlerHost::StartLogging(
193 const GenericDoneCallback& callback) {
194 DCHECK_CURRENTLY_ON(BrowserThread::IO);
195 DCHECK(!callback.is_null());
196
197 if (logging_state_ != CLOSED) {
198 FireGenericDoneCallback(callback, false, "A log is already open.");
199 return;
200 }
201
202 if (!log_uploader_->ApplyForStartLogging()) {
203 FireGenericDoneCallback(callback, false,
204 "Cannot start, maybe the maximum number of "
205 "simultaneuos logs has been reached.");
206 return;
207 }
208
209 logging_state_ = STARTING;
210
211 DCHECK(!log_buffer_.get());
212 log_buffer_.reset(new WebRtcLogBuffer());
213 if (!meta_data_.get())
214 meta_data_.reset(new MetaDataMap());
215
216 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
217 &WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread, this, callback));
218 }
219
220 void WebRtcLoggingHandlerHost::StopLogging(
221 const GenericDoneCallback& callback) {
222 DCHECK_CURRENTLY_ON(BrowserThread::IO);
223 DCHECK(!callback.is_null());
224
225 if (logging_state_ != STARTED) {
226 FireGenericDoneCallback(callback, false, "Logging not started.");
227 return;
228 }
229
230 stop_callback_ = callback;
231 logging_state_ = STOPPING;
232
233 Send(new WebRtcLoggingMsg_StopLogging());
234
235 BrowserThread::PostTask(
236 BrowserThread::UI, FROM_HERE,
237 base::Bind(
238 &WebRtcLoggingHandlerHost::DisableBrowserProcessLoggingOnUIThread,
239 this));
240 }
241
242 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) {
243 DCHECK_CURRENTLY_ON(BrowserThread::IO);
244 DCHECK(!callback.is_null());
245
246 if (logging_state_ != STOPPED) {
247 if (!callback.is_null()) {
248 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
249 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen));
250 }
251 return;
252 }
253
254 content::BrowserThread::PostTaskAndReplyWithResult(
255 content::BrowserThread::FILE,
256 FROM_HERE,
257 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
258 this),
259 base::Bind(&WebRtcLoggingHandlerHost::TriggerUpload, this, callback));
260 }
261
262 void WebRtcLoggingHandlerHost::UploadStoredLog(
263 const std::string& log_id,
264 const UploadDoneCallback& callback) {
265 DCHECK_CURRENTLY_ON(BrowserThread::IO);
266 DCHECK(!callback.is_null());
267
268 content::BrowserThread::PostTask(content::BrowserThread::FILE,
269 FROM_HERE,
270 base::Bind(&WebRtcLoggingHandlerHost::UploadStoredLogOnFileThread,
271 this, log_id, callback));
272 }
273
274 void WebRtcLoggingHandlerHost::UploadStoredLogOnFileThread(
275 const std::string& log_id,
276 const UploadDoneCallback& callback) {
277 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
278
279 WebRtcLogUploadDoneData upload_data;
280 upload_data.log_path = GetLogDirectoryAndEnsureExists();
281 upload_data.callback = callback;
282 upload_data.host = this;
283 upload_data.local_log_id = log_id;
284
285 log_uploader_->UploadStoredLog(upload_data);
286 }
287
288 void WebRtcLoggingHandlerHost::UploadLogDone() {
289 DCHECK_CURRENTLY_ON(BrowserThread::IO);
290 logging_state_ = CLOSED;
291 }
292
293 void WebRtcLoggingHandlerHost::DiscardLog(const GenericDoneCallback& callback) {
294 DCHECK_CURRENTLY_ON(BrowserThread::IO);
295 DCHECK(!callback.is_null());
296
297 if (logging_state_ != STOPPED) {
298 FireGenericDoneCallback(callback, false, kLogNotStoppedOrNoLogOpen);
299 return;
300 }
301 log_uploader_->LoggingStoppedDontUpload();
302 log_buffer_.reset();
303 meta_data_.reset();
304 logging_state_ = CLOSED;
305 rtp_dump_handler_.reset();
306 stop_rtp_dump_callback_.Reset();
307 FireGenericDoneCallback(callback, true, "");
308 }
309
310 // Stores the log locally using a hash of log_id + security origin.
311 void WebRtcLoggingHandlerHost::StoreLog(
312 const std::string& log_id,
313 const GenericDoneCallback& callback) {
314 DCHECK_CURRENTLY_ON(BrowserThread::IO);
315 DCHECK(!callback.is_null());
316
317 if (logging_state_ != STOPPED) {
318 FireGenericDoneCallback(callback, false, kLogNotStoppedOrNoLogOpen);
319 return;
320 }
321
322 if (rtp_dump_handler_) {
323 BrowserThread::PostTask(
324 BrowserThread::UI,
325 FROM_HERE,
326 base::Bind(stop_rtp_dump_callback_, true, true));
327
328 rtp_dump_handler_->StopOngoingDumps(
329 base::Bind(&WebRtcLoggingHandlerHost::StoreLogContinue,
330 this, log_id, callback));
331 return;
332 }
333
334 StoreLogContinue(log_id, callback);
335 }
336
337 void WebRtcLoggingHandlerHost::StoreLogContinue(
338 const std::string& log_id,
339 const GenericDoneCallback& callback) {
340 DCHECK_CURRENTLY_ON(BrowserThread::IO);
341 DCHECK(!callback.is_null());
342
343 std::unique_ptr<WebRtcLogPaths> log_paths(new WebRtcLogPaths());
344 ReleaseRtpDumps(log_paths.get());
345
346 content::BrowserThread::PostTaskAndReplyWithResult(
347 content::BrowserThread::FILE, FROM_HERE,
348 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
349 this),
350 base::Bind(&WebRtcLoggingHandlerHost::StoreLogInDirectory, this, log_id,
351 base::Passed(&log_paths), callback));
352 }
353
354 void WebRtcLoggingHandlerHost::LogMessage(const std::string& message) {
355 DCHECK_CURRENTLY_ON(BrowserThread::IO);
356 if (logging_state_ == STARTED) {
357 LogToCircularBuffer(WebRtcLoggingMessageData::Format(
358 message, base::Time::Now(), logging_started_time_));
359 }
360 }
361
362 void WebRtcLoggingHandlerHost::StartRtpDump(
363 RtpDumpType type,
364 const GenericDoneCallback& callback,
365 const content::RenderProcessHost::WebRtcStopRtpDumpCallback&
366 stop_callback) {
367 DCHECK_CURRENTLY_ON(BrowserThread::IO);
368 DCHECK(stop_rtp_dump_callback_.is_null() ||
369 stop_rtp_dump_callback_.Equals(stop_callback));
370
371 stop_rtp_dump_callback_ = stop_callback;
372
373 if (!rtp_dump_handler_) {
374 content::BrowserThread::PostTaskAndReplyWithResult(
375 content::BrowserThread::FILE,
376 FROM_HERE,
377 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
378 this),
379 base::Bind(&WebRtcLoggingHandlerHost::CreateRtpDumpHandlerAndStart,
380 this,
381 type,
382 callback));
383 return;
384 }
385
386 DoStartRtpDump(type, callback);
387 }
388
389 void WebRtcLoggingHandlerHost::StopRtpDump(
390 RtpDumpType type,
391 const GenericDoneCallback& callback) {
392 DCHECK_CURRENTLY_ON(BrowserThread::IO);
393 DCHECK(!callback.is_null());
394
395 if (!rtp_dump_handler_) {
396 FireGenericDoneCallback(callback, false, "RTP dump has not been started.");
397 return;
398 }
399
400 if (!stop_rtp_dump_callback_.is_null()) {
401 BrowserThread::PostTask(
402 BrowserThread::UI,
403 FROM_HERE,
404 base::Bind(stop_rtp_dump_callback_,
405 type == RTP_DUMP_INCOMING || type == RTP_DUMP_BOTH,
406 type == RTP_DUMP_OUTGOING || type == RTP_DUMP_BOTH));
407 }
408
409 rtp_dump_handler_->StopDump(type, callback);
410 }
411
412 void WebRtcLoggingHandlerHost::OnRtpPacket(
413 std::unique_ptr<uint8_t[]> packet_header,
414 size_t header_length,
415 size_t packet_length,
416 bool incoming) {
417 DCHECK_CURRENTLY_ON(BrowserThread::UI);
418
419 BrowserThread::PostTask(
420 BrowserThread::IO,
421 FROM_HERE,
422 base::Bind(&WebRtcLoggingHandlerHost::DumpRtpPacketOnIOThread,
423 this,
424 base::Passed(&packet_header),
425 header_length,
426 packet_length,
427 incoming));
428 }
429
430 void WebRtcLoggingHandlerHost::DumpRtpPacketOnIOThread(
431 std::unique_ptr<uint8_t[]> packet_header,
432 size_t header_length,
433 size_t packet_length,
434 bool incoming) {
435 DCHECK_CURRENTLY_ON(BrowserThread::IO);
436
437 // |rtp_dump_handler_| could be NULL if we are waiting for the FILE thread to
438 // create/ensure the log directory.
439 if (rtp_dump_handler_) {
440 rtp_dump_handler_->OnRtpPacket(
441 packet_header.get(), header_length, packet_length, incoming);
442 }
443 }
444
445 void WebRtcLoggingHandlerHost::OnChannelClosing() {
446 DCHECK_CURRENTLY_ON(BrowserThread::IO);
447 if (logging_state_ == STARTED || logging_state_ == STOPPED) {
448 if (upload_log_on_render_close_) {
449 logging_started_time_ = base::Time();
450
451 content::BrowserThread::PostTaskAndReplyWithResult(
452 content::BrowserThread::FILE,
453 FROM_HERE,
454 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
455 this),
456 base::Bind(&WebRtcLoggingHandlerHost::TriggerUpload, this,
457 UploadDoneCallback()));
458 } else {
459 log_uploader_->LoggingStoppedDontUpload();
460 logging_state_ = CLOSED;
461 }
462 }
463 content::BrowserMessageFilter::OnChannelClosing();
464 }
465
466 void WebRtcLoggingHandlerHost::OnDestruct() const {
467 BrowserThread::DeleteOnIOThread::Destruct(this);
468 }
469
470 bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message) {
471 DCHECK_CURRENTLY_ON(BrowserThread::IO);
472 bool handled = true;
473 IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingHandlerHost, message)
474 IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_AddLogMessages, OnAddLogMessages)
475 IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_LoggingStopped,
476 OnLoggingStoppedInRenderer)
477 IPC_MESSAGE_UNHANDLED(handled = false)
478 IPC_END_MESSAGE_MAP()
479
480 return handled;
481 }
482
483 void WebRtcLoggingHandlerHost::OnAddLogMessages(
484 const std::vector<WebRtcLoggingMessageData>& messages) {
485 DCHECK_CURRENTLY_ON(BrowserThread::IO);
486 if (logging_state_ == STARTED || logging_state_ == STOPPING) {
487 for (size_t i = 0; i < messages.size(); ++i) {
488 LogToCircularBuffer(messages[i].Format(logging_started_time_));
489 }
490 }
491 }
492
493 void WebRtcLoggingHandlerHost::OnLoggingStoppedInRenderer() {
494 DCHECK_CURRENTLY_ON(BrowserThread::IO);
495 if (logging_state_ != STOPPING) {
496 // If an out-of-order response is received, stop_callback_ may be invalid,
497 // and must not be invoked.
498 DLOG(ERROR) << "OnLoggingStoppedInRenderer invoked in state "
499 << logging_state_;
500 bad_message::ReceivedBadMessage(
501 this, bad_message::WRLHH_LOGGING_STOPPED_BAD_STATE);
502 return;
503 }
504 logging_started_time_ = base::Time();
505 logging_state_ = STOPPED;
506 FireGenericDoneCallback(stop_callback_, true, "");
507 stop_callback_.Reset();
508 }
509
510 void WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread(
511 const GenericDoneCallback& callback) {
512 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
513
514 net::NetworkInterfaceList network_list;
515 net::GetNetworkList(&network_list,
516 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
517
518 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
519 &WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, this, network_list,
520 callback));
521 }
522
523 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread(
524 const net::NetworkInterfaceList& network_list,
525 const GenericDoneCallback& callback) {
526 DCHECK_CURRENTLY_ON(BrowserThread::IO);
527 if (logging_state_ != STARTING) {
528 FireGenericDoneCallback(callback, false, "Logging cancelled.");
529 return;
530 }
531
532 // Tell the renderer and the browser to enable logging. Log messages are
533 // recevied on the IO thread, so the initial info will finish to be written
534 // first.
535 Send(new WebRtcLoggingMsg_StartLogging());
536 BrowserThread::PostTask(
537 BrowserThread::UI, FROM_HERE,
538 base::Bind(
539 &WebRtcLoggingHandlerHost::EnableBrowserProcessLoggingOnUIThread,
540 this));
541
542 // Log start time (current time). We don't use base/i18n/time_formatting.h
543 // here because we don't want the format of the current locale.
544 base::Time::Exploded now = {0};
545 base::Time::Now().LocalExplode(&now);
546 LogToCircularBuffer(base::StringPrintf(
547 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month,
548 now.day_of_month, now.hour, now.minute, now.second));
549
550 // Write metadata if received before logging started.
551 if (meta_data_.get() && !meta_data_->empty()) {
552 std::string info;
553 FormatMetaDataAsLogMessage(*meta_data_.get(), &info);
554 LogToCircularBuffer(info);
555 }
556
557 // Chrome version
558 LogToCircularBuffer("Chrome version: " + version_info::GetVersionNumber() +
559 " " + chrome::GetChannelString());
560
561 // OS
562 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " +
563 base::SysInfo::OperatingSystemVersion() + " " +
564 base::SysInfo::OperatingSystemArchitecture());
565 #if defined(OS_LINUX)
566 LogToCircularBuffer("Linux distribution: " + base::GetLinuxDistro());
567 #endif
568
569 // CPU
570 base::CPU cpu;
571 LogToCircularBuffer(
572 "Cpu: " + IntToString(cpu.family()) + "." + IntToString(cpu.model()) +
573 "." + IntToString(cpu.stepping()) + ", x" +
574 IntToString(base::SysInfo::NumberOfProcessors()) + ", " +
575 IntToString(base::SysInfo::AmountOfPhysicalMemoryMB()) + "MB");
576 std::string cpu_brand = cpu.cpu_brand();
577 // Workaround for crbug.com/249713.
578 // TODO(grunell): Remove workaround when bug is fixed.
579 size_t null_pos = cpu_brand.find('\0');
580 if (null_pos != std::string::npos)
581 cpu_brand.erase(null_pos);
582 LogToCircularBuffer("Cpu brand: " + cpu_brand);
583
584 // Computer model
585 std::string computer_model = "Not available";
586 #if defined(OS_MACOSX)
587 computer_model = base::mac::GetModelIdentifier();
588 #elif defined(OS_CHROMEOS)
589 chromeos::system::StatisticsProvider::GetInstance()->
590 GetMachineStatistic(chromeos::system::kHardwareClassKey, &computer_model);
591 #endif
592 LogToCircularBuffer("Computer model: " + computer_model);
593
594 // GPU
595 gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
596 LogToCircularBuffer(
597 "Gpu: machine-model-name=" + gpu_info.machine_model_name +
598 ", machine-model-version=" + gpu_info.machine_model_version +
599 ", vendor-id=" + base::UintToString(gpu_info.gpu.vendor_id) +
600 ", device-id=" + base::UintToString(gpu_info.gpu.device_id) +
601 ", driver-vendor=" + gpu_info.driver_vendor +
602 ", driver-version=" + gpu_info.driver_version);
603 LogToCircularBuffer(
604 "OpenGL: gl-vendor=" + gpu_info.gl_vendor +
605 ", gl-renderer=" + gpu_info.gl_renderer +
606 ", gl-version=" + gpu_info.gl_version);
607
608 // Network interfaces
609 LogToCircularBuffer("Discovered " + base::SizeTToString(network_list.size()) +
610 " network interfaces:");
611 for (net::NetworkInterfaceList::const_iterator it = network_list.begin();
612 it != network_list.end(); ++it) {
613 LogToCircularBuffer(
614 "Name: " + it->friendly_name + ", Address: " +
615 IPAddressToSensitiveString(it->address) + ", Type: " +
616 net::NetworkChangeNotifier::ConnectionTypeToString(it->type));
617 }
618
619 logging_started_time_ = base::Time::Now();
620 logging_state_ = STARTED;
621 FireGenericDoneCallback(callback, true, "");
622 }
623
624 void WebRtcLoggingHandlerHost::EnableBrowserProcessLoggingOnUIThread() {
625 DCHECK_CURRENTLY_ON(BrowserThread::UI);
626 content::RenderProcessHost* host =
627 content::RenderProcessHost::FromID(render_process_id_);
628 if (host) {
629 host->SetWebRtcLogMessageCallback(
630 base::Bind(&WebRtcLoggingHandlerHost::LogMessage, this));
631 }
632 }
633
634 void WebRtcLoggingHandlerHost::DisableBrowserProcessLoggingOnUIThread() {
635 DCHECK_CURRENTLY_ON(BrowserThread::UI);
636 content::RenderProcessHost* host =
637 content::RenderProcessHost::FromID(render_process_id_);
638 if (host)
639 host->ClearWebRtcLogMessageCallback();
640 }
641
642 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) {
643 DCHECK_CURRENTLY_ON(BrowserThread::IO);
644 DCHECK_NE(logging_state_, CLOSED);
645 log_buffer_->Log(message);
646 }
647
648 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() {
649 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
650 base::FilePath log_dir_path =
651 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath());
652 base::File::Error error;
653 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) {
654 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error;
655 return base::FilePath();
656 }
657 return log_dir_path;
658 }
659
660 void WebRtcLoggingHandlerHost::TriggerUpload(
661 const UploadDoneCallback& callback,
662 const base::FilePath& log_directory) {
663 DCHECK_CURRENTLY_ON(BrowserThread::IO);
664
665 if (rtp_dump_handler_) {
666 BrowserThread::PostTask(
667 BrowserThread::UI,
668 FROM_HERE,
669 base::Bind(stop_rtp_dump_callback_, true, true));
670
671 rtp_dump_handler_->StopOngoingDumps(
672 base::Bind(&WebRtcLoggingHandlerHost::DoUploadLogAndRtpDumps,
673 this,
674 log_directory,
675 callback));
676 return;
677 }
678
679 DoUploadLogAndRtpDumps(log_directory, callback);
680 }
681
682 void WebRtcLoggingHandlerHost::StoreLogInDirectory(
683 const std::string& log_id,
684 std::unique_ptr<WebRtcLogPaths> log_paths,
685 const GenericDoneCallback& done_callback,
686 const base::FilePath& directory) {
687 DCHECK_CURRENTLY_ON(BrowserThread::IO);
688 log_paths->log_path = directory;
689
690 log_buffer_->SetComplete();
691 BrowserThread::PostTask(
692 BrowserThread::FILE, FROM_HERE,
693 base::Bind(&WebRtcLogUploader::LoggingStoppedDoStore,
694 base::Unretained(log_uploader_),
695 *log_paths.get(), log_id, base::Passed(&log_buffer_),
696 base::Passed(&meta_data_), done_callback));
697
698 logging_state_ = CLOSED;
699 }
700
701 void WebRtcLoggingHandlerHost::DoUploadLogAndRtpDumps(
702 const base::FilePath& log_directory,
703 const UploadDoneCallback& callback) {
704 DCHECK_CURRENTLY_ON(BrowserThread::IO);
705
706 WebRtcLogUploadDoneData upload_done_data;
707 upload_done_data.log_path = log_directory;
708 upload_done_data.callback = callback;
709 upload_done_data.host = this;
710 ReleaseRtpDumps(&upload_done_data);
711
712 log_buffer_->SetComplete();
713 BrowserThread::PostTask(
714 BrowserThread::FILE, FROM_HERE,
715 base::Bind(&WebRtcLogUploader::LoggingStoppedDoUpload,
716 base::Unretained(log_uploader_), base::Passed(&log_buffer_),
717 base::Passed(&meta_data_), upload_done_data));
718
719 logging_state_ = CLOSED;
720 }
721
722 void WebRtcLoggingHandlerHost::CreateRtpDumpHandlerAndStart(
723 RtpDumpType type,
724 const GenericDoneCallback& callback,
725 const base::FilePath& dump_dir) {
726 DCHECK_CURRENTLY_ON(BrowserThread::IO);
727
728 // |rtp_dump_handler_| may be non-NULL if StartRtpDump is called again before
729 // GetLogDirectoryAndEnsureExists returns on the FILE thread for a previous
730 // StartRtpDump.
731 if (!rtp_dump_handler_)
732 rtp_dump_handler_.reset(new WebRtcRtpDumpHandler(dump_dir));
733
734 DoStartRtpDump(type, callback);
735 }
736
737 void WebRtcLoggingHandlerHost::DoStartRtpDump(
738 RtpDumpType type, const GenericDoneCallback& callback) {
739 DCHECK_CURRENTLY_ON(BrowserThread::IO);
740 DCHECK(rtp_dump_handler_);
741
742 std::string error;
743 bool result = rtp_dump_handler_->StartDump(type, &error);
744 FireGenericDoneCallback(callback, result, error);
745 }
746
747 bool WebRtcLoggingHandlerHost::ReleaseRtpDumps(WebRtcLogPaths* log_paths) {
748 DCHECK_CURRENTLY_ON(BrowserThread::IO);
749 DCHECK(log_paths);
750
751 if (!rtp_dump_handler_)
752 return false;
753
754 WebRtcRtpDumpHandler::ReleasedDumps rtp_dumps(
755 rtp_dump_handler_->ReleaseDumps());
756 log_paths->incoming_rtp_dump = rtp_dumps.incoming_dump_path;
757 log_paths->outgoing_rtp_dump = rtp_dumps.outgoing_dump_path;
758
759 rtp_dump_handler_.reset();
760 stop_rtp_dump_callback_.Reset();
761
762 return true;
763 }
764
765 void WebRtcLoggingHandlerHost::FireGenericDoneCallback(
766 const WebRtcLoggingHandlerHost::GenericDoneCallback& callback,
767 bool success,
768 const std::string& error_message) {
769 DCHECK_CURRENTLY_ON(BrowserThread::IO);
770 DCHECK(!callback.is_null());
771
772 if (error_message.empty()) {
773 DCHECK(success);
774 content::BrowserThread::PostTask(
775 content::BrowserThread::UI,
776 FROM_HERE,
777 base::Bind(callback, success, error_message));
778 return;
779 }
780
781 DCHECK(!success);
782
783 // Add current logging state to error message.
784 std::string error_message_with_state(error_message);
785 switch (logging_state_) {
786 case CLOSED:
787 error_message_with_state += " State=closed.";
788 break;
789 case STARTING:
790 error_message_with_state += " State=starting.";
791 break;
792 case STARTED:
793 error_message_with_state += " State=started.";
794 break;
795 case STOPPING:
796 error_message_with_state += " State=stopping.";
797 break;
798 case STOPPED:
799 error_message_with_state += " State=stopped.";
800 break;
801 }
802
803 content::BrowserThread::PostTask(
804 content::BrowserThread::UI,
805 FROM_HERE,
806 base::Bind(callback, success, error_message_with_state));
807 }
OLDNEW
« no previous file with comments | « chrome/browser/media/webrtc_logging_handler_host.h ('k') | chrome/browser/media/webrtc_perf_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698