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 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | |
11 #include "base/cpu.h" | 10 #include "base/cpu.h" |
12 #include "base/file_util.h" | 11 #include "base/file_util.h" |
13 #include "base/logging.h" | 12 #include "base/logging.h" |
14 #include "base/prefs/pref_service.h" | |
15 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
16 #include "base/sys_info.h" | 14 #include "base/sys_info.h" |
17 #include "base/time/time.h" | 15 #include "base/time/time.h" |
18 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
19 #include "chrome/browser/chromeos/settings/cros_settings.h" | |
20 #include "chrome/browser/media/webrtc_log_list.h" | 17 #include "chrome/browser/media/webrtc_log_list.h" |
21 #include "chrome/browser/media/webrtc_log_uploader.h" | 18 #include "chrome/browser/media/webrtc_log_uploader.h" |
22 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/common/chrome_switches.h" | |
24 #include "chrome/common/media/webrtc_logging_messages.h" | 20 #include "chrome/common/media/webrtc_logging_messages.h" |
25 #include "chrome/common/partial_circular_buffer.h" | 21 #include "chrome/common/partial_circular_buffer.h" |
26 #include "chrome/common/pref_names.h" | |
27 #include "chromeos/settings/cros_settings_names.h" | |
28 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/content_browser_client.h" | 23 #include "content/public/browser/content_browser_client.h" |
30 #include "content/public/browser/gpu_data_manager.h" | 24 #include "content/public/browser/gpu_data_manager.h" |
31 #include "content/public/browser/render_process_host.h" | 25 #include "content/public/browser/render_process_host.h" |
32 #include "gpu/config/gpu_info.h" | 26 #include "gpu/config/gpu_info.h" |
33 #include "net/base/address_family.h" | 27 #include "net/base/address_family.h" |
34 #include "net/url_request/url_request_context_getter.h" | 28 #include "net/url_request/url_request_context_getter.h" |
35 | 29 |
36 #if defined(OS_LINUX) | 30 #if defined(OS_LINUX) |
37 #include "base/linux_util.h" | 31 #include "base/linux_util.h" |
38 #endif | 32 #endif |
39 | 33 |
40 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
41 #include "base/mac/mac_util.h" | 35 #include "base/mac/mac_util.h" |
42 #endif | 36 #endif |
43 | 37 |
44 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
| 39 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 40 #include "chromeos/settings/cros_settings_names.h" |
45 #include "chromeos/system/statistics_provider.h" | 41 #include "chromeos/system/statistics_provider.h" |
46 #endif | 42 #endif |
47 | 43 |
48 using base::IntToString; | 44 using base::IntToString; |
49 using content::BrowserThread; | 45 using content::BrowserThread; |
50 | 46 |
51 | 47 |
52 #if defined(OS_ANDROID) | 48 #if defined(OS_ANDROID) |
53 const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB | 49 const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB |
54 #else | 50 #else |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 meta_data_ = meta_data; | 127 meta_data_ = meta_data; |
132 } else if (logging_state_ == STARTED) { | 128 } else if (logging_state_ == STARTED) { |
133 meta_data_ = meta_data; | 129 meta_data_ = meta_data; |
134 std::string meta_data_message; | 130 std::string meta_data_message; |
135 FormatMetaDataAsLogMessage(meta_data_, &meta_data_message); | 131 FormatMetaDataAsLogMessage(meta_data_, &meta_data_message); |
136 LogToCircularBuffer(meta_data_message); | 132 LogToCircularBuffer(meta_data_message); |
137 } else { | 133 } else { |
138 error_message = "Meta data must be set before stop or upload."; | 134 error_message = "Meta data must be set before stop or upload."; |
139 } | 135 } |
140 bool success = error_message.empty(); | 136 bool success = error_message.empty(); |
141 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 137 BrowserThread::PostTask(BrowserThread::UI, |
142 base::Bind(callback, success, | 138 FROM_HERE, |
143 error_message)); | 139 base::Bind(callback, success, error_message)); |
144 } | 140 } |
145 | 141 |
146 void WebRtcLoggingHandlerHost::StartLogging( | 142 void WebRtcLoggingHandlerHost::StartLogging( |
147 const GenericDoneCallback& callback) { | 143 const GenericDoneCallback& callback) { |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
149 DCHECK(!callback.is_null()); | 145 DCHECK(!callback.is_null()); |
150 | 146 |
151 start_callback_ = callback; | 147 start_callback_ = callback; |
152 if (logging_state_ != CLOSED) { | 148 if (logging_state_ != CLOSED) { |
153 FireGenericDoneCallback(&start_callback_, false, "A log is already open"); | 149 FireGenericDoneCallback(&start_callback_, false, "A log is already open"); |
(...skipping 17 matching lines...) Expand all Loading... |
171 logging_state_ = STOPPING; | 167 logging_state_ = STOPPING; |
172 Send(new WebRtcLoggingMsg_StopLogging()); | 168 Send(new WebRtcLoggingMsg_StopLogging()); |
173 } | 169 } |
174 | 170 |
175 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) { | 171 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) { |
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
177 DCHECK(!callback.is_null()); | 173 DCHECK(!callback.is_null()); |
178 | 174 |
179 if (logging_state_ != STOPPED) { | 175 if (logging_state_ != STOPPED) { |
180 if (!callback.is_null()) { | 176 if (!callback.is_null()) { |
181 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 177 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
182 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen)); | 178 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen)); |
183 } | 179 } |
184 return; | 180 return; |
185 } | 181 } |
186 upload_callback_ = callback; | 182 upload_callback_ = callback; |
187 logging_state_ = UPLOADING; | 183 logging_state_ = UPLOADING; |
188 content::BrowserThread::PostTaskAndReplyWithResult( | 184 base::PostTaskAndReplyWithResult( |
189 content::BrowserThread::FILE, | 185 BrowserThread::GetBlockingPool(), |
190 FROM_HERE, | 186 FROM_HERE, |
191 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | 187 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, |
192 this), | 188 this), |
193 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); | 189 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); |
194 } | 190 } |
195 | 191 |
196 void WebRtcLoggingHandlerHost::UploadLogDone() { | 192 void WebRtcLoggingHandlerHost::UploadLogDone() { |
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
198 logging_state_ = CLOSED; | 194 logging_state_ = CLOSED; |
199 } | 195 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 const GenericDoneCallback& callback) { | 234 const GenericDoneCallback& callback) { |
239 NOTIMPLEMENTED(); | 235 NOTIMPLEMENTED(); |
240 } | 236 } |
241 | 237 |
242 void WebRtcLoggingHandlerHost::OnChannelClosing() { | 238 void WebRtcLoggingHandlerHost::OnChannelClosing() { |
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
244 if (logging_state_ == STARTED || logging_state_ == STOPPED) { | 240 if (logging_state_ == STARTED || logging_state_ == STOPPED) { |
245 if (upload_log_on_render_close_) { | 241 if (upload_log_on_render_close_) { |
246 logging_state_ = UPLOADING; | 242 logging_state_ = UPLOADING; |
247 logging_started_time_ = base::Time(); | 243 logging_started_time_ = base::Time(); |
248 content::BrowserThread::PostTaskAndReplyWithResult( | 244 base::PostTaskAndReplyWithResult( |
249 content::BrowserThread::FILE, | 245 BrowserThread::GetBlockingPool(), |
250 FROM_HERE, | 246 FROM_HERE, |
251 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | 247 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, |
252 this), | 248 this), |
253 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); | 249 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); |
254 } else { | 250 } else { |
255 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload(); | 251 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload(); |
256 } | 252 } |
257 } | 253 } |
258 content::BrowserMessageFilter::OnChannelClosing(); | 254 BrowserMessageFilter::OnChannelClosing(); |
259 } | 255 } |
260 | 256 |
261 void WebRtcLoggingHandlerHost::OnDestruct() const { | 257 void WebRtcLoggingHandlerHost::OnDestruct() const { |
262 BrowserThread::DeleteOnIOThread::Destruct(this); | 258 BrowserThread::DeleteOnIOThread::Destruct(this); |
263 } | 259 } |
264 | 260 |
265 bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message) { | 261 bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message) { |
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
267 bool handled = true; | 263 bool handled = true; |
268 IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingHandlerHost, message) | 264 IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingHandlerHost, message) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 void WebRtcLoggingHandlerHost::DoStartLogging() { | 319 void WebRtcLoggingHandlerHost::DoStartLogging() { |
324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
325 | 321 |
326 log_buffer_.reset(new unsigned char[kWebRtcLogSize]); | 322 log_buffer_.reset(new unsigned char[kWebRtcLogSize]); |
327 circular_buffer_.reset( | 323 circular_buffer_.reset( |
328 new PartialCircularBuffer(log_buffer_.get(), | 324 new PartialCircularBuffer(log_buffer_.get(), |
329 kWebRtcLogSize, | 325 kWebRtcLogSize, |
330 kWebRtcLogSize / 2, | 326 kWebRtcLogSize / 2, |
331 false)); | 327 false)); |
332 | 328 |
333 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( | 329 BrowserThread::PostBlockingPoolTask( |
334 &WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread, this)); | 330 FROM_HERE, |
| 331 base::Bind(&WebRtcLoggingHandlerHost::LogInitialInfoOnBlockingPool, |
| 332 this)); |
335 } | 333 } |
336 | 334 |
337 void WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread() { | 335 void WebRtcLoggingHandlerHost::LogInitialInfoOnBlockingPool() { |
338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 336 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
339 | 337 |
340 net::NetworkInterfaceList network_list; | 338 net::NetworkInterfaceList network_list; |
341 net::GetNetworkList(&network_list, | 339 net::GetNetworkList(&network_list, |
342 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); | 340 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); |
343 | 341 |
344 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 342 std::string linux_distro; |
345 &WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, this, network_list)); | 343 #if defined(OS_LINUX) |
| 344 linux_distro = base::GetLinuxDistro(); |
| 345 #endif |
| 346 |
| 347 BrowserThread::PostTask( |
| 348 BrowserThread::IO, |
| 349 FROM_HERE, |
| 350 base::Bind(&WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, |
| 351 this, |
| 352 network_list, |
| 353 linux_distro)); |
346 } | 354 } |
347 | 355 |
348 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread( | 356 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread( |
349 const net::NetworkInterfaceList& network_list) { | 357 const net::NetworkInterfaceList& network_list, |
| 358 const std::string& linux_distro) { |
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
351 | 360 |
352 // Log start time (current time). We don't use base/i18n/time_formatting.h | 361 // Log start time (current time). We don't use base/i18n/time_formatting.h |
353 // here because we don't want the format of the current locale. | 362 // here because we don't want the format of the current locale. |
354 base::Time::Exploded now = {0}; | 363 base::Time::Exploded now = {0}; |
355 base::Time::Now().LocalExplode(&now); | 364 base::Time::Now().LocalExplode(&now); |
356 LogToCircularBuffer(base::StringPrintf( | 365 LogToCircularBuffer(base::StringPrintf( |
357 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month, | 366 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month, |
358 now.day_of_month, now.hour, now.minute, now.second)); | 367 now.day_of_month, now.hour, now.minute, now.second)); |
359 | 368 |
360 // Write metadata if received before logging started. | 369 // Write metadata if received before logging started. |
361 if (!meta_data_.empty()) { | 370 if (!meta_data_.empty()) { |
362 std::string info; | 371 std::string info; |
363 FormatMetaDataAsLogMessage(meta_data_, &info); | 372 FormatMetaDataAsLogMessage(meta_data_, &info); |
364 LogToCircularBuffer(info); | 373 LogToCircularBuffer(info); |
365 } | 374 } |
366 | 375 |
367 // OS | 376 // OS |
368 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " + | 377 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " + |
369 base::SysInfo::OperatingSystemVersion() + " " + | 378 base::SysInfo::OperatingSystemVersion() + " " + |
370 base::SysInfo::OperatingSystemArchitecture()); | 379 base::SysInfo::OperatingSystemArchitecture()); |
371 #if defined(OS_LINUX) | 380 #if defined(OS_LINUX) |
372 LogToCircularBuffer("Linux distribution: " + base::GetLinuxDistro()); | 381 LogToCircularBuffer("Linux distribution: " + linux_distro); |
373 #endif | 382 #endif |
374 | 383 |
375 // CPU | 384 // CPU |
376 base::CPU cpu; | 385 base::CPU cpu; |
377 LogToCircularBuffer( | 386 LogToCircularBuffer( |
378 "Cpu: " + IntToString(cpu.family()) + "." + IntToString(cpu.model()) + | 387 "Cpu: " + IntToString(cpu.family()) + "." + IntToString(cpu.model()) + |
379 "." + IntToString(cpu.stepping()) + ", x" + | 388 "." + IntToString(cpu.stepping()) + ", x" + |
380 IntToString(base::SysInfo::NumberOfProcessors()) + ", " + | 389 IntToString(base::SysInfo::NumberOfProcessors()) + ", " + |
381 IntToString(base::SysInfo::AmountOfPhysicalMemoryMB()) + "MB"); | 390 IntToString(base::SysInfo::AmountOfPhysicalMemoryMB()) + "MB"); |
382 std::string cpu_brand = cpu.cpu_brand(); | 391 std::string cpu_brand = cpu.cpu_brand(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 | 442 |
434 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) { | 443 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) { |
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
436 DCHECK(circular_buffer_.get()); | 445 DCHECK(circular_buffer_.get()); |
437 circular_buffer_->Write(message.c_str(), message.length()); | 446 circular_buffer_->Write(message.c_str(), message.length()); |
438 const char eol = '\n'; | 447 const char eol = '\n'; |
439 circular_buffer_->Write(&eol, 1); | 448 circular_buffer_->Write(&eol, 1); |
440 } | 449 } |
441 | 450 |
442 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() { | 451 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() { |
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 452 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
444 base::FilePath log_dir_path = | 453 base::FilePath log_dir_path = |
445 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath()); | 454 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath()); |
446 base::File::Error error; | 455 base::File::Error error; |
447 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) { | 456 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) { |
448 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error; | 457 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error; |
449 return base::FilePath(); | 458 return base::FilePath(); |
450 } | 459 } |
451 return log_dir_path; | 460 return log_dir_path; |
452 } | 461 } |
453 | 462 |
454 void WebRtcLoggingHandlerHost::TriggerUploadLog( | 463 void WebRtcLoggingHandlerHost::TriggerUploadLog( |
455 const base::FilePath& log_directory) { | 464 const base::FilePath& log_directory) { |
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
457 DCHECK_EQ(logging_state_, UPLOADING); | 466 DCHECK_EQ(logging_state_, UPLOADING); |
458 | 467 |
459 WebRtcLogUploadDoneData upload_done_data; | 468 WebRtcLogUploadDoneData upload_done_data; |
460 upload_done_data.log_path = log_directory; | 469 upload_done_data.log_path = log_directory; |
461 upload_done_data.callback = upload_callback_; | 470 upload_done_data.callback = upload_callback_; |
462 upload_done_data.host = this; | 471 upload_done_data.host = this; |
463 upload_callback_.Reset(); | 472 upload_callback_.Reset(); |
464 | 473 |
465 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( | 474 BrowserThread::PostBlockingPoolTask( |
466 &WebRtcLogUploader::LoggingStoppedDoUpload, | 475 FROM_HERE, |
467 base::Unretained(g_browser_process->webrtc_log_uploader()), | 476 base::Bind(&WebRtcLogUploader::LoggingStoppedDoUpload, |
468 Passed(&log_buffer_), | 477 base::Unretained(g_browser_process->webrtc_log_uploader()), |
469 kWebRtcLogSize, | 478 Passed(&log_buffer_), |
470 meta_data_, | 479 kWebRtcLogSize, |
471 upload_done_data)); | 480 meta_data_, |
| 481 upload_done_data)); |
472 | 482 |
473 meta_data_.clear(); | 483 meta_data_.clear(); |
474 circular_buffer_.reset(); | 484 circular_buffer_.reset(); |
475 } | 485 } |
476 | 486 |
477 void WebRtcLoggingHandlerHost::FireGenericDoneCallback( | 487 void WebRtcLoggingHandlerHost::FireGenericDoneCallback( |
478 GenericDoneCallback* callback, bool success, | 488 GenericDoneCallback* callback, bool success, |
479 const std::string& error_message) { | 489 const std::string& error_message) { |
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
481 DCHECK(!(*callback).is_null()); | 491 DCHECK(!callback->is_null()); |
482 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 492 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
483 base::Bind(*callback, success, | 493 base::Bind(*callback, success, error_message)); |
484 error_message)); | 494 callback->Reset(); |
485 (*callback).Reset(); | |
486 } | 495 } |
OLD | NEW |