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