debug_daemon_log_source.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/system_logs/system_logs_fetcher.h"
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/debug_daemon_client.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNotAvailable[] = "<not available>";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRoutesKeyName[] = "routes";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNetworkStatusKeyName[] = "network-status";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kModemStatusKeyName[] = "modem-status";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserLogFileKeyName[] = "user_log_files";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonLogSource::DebugDaemonLogSource()
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : response_(new SystemLogsResponse()),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_pending_requests_(0),
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonLogSource::~DebugDaemonLogSource() {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback& callback) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetRoutes(true,   // Numeric
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    false,  // No IPv6
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&DebugDaemonLogSource::OnGetRoutes,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               weak_ptr_factory_.GetWeakPtr()));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetNetworkStatus(base::Bind(&DebugDaemonLogSource::OnGetNetworkStatus,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      weak_ptr_factory_.GetWeakPtr()));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetModemStatus(base::Bind(&DebugDaemonLogSource::OnGetModemStatus,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    weak_ptr_factory_.GetWeakPtr()));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetAllLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                weak_ptr_factory_.GetWeakPtr()));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->GetUserLogFiles(base::Bind(&DebugDaemonLogSource::OnGetUserLogFiles,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     weak_ptr_factory_.GetWeakPtr()));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_pending_requests_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetRoutes(bool succeeded,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const std::vector<std::string>& routes) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kRoutesKeyName] = JoinString(routes, '\n');
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kRoutesKeyName] = kNotAvailable;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const std::string& status) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kNetworkStatusKeyName] = status;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kNetworkStatusKeyName] = kNotAvailable;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetModemStatus(bool succeeded,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const std::string& status) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kModemStatusKeyName] = status;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kModemStatusKeyName] = kNotAvailable;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetLogs(bool /* succeeded */,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const KeyValueMap& logs) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We ignore 'succeeded' for this callback - we want to display as much of the
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // debug info as we can even if we failed partway through parsing, and if we
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // couldn't fetch any of it, none of the fields will even appear.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_->insert(logs.begin(), logs.end());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestCompleted();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::OnGetUserLogFiles(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool succeeded,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const KeyValueMap& user_log_files) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (succeeded) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::BrowserThread::PostBlockingPoolTaskAndReply(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &DebugDaemonLogSource::ReadUserLogFiles,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            user_log_files),
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonLogSource::RequestCompleted,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*response_)[kUserLogFileKeyName] = kNotAvailable;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::ReadUserLogFiles(const KeyValueMap& user_log_files) {
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<Profile*> last_used = ProfileManager::GetLastOpenedProfiles();
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  for (size_t i = 0; i < last_used.size(); ++i) {
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    std::string profile_prefix = "Profile[" + base::UintToString(i) + "] ";
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for (KeyValueMap::const_iterator it = user_log_files.begin();
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)         it != user_log_files.end();
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)         ++it) {
135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      std::string key = it->first;
136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      std::string value;
137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      std::string filename = it->second;
138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath profile_dir = last_used[i]->GetPath();
139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      bool read_success = file_util::ReadFileToString(
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          profile_dir.Append(filename), &value);
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      if (read_success && !value.empty())
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        (*response_)[profile_prefix + key] = value;
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      else
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        (*response_)[profile_prefix + filename] = kNotAvailable;
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DebugDaemonLogSource::RequestCompleted() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback_.is_null());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --num_pending_requests_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_pending_requests_ > 0)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Run(response_.get());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
161