| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/media/webrtc_logging_handler_host.h" | 5 #include "chrome/browser/media/webrtc_logging_handler_host.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #include "base/mac/mac_util.h" | 45 #include "base/mac/mac_util.h" |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 #if defined(OS_CHROMEOS) | 48 #if defined(OS_CHROMEOS) |
| 49 #include "chromeos/system/statistics_provider.h" | 49 #include "chromeos/system/statistics_provider.h" |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 using base::IntToString; | 52 using base::IntToString; |
| 53 using content::BrowserThread; | 53 using content::BrowserThread; |
| 54 | 54 |
| 55 // Key used to attach the handler to the RenderProcessHost. |
| 56 const char WebRtcLoggingHandlerHost::kWebRtcLoggingHandlerHostKey[] = |
| 57 "kWebRtcLoggingHandlerHostKey"; |
| 58 |
| 55 namespace { | 59 namespace { |
| 56 | 60 |
| 57 const char kLogNotStoppedOrNoLogOpen[] = | 61 const char kLogNotStoppedOrNoLogOpen[] = |
| 58 "Logging not stopped or no log open."; | 62 "Logging not stopped or no log open."; |
| 59 | 63 |
| 60 // For privacy reasons when logging IP addresses. The returned "sensitive | 64 // For privacy reasons when logging IP addresses. The returned "sensitive |
| 61 // string" is for release builds a string with the end stripped away. Last | 65 // string" is for release builds a string with the end stripped away. Last |
| 62 // octet for IPv4 and last 80 bits (5 groups) for IPv6. String will be | 66 // octet for IPv4 and last 80 bits (5 groups) for IPv6. String will be |
| 63 // "1.2.3.x" and "1.2.3::" respectively. For debug builds, the string is | 67 // "1.2.3.x" and "1.2.3::" respectively. For debug builds, the string is |
| 64 // not stripped. | 68 // not stripped. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 const MetaDataMap& meta_data, | 100 const MetaDataMap& meta_data, |
| 97 std::string* message) { | 101 std::string* message) { |
| 98 for (MetaDataMap::const_iterator it = meta_data.begin(); | 102 for (MetaDataMap::const_iterator it = meta_data.begin(); |
| 99 it != meta_data.end(); ++it) { | 103 it != meta_data.end(); ++it) { |
| 100 *message += it->first + ": " + it->second + '\n'; | 104 *message += it->first + ": " + it->second + '\n'; |
| 101 } | 105 } |
| 102 // Remove last '\n'. | 106 // Remove last '\n'. |
| 103 message->resize(message->size() - 1); | 107 message->resize(message->size() - 1); |
| 104 } | 108 } |
| 105 | 109 |
| 106 // Returns a path name to be used as prefix for audio debug recordings files. | |
| 107 base::FilePath GetAudioDebugRecordingsPrefixPath( | |
| 108 const base::FilePath& directory, | |
| 109 uint64_t audio_debug_recordings_id) { | |
| 110 static const char kAudioDebugRecordingsFilePrefix[] = "AudioDebugRecordings."; | |
| 111 return directory.AppendASCII(kAudioDebugRecordingsFilePrefix + | |
| 112 base::Int64ToString(audio_debug_recordings_id)); | |
| 113 } | |
| 114 | |
| 115 } // namespace | 110 } // namespace |
| 116 | 111 |
| 117 WebRtcLogBuffer::WebRtcLogBuffer() | 112 WebRtcLogBuffer::WebRtcLogBuffer() |
| 118 : buffer_(), | 113 : buffer_(), |
| 119 circular_(&buffer_[0], sizeof(buffer_), sizeof(buffer_) / 2, false), | 114 circular_(&buffer_[0], sizeof(buffer_), sizeof(buffer_) / 2, false), |
| 120 read_only_(false) { | 115 read_only_(false) { |
| 121 } | 116 } |
| 122 | 117 |
| 123 WebRtcLogBuffer::~WebRtcLogBuffer() { | 118 WebRtcLogBuffer::~WebRtcLogBuffer() { |
| 124 DCHECK(read_only_ || thread_checker_.CalledOnValidThread()); | 119 DCHECK(read_only_ || thread_checker_.CalledOnValidThread()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 147 thread_checker_.DetachFromThread(); | 142 thread_checker_.DetachFromThread(); |
| 148 } | 143 } |
| 149 | 144 |
| 150 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost( | 145 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost( |
| 151 Profile* profile, | 146 Profile* profile, |
| 152 WebRtcLogUploader* log_uploader) | 147 WebRtcLogUploader* log_uploader) |
| 153 : BrowserMessageFilter(WebRtcLoggingMsgStart), | 148 : BrowserMessageFilter(WebRtcLoggingMsgStart), |
| 154 profile_(profile), | 149 profile_(profile), |
| 155 logging_state_(CLOSED), | 150 logging_state_(CLOSED), |
| 156 upload_log_on_render_close_(false), | 151 upload_log_on_render_close_(false), |
| 157 log_uploader_(log_uploader), | 152 log_uploader_(log_uploader) { |
| 158 is_audio_debug_recordings_in_progress_(false), | |
| 159 current_audio_debug_recordings_id_(0) { | |
| 160 DCHECK(profile_); | 153 DCHECK(profile_); |
| 161 DCHECK(log_uploader_); | 154 DCHECK(log_uploader_); |
| 162 } | 155 } |
| 163 | 156 |
| 164 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() { | 157 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() { |
| 165 // If we hit this, then we might be leaking a log reference count (see | 158 // If we hit this, then we might be leaking a log reference count (see |
| 166 // ApplyForStartLogging). | 159 // ApplyForStartLogging). |
| 167 DCHECK_EQ(CLOSED, logging_state_); | 160 DCHECK_EQ(CLOSED, logging_state_); |
| 168 } | 161 } |
| 169 | 162 |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 425 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 433 | 426 |
| 434 // |rtp_dump_handler_| could be NULL if we are waiting for the FILE thread to | 427 // |rtp_dump_handler_| could be NULL if we are waiting for the FILE thread to |
| 435 // create/ensure the log directory. | 428 // create/ensure the log directory. |
| 436 if (rtp_dump_handler_) { | 429 if (rtp_dump_handler_) { |
| 437 rtp_dump_handler_->OnRtpPacket( | 430 rtp_dump_handler_->OnRtpPacket( |
| 438 packet_header.get(), header_length, packet_length, incoming); | 431 packet_header.get(), header_length, packet_length, incoming); |
| 439 } | 432 } |
| 440 } | 433 } |
| 441 | 434 |
| 442 void WebRtcLoggingHandlerHost::StartAudioDebugRecordings( | |
| 443 content::RenderProcessHost* host, | |
| 444 base::TimeDelta delay, | |
| 445 const AudioDebugRecordingsCallback& callback, | |
| 446 const AudioDebugRecordingsErrorCallback& error_callback) { | |
| 447 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 448 | |
| 449 BrowserThread::PostTaskAndReplyWithResult( | |
| 450 BrowserThread::FILE, FROM_HERE, | |
| 451 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | |
| 452 this), | |
| 453 base::Bind(&WebRtcLoggingHandlerHost::DoStartAudioDebugRecordings, this, | |
| 454 host, delay, callback, error_callback)); | |
| 455 } | |
| 456 | |
| 457 void WebRtcLoggingHandlerHost::StopAudioDebugRecordings( | |
| 458 content::RenderProcessHost* host, | |
| 459 const AudioDebugRecordingsCallback& callback, | |
| 460 const AudioDebugRecordingsErrorCallback& error_callback) { | |
| 461 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 462 BrowserThread::PostTaskAndReplyWithResult( | |
| 463 BrowserThread::FILE, FROM_HERE, | |
| 464 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | |
| 465 this), | |
| 466 base::Bind(&WebRtcLoggingHandlerHost::DoStopAudioDebugRecordings, this, | |
| 467 host, true /* manual stop */, | |
| 468 current_audio_debug_recordings_id_, callback, error_callback)); | |
| 469 } | |
| 470 | |
| 471 void WebRtcLoggingHandlerHost::OnChannelClosing() { | 435 void WebRtcLoggingHandlerHost::OnChannelClosing() { |
| 472 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 436 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 473 if (logging_state_ == STARTED || logging_state_ == STOPPED) { | 437 if (logging_state_ == STARTED || logging_state_ == STOPPED) { |
| 474 if (upload_log_on_render_close_) { | 438 if (upload_log_on_render_close_) { |
| 475 logging_started_time_ = base::Time(); | 439 logging_started_time_ = base::Time(); |
| 476 | 440 |
| 477 content::BrowserThread::PostTaskAndReplyWithResult( | 441 content::BrowserThread::PostTaskAndReplyWithResult( |
| 478 content::BrowserThread::FILE, | 442 content::BrowserThread::FILE, |
| 479 FROM_HERE, | 443 FROM_HERE, |
| 480 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | 444 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 case STOPPED: | 761 case STOPPED: |
| 798 error_message_with_state += " State=stopped."; | 762 error_message_with_state += " State=stopped."; |
| 799 break; | 763 break; |
| 800 } | 764 } |
| 801 | 765 |
| 802 content::BrowserThread::PostTask( | 766 content::BrowserThread::PostTask( |
| 803 content::BrowserThread::UI, | 767 content::BrowserThread::UI, |
| 804 FROM_HERE, | 768 FROM_HERE, |
| 805 base::Bind(callback, success, error_message_with_state)); | 769 base::Bind(callback, success, error_message_with_state)); |
| 806 } | 770 } |
| 807 | |
| 808 void WebRtcLoggingHandlerHost::DoStartAudioDebugRecordings( | |
| 809 content::RenderProcessHost* host, | |
| 810 base::TimeDelta delay, | |
| 811 const AudioDebugRecordingsCallback& callback, | |
| 812 const AudioDebugRecordingsErrorCallback& error_callback, | |
| 813 const base::FilePath& log_directory) { | |
| 814 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 815 | |
| 816 if (is_audio_debug_recordings_in_progress_) { | |
| 817 error_callback.Run("Audio debug recordings already in progress"); | |
| 818 return; | |
| 819 } | |
| 820 | |
| 821 is_audio_debug_recordings_in_progress_ = true; | |
| 822 base::FilePath prefix_path = GetAudioDebugRecordingsPrefixPath( | |
| 823 log_directory, ++current_audio_debug_recordings_id_); | |
| 824 host->EnableAudioDebugRecordings(prefix_path); | |
| 825 | |
| 826 if (delay.is_zero()) { | |
| 827 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */, | |
| 828 false /* not manually stopped */); | |
| 829 return; | |
| 830 } | |
| 831 | |
| 832 BrowserThread::PostDelayedTask( | |
| 833 BrowserThread::UI, FROM_HERE, | |
| 834 base::Bind(&WebRtcLoggingHandlerHost::DoStopAudioDebugRecordings, this, | |
| 835 host, false /* no manual stop */, | |
| 836 current_audio_debug_recordings_id_, callback, error_callback, | |
| 837 prefix_path), | |
| 838 delay); | |
| 839 } | |
| 840 | |
| 841 void WebRtcLoggingHandlerHost::DoStopAudioDebugRecordings( | |
| 842 content::RenderProcessHost* host, | |
| 843 bool is_manual_stop, | |
| 844 uint64_t audio_debug_recordings_id, | |
| 845 const AudioDebugRecordingsCallback& callback, | |
| 846 const AudioDebugRecordingsErrorCallback& error_callback, | |
| 847 const base::FilePath& log_directory) { | |
| 848 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 849 DCHECK_LE(audio_debug_recordings_id, current_audio_debug_recordings_id_); | |
| 850 | |
| 851 base::FilePath prefix_path = GetAudioDebugRecordingsPrefixPath( | |
| 852 log_directory, audio_debug_recordings_id); | |
| 853 // Prevent an old posted StopAudioDebugRecordings() call to stop a newer dump. | |
| 854 // This could happen in a sequence like: | |
| 855 // Start(10); //Start dump 1. Post Stop() to run after 10 seconds. | |
| 856 // Stop(); // Manually stop dump 1 before 10 seconds; | |
| 857 // Start(20); // Start dump 2. Posted Stop() for 1 should not stop dump 2. | |
| 858 if (audio_debug_recordings_id < current_audio_debug_recordings_id_) { | |
| 859 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */, | |
| 860 is_manual_stop); | |
| 861 return; | |
| 862 } | |
| 863 | |
| 864 if (!is_audio_debug_recordings_in_progress_) { | |
| 865 error_callback.Run("No audio debug recording in progress"); | |
| 866 return; | |
| 867 } | |
| 868 | |
| 869 host->DisableAudioDebugRecordings(); | |
| 870 is_audio_debug_recordings_in_progress_ = false; | |
| 871 callback.Run(prefix_path.AsUTF8Unsafe(), true /* stopped */, is_manual_stop); | |
| 872 } | |
| OLD | NEW |