webrtc_logging_handler_host.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/media/webrtc_logging_handler_host.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string>
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/command_line.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/cpu.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/file_util.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_service.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sys_info.h"
1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/time/time.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/media/webrtc_log_list.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/media/webrtc_log_uploader.h"
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/chrome_switches.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/media/webrtc_logging_messages.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/common/partial_circular_buffer.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/pref_names.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/gpu_data_manager.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "gpu/config/gpu_info.h"
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/address_family.h"
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_LINUX)
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/linux_util.h"
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_MACOSX)
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/mac/mac_util.h"
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/system/statistics_provider.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::IntToString;
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using content::BrowserThread;
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_ANDROID)
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const size_t kWebRtcLogSize = 1 * 1024 * 1024;  // 1 MB
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const size_t kWebRtcLogSize = 6 * 1024 * 1024;  // 6 MB
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kLogNotStoppedOrNoLogOpen[] =
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "Logging not stopped or no log open.";
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// For privacy reasons when logging IP addresses. The returned "sensitive
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// string" is for release builds a string with the end stripped away. Last
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// octet for IPv4 and last 80 bits (5 groups) for IPv6. String will be
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// "1.2.3.x" and "1.2.3::" respectively. For debug builds, the string is
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// not stripped.
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string IPAddressToSensitiveString(const net::IPAddressNumber& address) {
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(NDEBUG)
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string sensitive_address;
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (net::GetAddressFamily(address)) {
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case net::ADDRESS_FAMILY_IPV4: {
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sensitive_address = net::IPAddressToString(address);
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      size_t find_pos = sensitive_address.rfind('.');
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (find_pos == std::string::npos)
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return std::string();
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sensitive_address.resize(find_pos);
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sensitive_address += ".x";
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case net::ADDRESS_FAMILY_IPV6: {
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // TODO(grunell): Create a string of format "1:2:3:x:x:x:x:x" to clarify
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // that the end has been stripped out.
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      net::IPAddressNumber sensitive_address_number = address;
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sensitive_address_number.resize(net::kIPv6AddressSize - 10);
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sensitive_address_number.resize(net::kIPv6AddressSize, 0);
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sensitive_address = net::IPAddressToString(sensitive_address_number);
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case net::ADDRESS_FAMILY_UNSPECIFIED: {
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sensitive_address;
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return net::IPAddressToString(address);
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FormatMetaDataAsLogMessage(
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const MetaDataMap& meta_data,
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string* message) {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (MetaDataMap::const_iterator it = meta_data.begin();
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != meta_data.end(); ++it) {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *message += it->first + ": " + it->second + '\n';
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Remove last '\n'.
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message->resize(message->size() - 1);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost(Profile* profile)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BrowserMessageFilter(WebRtcLoggingMsgStart),
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_(profile),
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      logging_state_(CLOSED),
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      upload_log_on_render_close_(false) {
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(profile_);
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {}
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::SetMetaData(
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const MetaDataMap& meta_data,
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GenericDoneCallback& callback) {
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string error_message;
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (logging_state_ == CLOSED) {
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    meta_data_ = meta_data;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (logging_state_ == STARTED) {
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    meta_data_ = meta_data;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string meta_data_message;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FormatMetaDataAsLogMessage(meta_data_, &meta_data_message);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LogToCircularBuffer(meta_data_message);
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error_message = "Meta data must be set before stop or upload.";
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool success = error_message.empty();
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   base::Bind(callback, success,
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              error_message));
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::StartLogging(
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GenericDoneCallback& callback) {
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  start_callback_ = callback;
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (logging_state_ != CLOSED) {
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FireGenericDoneCallback(&start_callback_, false, "A log is already open");
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = STARTING;
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      &WebRtcLoggingHandlerHost::StartLoggingIfAllowed, this));
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::StopLogging(
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GenericDoneCallback& callback) {
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  stop_callback_ = callback;
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (logging_state_ != STARTED) {
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FireGenericDoneCallback(&stop_callback_, false, "Logging not started");
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = STOPPING;
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Send(new WebRtcLoggingMsg_StopLogging());
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) {
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (logging_state_ != STOPPED) {
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!callback.is_null()) {
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen));
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  upload_callback_ = callback;
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  content::BrowserThread::PostTaskAndReplyWithResult(
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      content::BrowserThread::FILE,
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      FROM_HERE,
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 this),
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this));
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::UploadLogDone() {
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = CLOSED;
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::DiscardLog(const GenericDoneCallback& callback) {
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GenericDoneCallback discard_callback = callback;
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (logging_state_ != STOPPED) {
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FireGenericDoneCallback(&discard_callback, false,
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            kLogNotStoppedOrNoLogOpen);
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload();
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  circular_buffer_.reset();
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  log_buffer_.reset();
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = CLOSED;
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FireGenericDoneCallback(&discard_callback, true, "");
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcLoggingHandlerHost::LogMessage(const std::string& message) {
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserThread::PostTask(
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BrowserThread::IO,
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          &WebRtcLoggingHandlerHost::AddLogMessageFromBrowser,
223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          this,
224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          WebRtcLoggingMessageData(base::Time::Now(), message)));
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void WebRtcLoggingHandlerHost::OnChannelClosing() {
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (logging_state_ == STARTED || logging_state_ == STOPPED) {
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (upload_log_on_render_close_) {
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      logging_state_ = STOPPED;
232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      logging_started_time_ = base::Time();
233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      content::BrowserThread::PostTaskAndReplyWithResult(
234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          content::BrowserThread::FILE,
235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          FROM_HERE,
236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists,
237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     this),
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this));
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload();
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::BrowserMessageFilter::OnChannelClosing();
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void WebRtcLoggingHandlerHost::OnDestruct() const {
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BrowserThread::DeleteOnIOThread::Destruct(this);
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message,
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                 bool* message_was_ok) {
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool handled = true;
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(WebRtcLoggingHandlerHost, message, *message_was_ok)
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_AddLogMessages, OnAddLogMessages)
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_LoggingStopped,
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        OnLoggingStoppedInRenderer)
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  IPC_END_MESSAGE_MAP_EX()
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return handled;
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcLoggingHandlerHost::AddLogMessageFromBrowser(
265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const WebRtcLoggingMessageData& message) {
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (logging_state_ == STARTED)
268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    LogToCircularBuffer(message.Format(logging_started_time_));
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid WebRtcLoggingHandlerHost::OnAddLogMessages(
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const std::vector<WebRtcLoggingMessageData>& messages) {
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (logging_state_ == STARTED || logging_state_ == STOPPING) {
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    for (size_t i = 0; i < messages.size(); ++i) {
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      LogToCircularBuffer(messages[i].Format(logging_started_time_));
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::OnLoggingStoppedInRenderer() {
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (logging_state_ != STOPPING) {
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // If an out-of-order response is received, stop_callback_ may be invalid,
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // and must not be invoked.
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DLOG(ERROR) << "OnLoggingStoppedInRenderer invoked in state "
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                << logging_state_;
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BadMessageReceived();
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  logging_started_time_ = base::Time();
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = STOPPED;
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FireGenericDoneCallback(&stop_callback_, true, "");
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::StartLoggingIfAllowed() {
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!g_browser_process->webrtc_log_uploader()->ApplyForStartLogging()) {
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    logging_state_ = CLOSED;
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      FireGenericDoneCallback(
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          &start_callback_, false, "Cannot start, maybe the maximum number of "
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "simultaneuos logs has been reached.");
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      &WebRtcLoggingHandlerHost::DoStartLogging, this));
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::DoStartLogging() {
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  log_buffer_.reset(new unsigned char[kWebRtcLogSize]);
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  circular_buffer_.reset(
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    new PartialCircularBuffer(log_buffer_.get(),
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kWebRtcLogSize,
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kWebRtcLogSize / 2,
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              false));
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      &WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread, this));
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
32323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread() {
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::NetworkInterfaceList network_list;
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::GetNetworkList(&network_list,
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
33123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      &WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, this, network_list));
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread(
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const net::NetworkInterfaceList& network_list) {
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Log start time (current time). We don't use base/i18n/time_formatting.h
33923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // here because we don't want the format of the current locale.
34023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::Time::Exploded now = {0};
34123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::Time::Now().LocalExplode(&now);
34223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  LogToCircularBuffer(base::StringPrintf(
34323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month,
34423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      now.day_of_month, now.hour, now.minute, now.second));
34523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Write metadata if received before logging started.
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!meta_data_.empty()) {
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string info;
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FormatMetaDataAsLogMessage(meta_data_, &info);
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LogToCircularBuffer(info);
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // OS
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " +
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      base::SysInfo::OperatingSystemVersion() + " " +
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      base::SysInfo::OperatingSystemArchitecture());
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_LINUX)
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer("Linux distribution: " + base::GetLinuxDistro());
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // CPU
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::CPU cpu;
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer(
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "Cpu: " + IntToString(cpu.family()) + "." + IntToString(cpu.model()) +
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "." + IntToString(cpu.stepping()) + ", x" +
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      IntToString(base::SysInfo::NumberOfProcessors()) + ", " +
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      IntToString(base::SysInfo::AmountOfPhysicalMemoryMB()) + "MB");
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string cpu_brand = cpu.cpu_brand();
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Workaround for crbug.com/249713.
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(grunell): Remove workaround when bug is fixed.
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t null_pos = cpu_brand.find('\0');
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (null_pos != std::string::npos)
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    cpu_brand.erase(null_pos);
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer("Cpu brand: " + cpu_brand);
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Computer model
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string computer_model = "Not available";
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_MACOSX)
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  computer_model = base::mac::GetModelIdentifier();
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_CHROMEOS)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chromeos::system::StatisticsProvider::GetInstance()->
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetMachineStatistic(chromeos::system::kHardwareClassKey, &computer_model);
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer("Computer model: " + computer_model);
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // GPU
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer("Gpu: machine-model='" + gpu_info.machine_model +
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      "', vendor-id=" + IntToString(gpu_info.gpu.vendor_id) +
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      ", device-id=" + IntToString(gpu_info.gpu.device_id) +
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      ", driver-vendor='" + gpu_info.driver_vendor +
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      "', driver-version=" + gpu_info.driver_version);
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Network interfaces
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LogToCircularBuffer("Discovered " + IntToString(network_list.size()) +
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      " network interfaces:");
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (net::NetworkInterfaceList::const_iterator it = network_list.begin();
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       it != network_list.end(); ++it) {
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LogToCircularBuffer("Name: " + it->friendly_name + ", Address: " +
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        IPAddressToSensitiveString(it->address));
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NotifyLoggingStarted();
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::NotifyLoggingStarted() {
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new WebRtcLoggingMsg_StartLogging());
409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  logging_started_time_ = base::Time::Now();
4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = STARTED;
4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FireGenericDoneCallback(&start_callback_, true, "");
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(circular_buffer_.get());
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  circular_buffer_->Write(message.c_str(), message.length());
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char eol = '\n';
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  circular_buffer_->Write(&eol, 1);
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
422effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbase::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() {
423effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
424effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::FilePath log_dir_path =
425effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath());
426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::File::Error error;
427effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) {
428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error;
429effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return base::FilePath();
430effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
431effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return log_dir_path;
432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
433effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
434effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid WebRtcLoggingHandlerHost::TriggerUploadLog(
435effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const base::FilePath& log_directory) {
4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(logging_state_ == STOPPED);
4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  logging_state_ = UPLOADING;
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebRtcLogUploadDoneData upload_done_data;
441effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
442effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  upload_done_data.log_path = log_directory;
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  upload_done_data.callback = upload_callback_;
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  upload_done_data.host = this;
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  upload_callback_.Reset();
446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      &WebRtcLogUploader::LoggingStoppedDoUpload,
449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Unretained(g_browser_process->webrtc_log_uploader()),
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Passed(&log_buffer_),
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kWebRtcLogSize,
4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      meta_data_,
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      upload_done_data));
4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  meta_data_.clear();
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  circular_buffer_.reset();
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRtcLoggingHandlerHost::FireGenericDoneCallback(
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GenericDoneCallback* callback, bool success,
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& error_message) {
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!(*callback).is_null());
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   base::Bind(*callback, success,
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              error_message));
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  (*callback).Reset();
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
469