Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / system_logs / debug_daemon_log_source.cc
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/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"
22
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";
29
30 namespace system_logs {
31
32 DebugDaemonLogSource::DebugDaemonLogSource(bool scrub)
33     : response_(new SystemLogsResponse()),
34       num_pending_requests_(0),
35       scrub_(scrub),
36       weak_ptr_factory_(this) {}
37
38 DebugDaemonLogSource::~DebugDaemonLogSource() {}
39
40 void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback& callback) {
41   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
42   DCHECK(!callback.is_null());
43   DCHECK(callback_.is_null());
44
45   callback_ = callback;
46   chromeos::DebugDaemonClient* client =
47       chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
48
49   client->GetRoutes(true,   // Numeric
50                     false,  // No IPv6
51                     base::Bind(&DebugDaemonLogSource::OnGetRoutes,
52                                weak_ptr_factory_.GetWeakPtr()));
53   ++num_pending_requests_;
54   client->GetNetworkStatus(base::Bind(&DebugDaemonLogSource::OnGetNetworkStatus,
55                                       weak_ptr_factory_.GetWeakPtr()));
56   ++num_pending_requests_;
57   client->GetModemStatus(base::Bind(&DebugDaemonLogSource::OnGetModemStatus,
58                                     weak_ptr_factory_.GetWeakPtr()));
59   ++num_pending_requests_;
60   client->GetWiMaxStatus(base::Bind(&DebugDaemonLogSource::OnGetWiMaxStatus,
61                                     weak_ptr_factory_.GetWeakPtr()));
62   ++num_pending_requests_;
63   client->GetUserLogFiles(base::Bind(&DebugDaemonLogSource::OnGetUserLogFiles,
64                                      weak_ptr_factory_.GetWeakPtr()));
65   ++num_pending_requests_;
66
67   if (scrub_) {
68     client->GetScrubbedLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs,
69                                        weak_ptr_factory_.GetWeakPtr()));
70   } else {
71     client->GetAllLogs(base::Bind(&DebugDaemonLogSource::OnGetLogs,
72                                   weak_ptr_factory_.GetWeakPtr()));
73   }
74   ++num_pending_requests_;
75 }
76
77 void DebugDaemonLogSource::OnGetRoutes(bool succeeded,
78                                        const std::vector<std::string>& routes) {
79   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
80
81   if (succeeded)
82     (*response_)[kRoutesKeyName] = JoinString(routes, '\n');
83   else
84     (*response_)[kRoutesKeyName] = kNotAvailable;
85   RequestCompleted();
86 }
87
88 void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded,
89                                               const std::string& status) {
90   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
91
92   if (succeeded)
93     (*response_)[kNetworkStatusKeyName] = status;
94   else
95     (*response_)[kNetworkStatusKeyName] = kNotAvailable;
96   RequestCompleted();
97 }
98
99 void DebugDaemonLogSource::OnGetModemStatus(bool succeeded,
100                                             const std::string& status) {
101   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
102
103   if (succeeded)
104     (*response_)[kModemStatusKeyName] = status;
105   else
106     (*response_)[kModemStatusKeyName] = kNotAvailable;
107   RequestCompleted();
108 }
109
110 void DebugDaemonLogSource::OnGetWiMaxStatus(bool succeeded,
111                                             const std::string& status) {
112   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
113
114   if (succeeded)
115     (*response_)[kWiMaxStatusKeyName] = status;
116   else
117     (*response_)[kWiMaxStatusKeyName] = kNotAvailable;
118   RequestCompleted();
119 }
120
121 void DebugDaemonLogSource::OnGetLogs(bool /* succeeded */,
122                                      const KeyValueMap& logs) {
123   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
124
125   // We ignore 'succeeded' for this callback - we want to display as much of the
126   // debug info as we can even if we failed partway through parsing, and if we
127   // couldn't fetch any of it, none of the fields will even appear.
128   response_->insert(logs.begin(), logs.end());
129   RequestCompleted();
130 }
131
132 void DebugDaemonLogSource::OnGetUserLogFiles(
133     bool succeeded,
134     const KeyValueMap& user_log_files) {
135   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
136   if (succeeded) {
137     SystemLogsResponse* response = new SystemLogsResponse;
138
139     const user_manager::UserList& users =
140         user_manager::UserManager::Get()->GetLoggedInUsers();
141     std::vector<base::FilePath> profile_dirs;
142     for (user_manager::UserList::const_iterator it = users.begin();
143          it != users.end();
144          ++it) {
145       if ((*it)->username_hash().empty())
146         continue;
147       profile_dirs.push_back(
148           chromeos::ProfileHelper::GetProfilePathByUserIdHash(
149               (*it)->username_hash()));
150     }
151
152     content::BrowserThread::PostBlockingPoolTaskAndReply(
153         FROM_HERE,
154         base::Bind(&DebugDaemonLogSource::ReadUserLogFiles,
155                    user_log_files, profile_dirs, response),
156         base::Bind(&DebugDaemonLogSource::MergeResponse,
157                    weak_ptr_factory_.GetWeakPtr(),
158                    base::Owned(response)));
159   } else {
160     (*response_)[kUserLogFileKeyName] = kNotAvailable;
161     RequestCompleted();
162   }
163 }
164
165 // static
166 void DebugDaemonLogSource::ReadUserLogFiles(
167     const KeyValueMap& user_log_files,
168     const std::vector<base::FilePath>& profile_dirs,
169     SystemLogsResponse* response) {
170   for (size_t i = 0; i < profile_dirs.size(); ++i) {
171     std::string profile_prefix = "Profile[" + base::UintToString(i) + "] ";
172     for (KeyValueMap::const_iterator it = user_log_files.begin();
173          it != user_log_files.end();
174          ++it) {
175       std::string key = it->first;
176       std::string value;
177       std::string filename = it->second;
178       bool read_success = base::ReadFileToString(
179           profile_dirs[i].Append(filename), &value);
180
181       if (read_success && !value.empty())
182         (*response)[profile_prefix + key] = value;
183       else
184         (*response)[profile_prefix + filename] = kNotAvailable;
185     }
186   }
187 }
188
189 void DebugDaemonLogSource::MergeResponse(SystemLogsResponse* response) {
190   for (SystemLogsResponse::const_iterator it = response->begin();
191        it != response->end(); ++it)
192     response_->insert(*it);
193   RequestCompleted();
194 }
195
196 void DebugDaemonLogSource::RequestCompleted() {
197   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
198   DCHECK(!callback_.is_null());
199
200   --num_pending_requests_;
201   if (num_pending_requests_ > 0)
202     return;
203   callback_.Run(response_.get());
204 }
205
206 }  // namespace system_logs