debug_daemon_log_source.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/system_logs/debug_daemon_log_source.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/file_util.h" 10#include "base/logging.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/memory/weak_ptr.h" 13#include "base/strings/string_number_conversions.h" 14#include "base/strings/string_util.h" 15#include "chrome/browser/profiles/profile_manager.h" 16#include "chrome/common/chrome_switches.h" 17#include "chromeos/dbus/dbus_thread_manager.h" 18#include "chromeos/dbus/debug_daemon_client.h" 19#include "content/public/browser/browser_thread.h" 20 21const char kNotAvailable[] = "<not available>"; 22const char kRoutesKeyName[] = "routes"; 23const char kNetworkStatusKeyName[] = "network-status"; 24const char kModemStatusKeyName[] = "modem-status"; 25const char kWiMaxStatusKeyName[] = "wimax-status"; 26const char kUserLogFileKeyName[] = "user_log_files"; 27 28namespace chromeos { 29 30DebugDaemonLogSource::DebugDaemonLogSource(bool scrub) 31 : response_(new SystemLogsResponse()), 32 num_pending_requests_(0), 33 scrub_(scrub), 34 weak_ptr_factory_(this) {} 35 36DebugDaemonLogSource::~DebugDaemonLogSource() {} 37 38void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback& callback) { 39 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 40 DCHECK(!callback.is_null()); 41 DCHECK(callback_.is_null()); 42 43 callback_ = callback; 44 DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient(); 45 46 client->GetRoutes(true, // Numeric 47 false, // No IPv6 48 base::Bind(&DebugDaemonLogSource::OnGetRoutes, 49 weak_ptr_factory_.GetWeakPtr())); 50 ++num_pending_requests_; 51 client->GetNetworkStatus(base::Bind(&DebugDaemonLogSource::OnGetNetworkStatus, 52 weak_ptr_factory_.GetWeakPtr())); 53 ++num_pending_requests_; 54 client->GetModemStatus(base::Bind(&DebugDaemonLogSource::OnGetModemStatus, 55 weak_ptr_factory_.GetWeakPtr())); 56 ++num_pending_requests_; 57 client->GetWiMaxStatus(base::Bind(&DebugDaemonLogSource::OnGetWiMaxStatus, 58 weak_ptr_factory_.GetWeakPtr())); 59 ++num_pending_requests_; 60 client->GetUserLogFiles(base::Bind(&DebugDaemonLogSource::OnGetUserLogFiles, 61 weak_ptr_factory_.GetWeakPtr())); 62 ++num_pending_requests_; 63 64 if (scrub_) { 65 client->GetScrubbedLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs, 66 weak_ptr_factory_.GetWeakPtr())); 67 } else { 68 client->GetAllLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs, 69 weak_ptr_factory_.GetWeakPtr())); 70 } 71 ++num_pending_requests_; 72} 73 74void DebugDaemonLogSource::OnGetRoutes(bool succeeded, 75 const std::vector<std::string>& routes) { 76 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 77 78 if (succeeded) 79 (*response_)[kRoutesKeyName] = JoinString(routes, '\n'); 80 else 81 (*response_)[kRoutesKeyName] = kNotAvailable; 82 RequestCompleted(); 83} 84 85void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded, 86 const std::string& status) { 87 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 88 89 if (succeeded) 90 (*response_)[kNetworkStatusKeyName] = status; 91 else 92 (*response_)[kNetworkStatusKeyName] = kNotAvailable; 93 RequestCompleted(); 94} 95 96void DebugDaemonLogSource::OnGetModemStatus(bool succeeded, 97 const std::string& status) { 98 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 99 100 if (succeeded) 101 (*response_)[kModemStatusKeyName] = status; 102 else 103 (*response_)[kModemStatusKeyName] = kNotAvailable; 104 RequestCompleted(); 105} 106 107void DebugDaemonLogSource::OnGetWiMaxStatus(bool succeeded, 108 const std::string& status) { 109 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 110 111 if (succeeded) 112 (*response_)[kWiMaxStatusKeyName] = status; 113 else 114 (*response_)[kWiMaxStatusKeyName] = kNotAvailable; 115 RequestCompleted(); 116} 117 118void DebugDaemonLogSource::OnGetLogs(bool /* succeeded */, 119 const KeyValueMap& logs) { 120 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 121 122 // We ignore 'succeeded' for this callback - we want to display as much of the 123 // debug info as we can even if we failed partway through parsing, and if we 124 // couldn't fetch any of it, none of the fields will even appear. 125 response_->insert(logs.begin(), logs.end()); 126 RequestCompleted(); 127} 128 129void DebugDaemonLogSource::OnGetUserLogFiles( 130 bool succeeded, 131 const KeyValueMap& user_log_files) { 132 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 133 if (succeeded) { 134 content::BrowserThread::PostBlockingPoolTaskAndReply( 135 FROM_HERE, 136 base::Bind( 137 &DebugDaemonLogSource::ReadUserLogFiles, 138 weak_ptr_factory_.GetWeakPtr(), 139 user_log_files), 140 base::Bind(&DebugDaemonLogSource::RequestCompleted, 141 weak_ptr_factory_.GetWeakPtr())); 142 } else { 143 (*response_)[kUserLogFileKeyName] = kNotAvailable; 144 RequestCompleted(); 145 } 146} 147 148void DebugDaemonLogSource::ReadUserLogFiles(const KeyValueMap& user_log_files) { 149 std::vector<Profile*> last_used = ProfileManager::GetLastOpenedProfiles(); 150 151 for (size_t i = 0; i < last_used.size(); ++i) { 152 std::string profile_prefix = "Profile[" + base::UintToString(i) + "] "; 153 for (KeyValueMap::const_iterator it = user_log_files.begin(); 154 it != user_log_files.end(); 155 ++it) { 156 std::string key = it->first; 157 std::string value; 158 std::string filename = it->second; 159 base::FilePath profile_dir = last_used[i]->GetPath(); 160 bool read_success = file_util::ReadFileToString( 161 profile_dir.Append(filename), &value); 162 163 if (read_success && !value.empty()) 164 (*response_)[profile_prefix + key] = value; 165 else 166 (*response_)[profile_prefix + filename] = kNotAvailable; 167 } 168 } 169} 170 171void DebugDaemonLogSource::RequestCompleted() { 172 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 173 DCHECK(!callback_.is_null()); 174 175 --num_pending_requests_; 176 if (num_pending_requests_ > 0) 177 return; 178 callback_.Run(response_.get()); 179} 180 181} // namespace chromeos 182