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/files/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/chromeos/profiles/profile_helper.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 "components/user_manager/user.h"
20 #include "components/user_manager/user_manager.h"
21 #include "content/public/browser/browser_thread.h"
23 const char kNotAvailable
[] = "<not available>";
24 const char kRoutesKeyName
[] = "routes";
25 const char kNetworkStatusKeyName
[] = "network-status";
26 const char kModemStatusKeyName
[] = "modem-status";
27 const char kWiMaxStatusKeyName
[] = "wimax-status";
28 const char kUserLogFileKeyName
[] = "user_log_files";
30 namespace system_logs
{
32 DebugDaemonLogSource::DebugDaemonLogSource(bool scrub
)
33 : SystemLogsSource("DebugDemon"),
34 response_(new SystemLogsResponse()),
35 num_pending_requests_(0),
37 weak_ptr_factory_(this) {}
39 DebugDaemonLogSource::~DebugDaemonLogSource() {}
41 void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback
& callback
) {
42 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
43 DCHECK(!callback
.is_null());
44 DCHECK(callback_
.is_null());
47 chromeos::DebugDaemonClient
* client
=
48 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
50 client
->GetRoutes(true, // Numeric
52 base::Bind(&DebugDaemonLogSource::OnGetRoutes
,
53 weak_ptr_factory_
.GetWeakPtr()));
54 ++num_pending_requests_
;
55 client
->GetNetworkStatus(base::Bind(&DebugDaemonLogSource::OnGetNetworkStatus
,
56 weak_ptr_factory_
.GetWeakPtr()));
57 ++num_pending_requests_
;
58 client
->GetModemStatus(base::Bind(&DebugDaemonLogSource::OnGetModemStatus
,
59 weak_ptr_factory_
.GetWeakPtr()));
60 ++num_pending_requests_
;
61 client
->GetWiMaxStatus(base::Bind(&DebugDaemonLogSource::OnGetWiMaxStatus
,
62 weak_ptr_factory_
.GetWeakPtr()));
63 ++num_pending_requests_
;
64 client
->GetUserLogFiles(base::Bind(&DebugDaemonLogSource::OnGetUserLogFiles
,
65 weak_ptr_factory_
.GetWeakPtr()));
66 ++num_pending_requests_
;
69 client
->GetScrubbedLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs
,
70 weak_ptr_factory_
.GetWeakPtr()));
72 client
->GetAllLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs
,
73 weak_ptr_factory_
.GetWeakPtr()));
75 ++num_pending_requests_
;
78 void DebugDaemonLogSource::OnGetRoutes(bool succeeded
,
79 const std::vector
<std::string
>& routes
) {
80 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
83 (*response_
)[kRoutesKeyName
] = base::JoinString(routes
, "\n");
85 (*response_
)[kRoutesKeyName
] = kNotAvailable
;
89 void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded
,
90 const std::string
& status
) {
91 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
94 (*response_
)[kNetworkStatusKeyName
] = status
;
96 (*response_
)[kNetworkStatusKeyName
] = kNotAvailable
;
100 void DebugDaemonLogSource::OnGetModemStatus(bool succeeded
,
101 const std::string
& status
) {
102 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
105 (*response_
)[kModemStatusKeyName
] = status
;
107 (*response_
)[kModemStatusKeyName
] = kNotAvailable
;
111 void DebugDaemonLogSource::OnGetWiMaxStatus(bool succeeded
,
112 const std::string
& status
) {
113 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
115 (*response_
)[kWiMaxStatusKeyName
] = succeeded
? status
: kNotAvailable
;
119 void DebugDaemonLogSource::OnGetLogs(bool /* succeeded */,
120 const KeyValueMap
& logs
) {
121 DCHECK_CURRENTLY_ON(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_CURRENTLY_ON(content::BrowserThread::UI
);
135 SystemLogsResponse
* response
= new SystemLogsResponse
;
137 const user_manager::UserList
& users
=
138 user_manager::UserManager::Get()->GetLoggedInUsers();
139 std::vector
<base::FilePath
> profile_dirs
;
140 for (user_manager::UserList::const_iterator it
= users
.begin();
143 if ((*it
)->username_hash().empty())
145 profile_dirs
.push_back(
146 chromeos::ProfileHelper::GetProfilePathByUserIdHash(
147 (*it
)->username_hash()));
150 content::BrowserThread::PostBlockingPoolTaskAndReply(
152 base::Bind(&DebugDaemonLogSource::ReadUserLogFiles
,
153 user_log_files
, profile_dirs
, response
),
154 base::Bind(&DebugDaemonLogSource::MergeResponse
,
155 weak_ptr_factory_
.GetWeakPtr(),
156 base::Owned(response
)));
158 (*response_
)[kUserLogFileKeyName
] = kNotAvailable
;
164 void DebugDaemonLogSource::ReadUserLogFiles(
165 const KeyValueMap
& user_log_files
,
166 const std::vector
<base::FilePath
>& profile_dirs
,
167 SystemLogsResponse
* response
) {
168 for (size_t i
= 0; i
< profile_dirs
.size(); ++i
) {
169 std::string profile_prefix
= "Profile[" + base::UintToString(i
) + "] ";
170 for (KeyValueMap::const_iterator it
= user_log_files
.begin();
171 it
!= user_log_files
.end();
173 std::string key
= it
->first
;
175 std::string filename
= it
->second
;
176 bool read_success
= base::ReadFileToString(
177 profile_dirs
[i
].Append(filename
), &value
);
179 if (read_success
&& !value
.empty())
180 (*response
)[profile_prefix
+ key
] = value
;
182 (*response
)[profile_prefix
+ filename
] = kNotAvailable
;
187 void DebugDaemonLogSource::MergeResponse(SystemLogsResponse
* response
) {
188 for (SystemLogsResponse::const_iterator it
= response
->begin();
189 it
!= response
->end(); ++it
)
190 response_
->insert(*it
);
194 void DebugDaemonLogSource::RequestCompleted() {
195 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
196 DCHECK(!callback_
.is_null());
198 --num_pending_requests_
;
199 if (num_pending_requests_
> 0)
201 callback_
.Run(response_
.get());
204 } // namespace system_logs