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

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

Issue 927233005: Adding support for storing webrtc logs locally with an extension supplied unique id, for later uplo… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 10 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
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 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/cpu.h" 11 #include "base/cpu.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
15 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
16 #include "base/sys_info.h" 16 #include "base/sys_info.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h" 19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/browser/media/webrtc_log_list.h" 20 #include "chrome/browser/media/webrtc_log_list.h"
21 #include "chrome/browser/media/webrtc_log_uploader.h" 21 #include "chrome/browser/media/webrtc_log_uploader.h"
22 #include "chrome/browser/media/webrtc_rtp_dump_handler.h" 22 #include "chrome/browser/media/webrtc_rtp_dump_handler.h"
23 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/chrome_version_info.h" 25 #include "chrome/common/chrome_version_info.h"
26 #include "chrome/common/media/webrtc_logging_messages.h" 26 #include "chrome/common/media/webrtc_logging_messages.h"
27 #include "chrome/common/partial_circular_buffer.h"
28 #include "chromeos/settings/cros_settings_names.h" 27 #include "chromeos/settings/cros_settings_names.h"
29 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/content_browser_client.h" 29 #include "content/public/browser/content_browser_client.h"
31 #include "content/public/browser/gpu_data_manager.h" 30 #include "content/public/browser/gpu_data_manager.h"
32 #include "content/public/browser/render_process_host.h" 31 #include "content/public/browser/render_process_host.h"
33 #include "gpu/config/gpu_info.h" 32 #include "gpu/config/gpu_info.h"
34 #include "net/base/address_family.h" 33 #include "net/base/address_family.h"
35 #include "net/url_request/url_request_context_getter.h" 34 #include "net/url_request/url_request_context_getter.h"
36 35
37 #if defined(OS_LINUX) 36 #if defined(OS_LINUX)
38 #include "base/linux_util.h" 37 #include "base/linux_util.h"
39 #endif 38 #endif
40 39
41 #if defined(OS_MACOSX) 40 #if defined(OS_MACOSX)
42 #include "base/mac/mac_util.h" 41 #include "base/mac/mac_util.h"
43 #endif 42 #endif
44 43
45 #if defined(OS_CHROMEOS) 44 #if defined(OS_CHROMEOS)
46 #include "chromeos/system/statistics_provider.h" 45 #include "chromeos/system/statistics_provider.h"
47 #endif 46 #endif
48 47
49 using base::IntToString; 48 using base::IntToString;
50 using content::BrowserThread; 49 using content::BrowserThread;
51 50
52 namespace { 51 namespace {
53 52
54 #if defined(OS_ANDROID)
55 const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB
56 #else
57 const size_t kWebRtcLogSize = 6 * 1024 * 1024; // 6 MB
58 #endif
59
60 const char kLogNotStoppedOrNoLogOpen[] = 53 const char kLogNotStoppedOrNoLogOpen[] =
61 "Logging not stopped or no log open."; 54 "Logging not stopped or no log open.";
62 55
63 // For privacy reasons when logging IP addresses. The returned "sensitive 56 // For privacy reasons when logging IP addresses. The returned "sensitive
64 // string" is for release builds a string with the end stripped away. Last 57 // string" is for release builds a string with the end stripped away. Last
65 // octet for IPv4 and last 80 bits (5 groups) for IPv6. String will be 58 // octet for IPv4 and last 80 bits (5 groups) for IPv6. String will be
66 // "1.2.3.x" and "1.2.3::" respectively. For debug builds, the string is 59 // "1.2.3.x" and "1.2.3::" respectively. For debug builds, the string is
67 // not stripped. 60 // not stripped.
68 std::string IPAddressToSensitiveString(const net::IPAddressNumber& address) { 61 std::string IPAddressToSensitiveString(const net::IPAddressNumber& address) {
69 #if defined(NDEBUG) 62 #if defined(NDEBUG)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 const MetaDataMap& meta_data, 94 const MetaDataMap& meta_data,
102 std::string* message) { 95 std::string* message) {
103 for (MetaDataMap::const_iterator it = meta_data.begin(); 96 for (MetaDataMap::const_iterator it = meta_data.begin();
104 it != meta_data.end(); ++it) { 97 it != meta_data.end(); ++it) {
105 *message += it->first + ": " + it->second + '\n'; 98 *message += it->first + ": " + it->second + '\n';
106 } 99 }
107 // Remove last '\n'. 100 // Remove last '\n'.
108 message->resize(message->size() - 1); 101 message->resize(message->size() - 1);
109 } 102 }
110 103
104 void FireGenericDoneCallback(
105 const WebRtcLoggingHandlerHost::GenericDoneCallback& callback,
106 bool success,
107 const std::string& error_message) {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
109 DCHECK(!callback.is_null());
110 content::BrowserThread::PostTask(
111 content::BrowserThread::UI,
112 FROM_HERE,
113 base::Bind(callback, success, error_message));
114 }
115
116 void FireAndResetGenericDoneCallback(
117 WebRtcLoggingHandlerHost::GenericDoneCallback* callback,
118 bool success,
119 const std::string& error_message) {
120 FireGenericDoneCallback(*callback, success, error_message);
121 callback->Reset();
122 }
123
111 } // namespace 124 } // namespace
112 125
126 WebRtcLogBuffer::WebRtcLogBuffer()
127 : buffer_(),
128 circular_(&buffer_[0], sizeof(buffer_), sizeof(buffer_) / 2, false),
129 read_only_(false) {
130 }
131
132 WebRtcLogBuffer::~WebRtcLogBuffer() {
133 DCHECK(read_only_ || thread_checker_.CalledOnValidThread());
134 }
135
136 void WebRtcLogBuffer::Log(const std::string& message) {
137 DCHECK(thread_checker_.CalledOnValidThread());
138 DCHECK(!read_only_);
139 circular_.Write(message.c_str(), message.length());
140 const char eol = '\n';
141 circular_.Write(&eol, 1);
142 }
143
144 PartialCircularBuffer WebRtcLogBuffer::Read() {
145 DCHECK(thread_checker_.CalledOnValidThread());
146 DCHECK(read_only_);
147 return PartialCircularBuffer(&buffer_[0], sizeof(buffer_));
148 }
149
150 void WebRtcLogBuffer::SetComplete() {
151 DCHECK(thread_checker_.CalledOnValidThread());
152 DCHECK(!read_only_) << "Already set? (programmer error)";
153 read_only_ = true;
154 // Detach from the current thread so that we can check reads on a different
155 // thread. This is to make sure that Read()s still happen on one thread only.
156 thread_checker_.DetachFromThread();
157 }
158
113 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost(Profile* profile) 159 WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost(Profile* profile)
114 : BrowserMessageFilter(WebRtcLoggingMsgStart), 160 : BrowserMessageFilter(WebRtcLoggingMsgStart),
115 profile_(profile), 161 profile_(profile),
116 logging_state_(CLOSED), 162 logging_state_(CLOSED),
117 upload_log_on_render_close_(false) { 163 upload_log_on_render_close_(false) {
118 DCHECK(profile_); 164 DCHECK(profile_);
119 } 165 }
120 166
121 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {} 167 WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {}
122 168
123 void WebRtcLoggingHandlerHost::SetMetaData( 169 void WebRtcLoggingHandlerHost::SetMetaData(
124 const MetaDataMap& meta_data, 170 scoped_ptr<MetaDataMap> meta_data,
125 const GenericDoneCallback& callback) { 171 const GenericDoneCallback& callback) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
127 DCHECK(!callback.is_null()); 173 DCHECK(!callback.is_null());
128 174
129 std::string error_message; 175 std::string error_message;
130 if (logging_state_ == CLOSED) { 176 if (logging_state_ == CLOSED) {
131 meta_data_ = meta_data; 177 if (!meta_data_.get())
178 meta_data_ = meta_data.Pass();
132 } else if (logging_state_ == STARTED) { 179 } else if (logging_state_ == STARTED) {
133 meta_data_ = meta_data;
134 std::string meta_data_message; 180 std::string meta_data_message;
135 FormatMetaDataAsLogMessage(meta_data_, &meta_data_message); 181 FormatMetaDataAsLogMessage(*meta_data.get(), &meta_data_message);
136 LogToCircularBuffer(meta_data_message); 182 LogToCircularBuffer(meta_data_message);
137 } else { 183 } else {
138 error_message = "Meta data must be set before stop or upload."; 184 error_message = "Meta data must be set before stop or upload.";
139 } 185 }
140 bool success = error_message.empty(); 186
141 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 187 if (error_message.empty() && meta_data.get()) {
142 base::Bind(callback, success, 188 // Keep the meta data around for uploading separately from the log.
143 error_message)); 189 for (const auto& it : *meta_data.get())
190 (*meta_data_.get())[it.first] = it.second;
191 }
192
193 FireGenericDoneCallback(callback, error_message.empty(), error_message);
144 } 194 }
145 195
146 void WebRtcLoggingHandlerHost::StartLogging( 196 void WebRtcLoggingHandlerHost::StartLogging(
147 const GenericDoneCallback& callback) { 197 const GenericDoneCallback& callback) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
149 DCHECK(!callback.is_null()); 199 DCHECK(!callback.is_null());
150 200
151 start_callback_ = callback;
152 if (logging_state_ != CLOSED) { 201 if (logging_state_ != CLOSED) {
153 FireGenericDoneCallback(&start_callback_, false, "A log is already open"); 202 FireGenericDoneCallback(callback, false, "A log is already open");
154 return; 203 return;
155 } 204 }
205
156 logging_state_ = STARTING; 206 logging_state_ = STARTING;
157 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( 207 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
158 &WebRtcLoggingHandlerHost::StartLoggingIfAllowed, this)); 208 &WebRtcLoggingHandlerHost::StartLoggingIfAllowed, this, callback));
159 } 209 }
160 210
161 void WebRtcLoggingHandlerHost::StopLogging( 211 void WebRtcLoggingHandlerHost::StopLogging(
162 const GenericDoneCallback& callback) { 212 const GenericDoneCallback& callback) {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
164 DCHECK(!callback.is_null()); 214 DCHECK(!callback.is_null());
165 215
166 stop_callback_ = callback;
167 if (logging_state_ != STARTED) { 216 if (logging_state_ != STARTED) {
168 FireGenericDoneCallback(&stop_callback_, false, "Logging not started"); 217 FireGenericDoneCallback(callback, false, "Logging not started");
169 return; 218 return;
170 } 219 }
220
221 stop_callback_ = callback;
171 logging_state_ = STOPPING; 222 logging_state_ = STOPPING;
172 Send(new WebRtcLoggingMsg_StopLogging()); 223 Send(new WebRtcLoggingMsg_StopLogging());
173 } 224 }
174 225
175 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) { 226 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177 DCHECK(!callback.is_null()); 228 DCHECK(!callback.is_null());
178 229
179 if (logging_state_ != STOPPED) { 230 if (logging_state_ != STOPPED) {
180 if (!callback.is_null()) { 231 if (!callback.is_null()) {
181 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 232 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
182 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen)); 233 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen));
183 } 234 }
184 return; 235 return;
185 } 236 }
186 237
187 upload_callback_ = callback;
188 logging_state_ = UPLOADING;
189 content::BrowserThread::PostTaskAndReplyWithResult( 238 content::BrowserThread::PostTaskAndReplyWithResult(
190 content::BrowserThread::FILE, 239 content::BrowserThread::FILE,
191 FROM_HERE, 240 FROM_HERE,
192 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, 241 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
193 this), 242 this),
194 base::Bind(&WebRtcLoggingHandlerHost::TriggerUpload, this)); 243 base::Bind(&WebRtcLoggingHandlerHost::TriggerUpload, this, callback));
244 }
245
246 void WebRtcLoggingHandlerHost::UploadStoredLog(
247 const std::string& log_id,
248 const UploadDoneCallback& callback) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
250 DCHECK(!callback.is_null());
251
252 content::BrowserThread::PostTask(content::BrowserThread::FILE,
253 FROM_HERE,
254 base::Bind(&WebRtcLoggingHandlerHost::UploadStoredLogOnFileThread,
255 this, log_id, callback));
256 }
257
258 void WebRtcLoggingHandlerHost::UploadStoredLogOnFileThread(
259 const std::string& log_id,
260 const UploadDoneCallback& callback) {
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
262
263 WebRtcLogUploadDoneData upload_data;
264 upload_data.log_path = GetLogDirectoryAndEnsureExists();
265 upload_data.callback = callback;
266 upload_data.host = this;
267 upload_data.local_log_id = log_id;
268
269 g_browser_process->webrtc_log_uploader()->UploadStoredLog(upload_data);
195 } 270 }
196 271
197 void WebRtcLoggingHandlerHost::UploadLogDone() { 272 void WebRtcLoggingHandlerHost::UploadLogDone() {
198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
199 logging_state_ = CLOSED; 274 logging_state_ = CLOSED;
200 } 275 }
201 276
202 void WebRtcLoggingHandlerHost::DiscardLog(const GenericDoneCallback& callback) { 277 void WebRtcLoggingHandlerHost::DiscardLog(const GenericDoneCallback& callback) {
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
204 DCHECK(!callback.is_null()); 279 DCHECK(!callback.is_null());
205 280
206 GenericDoneCallback discard_callback = callback;
207 if (logging_state_ != STOPPED) { 281 if (logging_state_ != STOPPED) {
208 FireGenericDoneCallback(&discard_callback, false, 282 FireGenericDoneCallback(callback, false, kLogNotStoppedOrNoLogOpen);
209 kLogNotStoppedOrNoLogOpen);
210 return; 283 return;
211 } 284 }
212 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload(); 285 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload();
213 circular_buffer_.reset();
214 log_buffer_.reset(); 286 log_buffer_.reset();
287 meta_data_.reset();
215 logging_state_ = CLOSED; 288 logging_state_ = CLOSED;
216 rtp_dump_handler_.reset(); 289 rtp_dump_handler_.reset();
217 stop_rtp_dump_callback_.Reset(); 290 stop_rtp_dump_callback_.Reset();
218 FireGenericDoneCallback(&discard_callback, true, ""); 291 FireGenericDoneCallback(callback, true, "");
292 }
293
294 // Stores the log locally using a hash of log_id + security origin.
295 void WebRtcLoggingHandlerHost::StoreLog(
296 const std::string& log_id,
297 const GenericDoneCallback& callback) {
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
299 DCHECK(!callback.is_null());
300
301 if (logging_state_ != STOPPED) {
302 FireGenericDoneCallback(callback, false, kLogNotStoppedOrNoLogOpen);
303 return;
304 }
305
306 if (rtp_dump_handler_) {
307 BrowserThread::PostTask(
308 BrowserThread::UI,
309 FROM_HERE,
310 base::Bind(stop_rtp_dump_callback_, true, true));
311
312 rtp_dump_handler_->StopOngoingDumps(
313 base::Bind(&WebRtcLoggingHandlerHost::StoreLogContinue,
314 this, log_id, callback));
315 return;
316 }
317
318 StoreLogContinue(log_id, callback);
319 }
320
321 void WebRtcLoggingHandlerHost::StoreLogContinue(
322 const std::string& log_id,
323 const GenericDoneCallback& callback) {
324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
325 DCHECK(!callback.is_null());
326
327 scoped_ptr<WebRtcLogPaths> log_paths(new WebRtcLogPaths());
328 ReleaseRtpDumps(log_paths.get());
329
330 content::BrowserThread::PostTaskAndReplyWithResult(
331 content::BrowserThread::FILE,
332 FROM_HERE,
333 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
334 this),
335 base::Bind(&WebRtcLoggingHandlerHost::StoreLogInDirectory, this, log_id,
336 Passed(&log_paths), callback));
219 } 337 }
220 338
221 void WebRtcLoggingHandlerHost::LogMessage(const std::string& message) { 339 void WebRtcLoggingHandlerHost::LogMessage(const std::string& message) {
222 BrowserThread::PostTask( 340 BrowserThread::PostTask(
223 BrowserThread::IO, 341 BrowserThread::IO,
224 FROM_HERE, 342 FROM_HERE,
225 base::Bind( 343 base::Bind(
226 &WebRtcLoggingHandlerHost::AddLogMessageFromBrowser, 344 &WebRtcLoggingHandlerHost::AddLogMessageFromBrowser,
227 this, 345 this,
228 WebRtcLoggingMessageData(base::Time::Now(), message))); 346 WebRtcLoggingMessageData(base::Time::Now(), message)));
(...skipping 16 matching lines...) Expand all
245 FROM_HERE, 363 FROM_HERE,
246 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, 364 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
247 this), 365 this),
248 base::Bind(&WebRtcLoggingHandlerHost::CreateRtpDumpHandlerAndStart, 366 base::Bind(&WebRtcLoggingHandlerHost::CreateRtpDumpHandlerAndStart,
249 this, 367 this,
250 type, 368 type,
251 callback)); 369 callback));
252 return; 370 return;
253 } 371 }
254 372
255 GenericDoneCallback start_callback = callback; 373 DoStartRtpDump(type, callback);
256 DoStartRtpDump(type, &start_callback);
257 } 374 }
258 375
259 void WebRtcLoggingHandlerHost::StopRtpDump( 376 void WebRtcLoggingHandlerHost::StopRtpDump(
260 RtpDumpType type, 377 RtpDumpType type,
261 const GenericDoneCallback& callback) { 378 const GenericDoneCallback& callback) {
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
263 DCHECK(!callback.is_null()); 380 DCHECK(!callback.is_null());
264 381
265 if (!rtp_dump_handler_) { 382 if (!rtp_dump_handler_) {
266 GenericDoneCallback stop_callback = callback; 383 FireGenericDoneCallback(callback, false, "RTP dump has not been started.");
267 FireGenericDoneCallback(
268 &stop_callback, false, "RTP dump has not been started.");
269 return; 384 return;
270 } 385 }
271 386
272 if (!stop_rtp_dump_callback_.is_null()) { 387 if (!stop_rtp_dump_callback_.is_null()) {
273 BrowserThread::PostTask( 388 BrowserThread::PostTask(
274 BrowserThread::UI, 389 BrowserThread::UI,
275 FROM_HERE, 390 FROM_HERE,
276 base::Bind(stop_rtp_dump_callback_, 391 base::Bind(stop_rtp_dump_callback_,
277 type == RTP_DUMP_INCOMING || type == RTP_DUMP_BOTH, 392 type == RTP_DUMP_INCOMING || type == RTP_DUMP_BOTH,
278 type == RTP_DUMP_OUTGOING || type == RTP_DUMP_BOTH)); 393 type == RTP_DUMP_OUTGOING || type == RTP_DUMP_BOTH));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 if (rtp_dump_handler_) { 425 if (rtp_dump_handler_) {
311 rtp_dump_handler_->OnRtpPacket( 426 rtp_dump_handler_->OnRtpPacket(
312 packet_header.get(), header_length, packet_length, incoming); 427 packet_header.get(), header_length, packet_length, incoming);
313 } 428 }
314 } 429 }
315 430
316 void WebRtcLoggingHandlerHost::OnChannelClosing() { 431 void WebRtcLoggingHandlerHost::OnChannelClosing() {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
318 if (logging_state_ == STARTED || logging_state_ == STOPPED) { 433 if (logging_state_ == STARTED || logging_state_ == STOPPED) {
319 if (upload_log_on_render_close_) { 434 if (upload_log_on_render_close_) {
320 logging_state_ = UPLOADING;
321 logging_started_time_ = base::Time(); 435 logging_started_time_ = base::Time();
322 436
323 content::BrowserThread::PostTaskAndReplyWithResult( 437 content::BrowserThread::PostTaskAndReplyWithResult(
324 content::BrowserThread::FILE, 438 content::BrowserThread::FILE,
325 FROM_HERE, 439 FROM_HERE,
326 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, 440 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
327 this), 441 this),
328 base::Bind(&WebRtcLoggingHandlerHost::TriggerUpload, this)); 442 base::Bind(&WebRtcLoggingHandlerHost::TriggerUpload, this,
443 UploadDoneCallback()));
329 } else { 444 } else {
330 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload(); 445 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload();
331 } 446 }
332 } 447 }
333 content::BrowserMessageFilter::OnChannelClosing(); 448 content::BrowserMessageFilter::OnChannelClosing();
334 } 449 }
335 450
336 void WebRtcLoggingHandlerHost::OnDestruct() const { 451 void WebRtcLoggingHandlerHost::OnDestruct() const {
337 BrowserThread::DeleteOnIOThread::Destruct(this); 452 BrowserThread::DeleteOnIOThread::Destruct(this);
338 } 453 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 if (logging_state_ != STOPPING) { 487 if (logging_state_ != STOPPING) {
373 // If an out-of-order response is received, stop_callback_ may be invalid, 488 // If an out-of-order response is received, stop_callback_ may be invalid,
374 // and must not be invoked. 489 // and must not be invoked.
375 DLOG(ERROR) << "OnLoggingStoppedInRenderer invoked in state " 490 DLOG(ERROR) << "OnLoggingStoppedInRenderer invoked in state "
376 << logging_state_; 491 << logging_state_;
377 BadMessageReceived(); 492 BadMessageReceived();
378 return; 493 return;
379 } 494 }
380 logging_started_time_ = base::Time(); 495 logging_started_time_ = base::Time();
381 logging_state_ = STOPPED; 496 logging_state_ = STOPPED;
382 FireGenericDoneCallback(&stop_callback_, true, ""); 497 FireAndResetGenericDoneCallback(&stop_callback_, true, "");
383 } 498 }
384 499
385 void WebRtcLoggingHandlerHost::StartLoggingIfAllowed() { 500 void WebRtcLoggingHandlerHost::StartLoggingIfAllowed(
501 const GenericDoneCallback& callback) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387 if (!g_browser_process->webrtc_log_uploader()->ApplyForStartLogging()) { 503 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
388 logging_state_ = CLOSED; 504 &WebRtcLoggingHandlerHost::DoStartLogging, this,
389 FireGenericDoneCallback( 505 g_browser_process->webrtc_log_uploader()->ApplyForStartLogging(),
390 &start_callback_, false, "Cannot start, maybe the maximum number of " 506 callback));
391 "simultaneuos logs has been reached."); 507 }
508
509 void WebRtcLoggingHandlerHost::DoStartLogging(
510 bool permissions_granted,
511 const GenericDoneCallback& callback) {
512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
513 if (logging_state_ != STARTING) {
514 FireGenericDoneCallback(callback, false, "Logging cancelled.");
392 return; 515 return;
393 } 516 }
394 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 517
395 &WebRtcLoggingHandlerHost::DoStartLogging, this)); 518 if (!permissions_granted) {
519 logging_state_ = CLOSED;
520 FireGenericDoneCallback(callback, false,
521 "Cannot start, maybe the maximum number of "
522 "simultaneuos logs has been reached.");
523 return;
524 }
525
526 DCHECK(!log_buffer_.get());
527 log_buffer_.reset(new WebRtcLogBuffer());
528 if (!meta_data_.get())
529 meta_data_.reset(new MetaDataMap());
530
531 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
532 &WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread, this, callback));
396 } 533 }
397 534
398 void WebRtcLoggingHandlerHost::DoStartLogging() { 535 void WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread(
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 536 const GenericDoneCallback& callback) {
400
401 log_buffer_.reset(new unsigned char[kWebRtcLogSize]);
402 circular_buffer_.reset(
403 new PartialCircularBuffer(log_buffer_.get(),
404 kWebRtcLogSize,
405 kWebRtcLogSize / 2,
406 false));
407
408 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
409 &WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread, this));
410 }
411
412 void WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread() {
413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
414 538
415 net::NetworkInterfaceList network_list; 539 net::NetworkInterfaceList network_list;
416 net::GetNetworkList(&network_list, 540 net::GetNetworkList(&network_list,
417 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); 541 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
418 542
419 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 543 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
420 &WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, this, network_list)); 544 &WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, this, network_list,
545 callback));
421 } 546 }
422 547
423 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread( 548 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread(
424 const net::NetworkInterfaceList& network_list) { 549 const net::NetworkInterfaceList& network_list,
550 const GenericDoneCallback& callback) {
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
552 if (logging_state_ != STARTING) {
553 FireGenericDoneCallback(callback, false, "Logging cancelled.");
554 return;
555 }
426 556
427 // Log start time (current time). We don't use base/i18n/time_formatting.h 557 // Log start time (current time). We don't use base/i18n/time_formatting.h
428 // here because we don't want the format of the current locale. 558 // here because we don't want the format of the current locale.
429 base::Time::Exploded now = {0}; 559 base::Time::Exploded now = {0};
430 base::Time::Now().LocalExplode(&now); 560 base::Time::Now().LocalExplode(&now);
431 LogToCircularBuffer(base::StringPrintf( 561 LogToCircularBuffer(base::StringPrintf(
432 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month, 562 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month,
433 now.day_of_month, now.hour, now.minute, now.second)); 563 now.day_of_month, now.hour, now.minute, now.second));
434 564
435 // Write metadata if received before logging started. 565 // Write metadata if received before logging started.
436 if (!meta_data_.empty()) { 566 if (meta_data_.get() && !meta_data_->empty()) {
437 std::string info; 567 std::string info;
438 FormatMetaDataAsLogMessage(meta_data_, &info); 568 FormatMetaDataAsLogMessage(*meta_data_.get(), &info);
439 LogToCircularBuffer(info); 569 LogToCircularBuffer(info);
440 } 570 }
441 571
442 // Chrome version 572 // Chrome version
443 chrome::VersionInfo version_info; 573 chrome::VersionInfo version_info;
444 LogToCircularBuffer("Chrome version: " + version_info.Version() + " " + 574 LogToCircularBuffer("Chrome version: " + version_info.Version() + " " +
445 chrome::VersionInfo::GetVersionStringModifier()); 575 chrome::VersionInfo::GetVersionStringModifier());
446 576
447 // OS 577 // OS
448 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " + 578 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " +
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 LogToCircularBuffer("Discovered " + IntToString(network_list.size()) + 625 LogToCircularBuffer("Discovered " + IntToString(network_list.size()) +
496 " network interfaces:"); 626 " network interfaces:");
497 for (net::NetworkInterfaceList::const_iterator it = network_list.begin(); 627 for (net::NetworkInterfaceList::const_iterator it = network_list.begin();
498 it != network_list.end(); ++it) { 628 it != network_list.end(); ++it) {
499 LogToCircularBuffer( 629 LogToCircularBuffer(
500 "Name: " + it->friendly_name + ", Address: " + 630 "Name: " + it->friendly_name + ", Address: " +
501 IPAddressToSensitiveString(it->address) + ", Type: " + 631 IPAddressToSensitiveString(it->address) + ", Type: " +
502 net::NetworkChangeNotifier::ConnectionTypeToString(it->type)); 632 net::NetworkChangeNotifier::ConnectionTypeToString(it->type));
503 } 633 }
504 634
505 NotifyLoggingStarted(); 635 NotifyLoggingStarted(callback);
506 } 636 }
507 637
508 void WebRtcLoggingHandlerHost::NotifyLoggingStarted() { 638 void WebRtcLoggingHandlerHost::NotifyLoggingStarted(
639 const GenericDoneCallback& callback) {
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
641 DCHECK_EQ(logging_state_, STARTING);
510 Send(new WebRtcLoggingMsg_StartLogging()); 642 Send(new WebRtcLoggingMsg_StartLogging());
511 logging_started_time_ = base::Time::Now(); 643 logging_started_time_ = base::Time::Now();
512 logging_state_ = STARTED; 644 logging_state_ = STARTED;
513 FireGenericDoneCallback(&start_callback_, true, ""); 645 FireGenericDoneCallback(callback, true, "");
514 } 646 }
515 647
516 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) { 648 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) {
517 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
518 DCHECK(circular_buffer_.get()); 650 DCHECK_NE(logging_state_, CLOSED);
519 circular_buffer_->Write(message.c_str(), message.length()); 651 log_buffer_->Log(message);
520 const char eol = '\n';
521 circular_buffer_->Write(&eol, 1);
522 } 652 }
523 653
524 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() { 654 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() {
525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
526 base::FilePath log_dir_path = 656 base::FilePath log_dir_path =
527 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath()); 657 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath());
528 base::File::Error error; 658 base::File::Error error;
529 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) { 659 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) {
530 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error; 660 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error;
531 return base::FilePath(); 661 return base::FilePath();
532 } 662 }
533 return log_dir_path; 663 return log_dir_path;
534 } 664 }
535 665
536 void WebRtcLoggingHandlerHost::TriggerUpload( 666 void WebRtcLoggingHandlerHost::TriggerUpload(
667 const UploadDoneCallback& callback,
537 const base::FilePath& log_directory) { 668 const base::FilePath& log_directory) {
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
539 DCHECK_EQ(logging_state_, UPLOADING);
540 670
541 if (rtp_dump_handler_) { 671 if (rtp_dump_handler_) {
542 BrowserThread::PostTask( 672 BrowserThread::PostTask(
543 BrowserThread::UI, 673 BrowserThread::UI,
544 FROM_HERE, 674 FROM_HERE,
545 base::Bind(stop_rtp_dump_callback_, true, true)); 675 base::Bind(stop_rtp_dump_callback_, true, true));
546 676
547 rtp_dump_handler_->StopOngoingDumps( 677 rtp_dump_handler_->StopOngoingDumps(
548 base::Bind(&WebRtcLoggingHandlerHost::DoUploadLogAndRtpDumps, 678 base::Bind(&WebRtcLoggingHandlerHost::DoUploadLogAndRtpDumps,
549 this, 679 this,
550 log_directory)); 680 log_directory,
681 callback));
551 return; 682 return;
552 } 683 }
553 684
554 DoUploadLogAndRtpDumps(log_directory); 685 DoUploadLogAndRtpDumps(log_directory, callback);
686 }
687
688 void WebRtcLoggingHandlerHost::StoreLogInDirectory(
689 const std::string& log_id,
690 scoped_ptr<WebRtcLogPaths> log_paths,
691 const GenericDoneCallback& done_callback,
692 const base::FilePath& directory) {
693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
694 log_paths->log_path = directory;
695
696 log_buffer_->SetComplete();
697 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
698 base::Bind(&WebRtcLogUploader::LoggingStoppedDoStore,
699 base::Unretained(g_browser_process->webrtc_log_uploader()),
700 *log_paths.get(), log_id, Passed(&log_buffer_), Passed(&meta_data_),
701 done_callback));
702
703 logging_state_ = CLOSED;
555 } 704 }
556 705
557 void WebRtcLoggingHandlerHost::DoUploadLogAndRtpDumps( 706 void WebRtcLoggingHandlerHost::DoUploadLogAndRtpDumps(
558 const base::FilePath& log_directory) { 707 const base::FilePath& log_directory,
708 const UploadDoneCallback& callback) {
709 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
710
559 WebRtcLogUploadDoneData upload_done_data; 711 WebRtcLogUploadDoneData upload_done_data;
560 upload_done_data.log_path = log_directory; 712 upload_done_data.log_path = log_directory;
713 upload_done_data.callback = callback;
714 upload_done_data.host = this;
715 ReleaseRtpDumps(&upload_done_data);
561 716
562 if (rtp_dump_handler_) { 717 log_buffer_->SetComplete();
563 WebRtcRtpDumpHandler::ReleasedDumps rtp_dumps(
564 rtp_dump_handler_->ReleaseDumps());
565 upload_done_data.incoming_rtp_dump = rtp_dumps.incoming_dump_path;
566 upload_done_data.outgoing_rtp_dump = rtp_dumps.outgoing_dump_path;
567
568 rtp_dump_handler_.reset();
569 stop_rtp_dump_callback_.Reset();
570 }
571
572 upload_done_data.callback = upload_callback_;
573 upload_done_data.host = this;
574 upload_callback_.Reset();
575
576 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( 718 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
577 &WebRtcLogUploader::LoggingStoppedDoUpload, 719 &WebRtcLogUploader::LoggingStoppedDoUpload,
578 base::Unretained(g_browser_process->webrtc_log_uploader()), 720 base::Unretained(g_browser_process->webrtc_log_uploader()),
579 Passed(&log_buffer_), 721 Passed(&log_buffer_),
580 kWebRtcLogSize, 722 Passed(&meta_data_),
581 meta_data_,
582 upload_done_data)); 723 upload_done_data));
583 724
584 meta_data_.clear(); 725 logging_state_ = CLOSED;
585 circular_buffer_.reset();
586 }
587
588 void WebRtcLoggingHandlerHost::FireGenericDoneCallback(
589 GenericDoneCallback* callback,
590 bool success,
591 const std::string& error_message) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
593 DCHECK(!(*callback).is_null());
594 content::BrowserThread::PostTask(
595 content::BrowserThread::UI,
596 FROM_HERE,
597 base::Bind(*callback, success, error_message));
598 (*callback).Reset();
599 } 726 }
600 727
601 void WebRtcLoggingHandlerHost::CreateRtpDumpHandlerAndStart( 728 void WebRtcLoggingHandlerHost::CreateRtpDumpHandlerAndStart(
602 RtpDumpType type, 729 RtpDumpType type,
603 GenericDoneCallback callback, 730 const GenericDoneCallback& callback,
604 const base::FilePath& dump_dir) { 731 const base::FilePath& dump_dir) {
605 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 732 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
606 733
607 // |rtp_dump_handler_| may be non-NULL if StartRtpDump is called again before 734 // |rtp_dump_handler_| may be non-NULL if StartRtpDump is called again before
608 // GetLogDirectoryAndEnsureExists returns on the FILE thread for a previous 735 // GetLogDirectoryAndEnsureExists returns on the FILE thread for a previous
609 // StartRtpDump. 736 // StartRtpDump.
610 if (!rtp_dump_handler_) 737 if (!rtp_dump_handler_)
611 rtp_dump_handler_.reset(new WebRtcRtpDumpHandler(dump_dir)); 738 rtp_dump_handler_.reset(new WebRtcRtpDumpHandler(dump_dir));
612 739
613 DoStartRtpDump(type, &callback); 740 DoStartRtpDump(type, callback);
614 } 741 }
615 742
616 void WebRtcLoggingHandlerHost::DoStartRtpDump(RtpDumpType type, 743 void WebRtcLoggingHandlerHost::DoStartRtpDump(
617 GenericDoneCallback* callback) { 744 RtpDumpType type, const GenericDoneCallback& callback) {
618 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
619 DCHECK(rtp_dump_handler_); 746 DCHECK(rtp_dump_handler_);
620 747
621 std::string error; 748 std::string error;
622
623 bool result = rtp_dump_handler_->StartDump(type, &error); 749 bool result = rtp_dump_handler_->StartDump(type, &error);
624 FireGenericDoneCallback(callback, result, error); 750 FireGenericDoneCallback(callback, result, error);
625 } 751 }
752
753 bool WebRtcLoggingHandlerHost::ReleaseRtpDumps(WebRtcLogPaths* log_paths) {
754 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
755 DCHECK(log_paths);
756
757 if (!rtp_dump_handler_)
758 return false;
759
760 WebRtcRtpDumpHandler::ReleasedDumps rtp_dumps(
761 rtp_dump_handler_->ReleaseDumps());
762 log_paths->incoming_rtp_dump = rtp_dumps.incoming_dump_path;
763 log_paths->outgoing_rtp_dump = rtp_dumps.outgoing_dump_path;
764
765 rtp_dump_handler_.reset();
766 stop_rtp_dump_callback_.Reset();
767
768 return true;
769 }
OLDNEW
« no previous file with comments | « chrome/browser/media/webrtc_logging_handler_host.h ('k') | chrome/common/extensions/api/webrtc_logging_private.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698