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