debug_daemon_log_source.cc revision 58537e28ecd584eab876aee8be7156509866d23a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/system_logs/debug_daemon_log_source.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/debug_daemon_client.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNotAvailable[] = "<not available>";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRoutesKeyName[] = "routes";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNetworkStatusKeyName[] = "network-status";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kModemStatusKeyName[] = "modem-status";
2558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochconst char kWiMaxStatusKeyName[] = "wimax-status";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserLogFileKeyName[] = "user_log_files";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochDebugDaemonLogSource::DebugDaemonLogSource(bool scrub)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : response_(new SystemLogsResponse()),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_pending_requests_(0),
33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      scrub_(scrub),
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonLogSource::~DebugDaemonLogSource() {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback& callback) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetRoutes(true,   // Numeric
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    false,  // No IPv6
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&DebugDaemonLogSource::OnGetRoutes,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               weak_ptr_factory_.GetWeakPtr()));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetNetworkStatus(base::Bind(&DebugDaemonLogSource::OnGetNetworkStatus,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      weak_ptr_factory_.GetWeakPtr()));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetModemStatus(base::Bind(&DebugDaemonLogSource::OnGetModemStatus,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    weak_ptr_factory_.GetWeakPtr()));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
5758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  client->GetWiMaxStatus(base::Bind(&DebugDaemonLogSource::OnGetWiMaxStatus,
5858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                                    weak_ptr_factory_.GetWeakPtr()));
5958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  ++num_pending_requests_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetUserLogFiles(base::Bind(&DebugDaemonLogSource::OnGetUserLogFiles,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     weak_ptr_factory_.GetWeakPtr()));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (scrub_) {
65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    client->GetScrubbedLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs,
66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                       weak_ptr_factory_.GetWeakPtr()));
67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    client->GetAllLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs,
69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                  weak_ptr_factory_.GetWeakPtr()));
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ++num_pending_requests_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetRoutes(bool succeeded,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const std::vector<std::string>& routes) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kRoutesKeyName] = JoinString(routes, '\n');
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kRoutesKeyName] = kNotAvailable;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const std::string& status) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kNetworkStatusKeyName] = status;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kNetworkStatusKeyName] = kNotAvailable;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetModemStatus(bool succeeded,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const std::string& status) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kModemStatusKeyName] = status;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kModemStatusKeyName] = kNotAvailable;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochvoid DebugDaemonLogSource::OnGetWiMaxStatus(bool succeeded,
10858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                                            const std::string& status) {
10958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
11058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
11158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  if (succeeded)
11258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    (*response_)[kWiMaxStatusKeyName] = status;
11358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  else
11458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    (*response_)[kWiMaxStatusKeyName] = kNotAvailable;
11558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  RequestCompleted();
11658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}
11758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetLogs(bool /* succeeded */,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const KeyValueMap& logs) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We ignore 'succeeded' for this callback - we want to display as much of the
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // debug info as we can even if we failed partway through parsing, and if we
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // couldn't fetch any of it, none of the fields will even appear.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_->insert(logs.begin(), logs.end());
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetUserLogFiles(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool succeeded,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const KeyValueMap& user_log_files) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded) {
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SystemLogsResponse* response = new SystemLogsResponse;
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::vector<Profile*> last_used = ProfileManager::GetLastOpenedProfiles();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::BrowserThread::PostBlockingPoolTaskAndReply(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&DebugDaemonLogSource::ReadUserLogFiles,
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   user_log_files, last_used, response),
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&DebugDaemonLogSource::MergeResponse,
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   base::Owned(response)));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kUserLogFileKeyName] = kNotAvailable;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// static
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DebugDaemonLogSource::ReadUserLogFiles(
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const KeyValueMap& user_log_files,
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::vector<Profile*>& last_used_profiles,
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SystemLogsResponse* response) {
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < last_used_profiles.size(); ++i) {
155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    std::string profile_prefix = "Profile[" + base::UintToString(i) + "] ";
156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for (KeyValueMap::const_iterator it = user_log_files.begin();
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)         it != user_log_files.end();
158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)         ++it) {
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      std::string key = it->first;
160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      std::string value;
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      std::string filename = it->second;
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::FilePath profile_dir = last_used_profiles[i]->GetPath();
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      bool read_success = base::ReadFileToString(
164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          profile_dir.Append(filename), &value);
165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      if (read_success && !value.empty())
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        (*response)[profile_prefix + key] = value;
168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      else
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        (*response)[profile_prefix + filename] = kNotAvailable;
170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DebugDaemonLogSource::MergeResponse(SystemLogsResponse* response) {
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (SystemLogsResponse::const_iterator it = response->begin();
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       it != response->end(); ++it)
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    response_->insert(*it);
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestCompleted();
1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::RequestCompleted() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback_.is_null());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --num_pending_requests_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_pending_requests_ > 0)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Run(response_.get());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
192