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.
5 #include "chrome/browser/chromeos/system_logs/debug_daemon_log_source.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"
21 const char kNotAvailable
[] = "<not available>";
22 const char kRoutesKeyName
[] = "routes";
23 const char kNetworkStatusKeyName
[] = "network-status";
24 const char kModemStatusKeyName
[] = "modem-status";
25 const char kWiMaxStatusKeyName
[] = "wimax-status";
26 const char kUserLogFileKeyName
[] = "user_log_files";
28 namespace system_logs
{
30 DebugDaemonLogSource::DebugDaemonLogSource(bool scrub
)
31 : response_(new SystemLogsResponse()),
32 num_pending_requests_(0),
34 weak_ptr_factory_(this) {}
36 DebugDaemonLogSource::~DebugDaemonLogSource() {}
38 void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback
& callback
) {
39 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
40 DCHECK(!callback
.is_null());
41 DCHECK(callback_
.is_null());
44 chromeos::DebugDaemonClient
* client
=
45 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
47 client
->GetRoutes(true, // Numeric
49 base::Bind(&DebugDaemonLogSource::OnGetRoutes
,
50 weak_ptr_factory_
.GetWeakPtr()));
51 ++num_pending_requests_
;
52 client
->GetNetworkStatus(base::Bind(&DebugDaemonLogSource::OnGetNetworkStatus
,
53 weak_ptr_factory_
.GetWeakPtr()));
54 ++num_pending_requests_
;
55 client
->GetModemStatus(base::Bind(&DebugDaemonLogSource::OnGetModemStatus
,
56 weak_ptr_factory_
.GetWeakPtr()));
57 ++num_pending_requests_
;
58 client
->GetWiMaxStatus(base::Bind(&DebugDaemonLogSource::OnGetWiMaxStatus
,
59 weak_ptr_factory_
.GetWeakPtr()));
60 ++num_pending_requests_
;
61 client
->GetUserLogFiles(base::Bind(&DebugDaemonLogSource::OnGetUserLogFiles
,
62 weak_ptr_factory_
.GetWeakPtr()));
63 ++num_pending_requests_
;
66 client
->GetScrubbedLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs
,
67 weak_ptr_factory_
.GetWeakPtr()));
69 client
->GetAllLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs
,
70 weak_ptr_factory_
.GetWeakPtr()));
72 ++num_pending_requests_
;
75 void DebugDaemonLogSource::OnGetRoutes(bool succeeded
,
76 const std::vector
<std::string
>& routes
) {
77 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
80 (*response_
)[kRoutesKeyName
] = JoinString(routes
, '\n');
82 (*response_
)[kRoutesKeyName
] = kNotAvailable
;
86 void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded
,
87 const std::string
& status
) {
88 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
91 (*response_
)[kNetworkStatusKeyName
] = status
;
93 (*response_
)[kNetworkStatusKeyName
] = kNotAvailable
;
97 void DebugDaemonLogSource::OnGetModemStatus(bool succeeded
,
98 const std::string
& status
) {
99 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
102 (*response_
)[kModemStatusKeyName
] = status
;
104 (*response_
)[kModemStatusKeyName
] = kNotAvailable
;
108 void DebugDaemonLogSource::OnGetWiMaxStatus(bool succeeded
,
109 const std::string
& status
) {
110 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
113 (*response_
)[kWiMaxStatusKeyName
] = status
;
115 (*response_
)[kWiMaxStatusKeyName
] = kNotAvailable
;
119 void DebugDaemonLogSource::OnGetLogs(bool /* succeeded */,
120 const KeyValueMap
& logs
) {
121 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
123 // We ignore 'succeeded' for this callback - we want to display as much of the
124 // debug info as we can even if we failed partway through parsing, and if we
125 // couldn't fetch any of it, none of the fields will even appear.
126 response_
->insert(logs
.begin(), logs
.end());
130 void DebugDaemonLogSource::OnGetUserLogFiles(
132 const KeyValueMap
& user_log_files
) {
133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
135 SystemLogsResponse
* response
= new SystemLogsResponse
;
136 std::vector
<Profile
*> last_used
= ProfileManager::GetLastOpenedProfiles();
137 content::BrowserThread::PostBlockingPoolTaskAndReply(
139 base::Bind(&DebugDaemonLogSource::ReadUserLogFiles
,
140 user_log_files
, last_used
, response
),
141 base::Bind(&DebugDaemonLogSource::MergeResponse
,
142 weak_ptr_factory_
.GetWeakPtr(),
143 base::Owned(response
)));
145 (*response_
)[kUserLogFileKeyName
] = kNotAvailable
;
151 void DebugDaemonLogSource::ReadUserLogFiles(
152 const KeyValueMap
& user_log_files
,
153 const std::vector
<Profile
*>& last_used_profiles
,
154 SystemLogsResponse
* response
) {
155 for (size_t i
= 0; i
< last_used_profiles
.size(); ++i
) {
156 std::string profile_prefix
= "Profile[" + base::UintToString(i
) + "] ";
157 for (KeyValueMap::const_iterator it
= user_log_files
.begin();
158 it
!= user_log_files
.end();
160 std::string key
= it
->first
;
162 std::string filename
= it
->second
;
163 base::FilePath profile_dir
= last_used_profiles
[i
]->GetPath();
164 bool read_success
= base::ReadFileToString(
165 profile_dir
.Append(filename
), &value
);
167 if (read_success
&& !value
.empty())
168 (*response
)[profile_prefix
+ key
] = value
;
170 (*response
)[profile_prefix
+ filename
] = kNotAvailable
;
175 void DebugDaemonLogSource::MergeResponse(SystemLogsResponse
* response
) {
176 for (SystemLogsResponse::const_iterator it
= response
->begin();
177 it
!= response
->end(); ++it
)
178 response_
->insert(*it
);
182 void DebugDaemonLogSource::RequestCompleted() {
183 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
184 DCHECK(!callback_
.is_null());
186 --num_pending_requests_
;
187 if (num_pending_requests_
> 0)
189 callback_
.Run(response_
.get());
192 } // namespace system_logs