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 24 matching lines...) Expand all Loading... |
149 | 144 |
150 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost( | 145 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost( |
151 int render_process_id, | 146 int render_process_id, |
152 Profile* profile, | 147 Profile* profile, |
153 WebRtcLogUploader* log_uploader) | 148 WebRtcLogUploader* log_uploader) |
154 : BrowserMessageFilter(WebRtcLoggingMsgStart), | 149 : BrowserMessageFilter(WebRtcLoggingMsgStart), |
155 profile_(profile), | 150 profile_(profile), |
156 logging_state_(CLOSED), | 151 logging_state_(CLOSED), |
157 upload_log_on_render_close_(false), | 152 upload_log_on_render_close_(false), |
158 log_uploader_(log_uploader), | 153 log_uploader_(log_uploader), |
159 is_audio_debug_recordings_in_progress_(false), | |
160 current_audio_debug_recordings_id_(0), | |
161 render_process_id_(render_process_id) { | 154 render_process_id_(render_process_id) { |
162 DCHECK(profile_); | 155 DCHECK(profile_); |
163 DCHECK(log_uploader_); | 156 DCHECK(log_uploader_); |
164 } | 157 } |
165 | 158 |
166 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() { | 159 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() { |
167 // If we hit this, then we might be leaking a log reference count (see | 160 // If we hit this, then we might be leaking a log reference count (see |
168 // ApplyForStartLogging). | 161 // ApplyForStartLogging). |
169 DCHECK_EQ(CLOSED, logging_state_); | 162 DCHECK_EQ(CLOSED, logging_state_); |
170 } | 163 } |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 435 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
443 | 436 |
444 // |rtp_dump_handler_| could be NULL if we are waiting for the FILE thread to | 437 // |rtp_dump_handler_| could be NULL if we are waiting for the FILE thread to |
445 // create/ensure the log directory. | 438 // create/ensure the log directory. |
446 if (rtp_dump_handler_) { | 439 if (rtp_dump_handler_) { |
447 rtp_dump_handler_->OnRtpPacket( | 440 rtp_dump_handler_->OnRtpPacket( |
448 packet_header.get(), header_length, packet_length, incoming); | 441 packet_header.get(), header_length, packet_length, incoming); |
449 } | 442 } |
450 } | 443 } |
451 | 444 |
452 void WebRtcLoggingHandlerHost::StartAudioDebugRecordings( | |
453 content::RenderProcessHost* host, | |
454 base::TimeDelta delay, | |
455 const AudioDebugRecordingsCallback& callback, | |
456 const AudioDebugRecordingsErrorCallback& error_callback) { | |
457 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
458 | |
459 BrowserThread::PostTaskAndReplyWithResult( | |
460 BrowserThread::FILE, FROM_HERE, | |
461 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | |
462 this), | |
463 base::Bind(&WebRtcLoggingHandlerHost::DoStartAudioDebugRecordings, this, | |
464 host, delay, callback, error_callback)); | |
465 } | |
466 | |
467 void WebRtcLoggingHandlerHost::StopAudioDebugRecordings( | |
468 content::RenderProcessHost* host, | |
469 const AudioDebugRecordingsCallback& callback, | |
470 const AudioDebugRecordingsErrorCallback& error_callback) { | |
471 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
472 BrowserThread::PostTaskAndReplyWithResult( | |
473 BrowserThread::FILE, FROM_HERE, | |
474 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | |
475 this), | |
476 base::Bind(&WebRtcLoggingHandlerHost::DoStopAudioDebugRecordings, this, | |
477 host, true /* manual stop */, | |
478 current_audio_debug_recordings_id_, callback, error_callback)); | |
479 } | |
480 | |
481 void WebRtcLoggingHandlerHost::OnChannelClosing() { | 445 void WebRtcLoggingHandlerHost::OnChannelClosing() { |
482 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 446 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
483 if (logging_state_ == STARTED || logging_state_ == STOPPED) { | 447 if (logging_state_ == STARTED || logging_state_ == STOPPED) { |
484 if (upload_log_on_render_close_) { | 448 if (upload_log_on_render_close_) { |
485 logging_started_time_ = base::Time(); | 449 logging_started_time_ = base::Time(); |
486 | 450 |
487 content::BrowserThread::PostTaskAndReplyWithResult( | 451 content::BrowserThread::PostTaskAndReplyWithResult( |
488 content::BrowserThread::FILE, | 452 content::BrowserThread::FILE, |
489 FROM_HERE, | 453 FROM_HERE, |
490 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | 454 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 case STOPPED: | 798 case STOPPED: |
835 error_message_with_state += " State=stopped."; | 799 error_message_with_state += " State=stopped."; |
836 break; | 800 break; |
837 } | 801 } |
838 | 802 |
839 content::BrowserThread::PostTask( | 803 content::BrowserThread::PostTask( |
840 content::BrowserThread::UI, | 804 content::BrowserThread::UI, |
841 FROM_HERE, | 805 FROM_HERE, |
842 base::Bind(callback, success, error_message_with_state)); | 806 base::Bind(callback, success, error_message_with_state)); |
843 } | 807 } |
844 | |
845 void WebRtcLoggingHandlerHost::DoStartAudioDebugRecordings( | |
846 content::RenderProcessHost* host, | |
847 base::TimeDelta delay, | |
848 const AudioDebugRecordingsCallback& callback, | |
849 const AudioDebugRecordingsErrorCallback& error_callback, | |
850 const base::FilePath& log_directory) { | |
851 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
852 | |
853 if (is_audio_debug_recordings_in_progress_) { | |
854 error_callback.Run("Audio debug recordings already in progress"); | |
855 return; | |
856 } | |
857 | |
858 is_audio_debug_recordings_in_progress_ = true; | |
859 base::FilePath prefix_path = GetAudioDebugRecordingsPrefixPath( | |
860 log_directory, ++current_audio_debug_recordings_id_); | |
861 host->EnableAudioDebugRecordings(prefix_path); | |
862 | |
863 if (delay.is_zero()) { | |
864 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */, | |
865 false /* not manually stopped */); | |
866 return; | |
867 } | |
868 | |
869 BrowserThread::PostDelayedTask( | |
870 BrowserThread::UI, FROM_HERE, | |
871 base::Bind(&WebRtcLoggingHandlerHost::DoStopAudioDebugRecordings, this, | |
872 host, false /* no manual stop */, | |
873 current_audio_debug_recordings_id_, callback, error_callback, | |
874 prefix_path), | |
875 delay); | |
876 } | |
877 | |
878 void WebRtcLoggingHandlerHost::DoStopAudioDebugRecordings( | |
879 content::RenderProcessHost* host, | |
880 bool is_manual_stop, | |
881 uint64_t audio_debug_recordings_id, | |
882 const AudioDebugRecordingsCallback& callback, | |
883 const AudioDebugRecordingsErrorCallback& error_callback, | |
884 const base::FilePath& log_directory) { | |
885 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
886 DCHECK_LE(audio_debug_recordings_id, current_audio_debug_recordings_id_); | |
887 | |
888 base::FilePath prefix_path = GetAudioDebugRecordingsPrefixPath( | |
889 log_directory, audio_debug_recordings_id); | |
890 // Prevent an old posted StopAudioDebugRecordings() call to stop a newer dump. | |
891 // This could happen in a sequence like: | |
892 // Start(10); //Start dump 1. Post Stop() to run after 10 seconds. | |
893 // Stop(); // Manually stop dump 1 before 10 seconds; | |
894 // Start(20); // Start dump 2. Posted Stop() for 1 should not stop dump 2. | |
895 if (audio_debug_recordings_id < current_audio_debug_recordings_id_) { | |
896 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */, | |
897 is_manual_stop); | |
898 return; | |
899 } | |
900 | |
901 if (!is_audio_debug_recordings_in_progress_) { | |
902 error_callback.Run("No audio debug recording in progress"); | |
903 return; | |
904 } | |
905 | |
906 host->DisableAudioDebugRecordings(); | |
907 is_audio_debug_recordings_in_progress_ = false; | |
908 callback.Run(prefix_path.AsUTF8Unsafe(), true /* stopped */, is_manual_stop); | |
909 } | |
OLD | NEW |