Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / log_private / log_private_api_chromeos.cc
1 // Copyright 2013 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/extensions/api/log_private/log_private_api.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/json/json_writer.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/extensions/api/log_private/filter_handler.h"
18 #include "chrome/browser/extensions/api/log_private/log_parser.h"
19 #include "chrome/browser/extensions/api/log_private/syslog_parser.h"
20 #include "chrome/browser/feedback/system_logs/scrubbed_system_logs_fetcher.h"
21 #include "chrome/browser/io_thread.h"
22 #include "chrome/browser/net/chrome_net_log.h"
23 #include "chrome/common/extensions/api/log_private.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h"
26 #include "extensions/browser/event_router.h"
27 #include "extensions/browser/extension_function.h"
28 #include "extensions/browser/extension_system.h"
29
30 using content::BrowserThread;
31
32 namespace events {
33 const char kOnAddNetInternalsEntries[] = "logPrivate.onAddNetInternalsEntries";
34 }  // namespace events
35
36 namespace extensions {
37 namespace {
38
39 const int kNetLogEventDelayMilliseconds = 100;
40
41 scoped_ptr<LogParser> CreateLogParser(const std::string& log_type) {
42   if (log_type == "syslog")
43     return scoped_ptr<LogParser>(new SyslogParser());
44   // TODO(shinfan): Add more parser here
45
46   NOTREACHED() << "Invalid log type: " << log_type;
47   return  scoped_ptr<LogParser>();
48 }
49
50 void CollectLogInfo(
51     FilterHandler* filter_handler,
52     system_logs::SystemLogsResponse* logs,
53     std::vector<linked_ptr<api::log_private::LogEntry> >* output) {
54   for (system_logs::SystemLogsResponse::const_iterator
55       request_it = logs->begin(); request_it != logs->end(); ++request_it) {
56     if (!filter_handler->IsValidSource(request_it->first)) {
57       continue;
58     }
59     scoped_ptr<LogParser> parser(CreateLogParser(request_it->first));
60     if (parser) {
61       parser->Parse(request_it->second, output, filter_handler);
62     }
63   }
64 }
65
66 }  // namespace
67
68 // static
69 LogPrivateAPI* LogPrivateAPI::Get(Profile* profile) {
70   return GetFactoryInstance()->GetForProfile(profile);
71 }
72
73 LogPrivateAPI::LogPrivateAPI(Profile* profile)
74   : profile_(profile), logging_net_internals_(false) {
75   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
76                  content::Source<Profile>(profile));
77 }
78
79 LogPrivateAPI::~LogPrivateAPI() {
80 }
81
82 void LogPrivateAPI::StartNetInternalsWatch(const std::string& extension_id) {
83   net_internal_watches_.insert(extension_id);
84   BrowserThread::PostTask(
85       BrowserThread::IO, FROM_HERE,
86       base::Bind(&LogPrivateAPI::MaybeStartNetInternalLogging,
87                  base::Unretained(this)));
88 }
89
90 void LogPrivateAPI::StopNetInternalsWatch(const std::string& extension_id) {
91   net_internal_watches_.erase(extension_id);
92   MaybeStopNetInternalLogging();
93 }
94
95 static base::LazyInstance<ProfileKeyedAPIFactory<LogPrivateAPI> >
96     g_factory = LAZY_INSTANCE_INITIALIZER;
97
98 // static
99 ProfileKeyedAPIFactory<LogPrivateAPI>*
100 LogPrivateAPI::GetFactoryInstance() {
101   return &g_factory.Get();
102 }
103
104 void LogPrivateAPI::OnAddEntry(const net::NetLog::Entry& entry) {
105   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
106   if (!pending_entries_.get()) {
107     pending_entries_.reset(new base::ListValue());
108     BrowserThread::PostDelayedTask(
109         BrowserThread::IO, FROM_HERE,
110         base::Bind(&LogPrivateAPI::PostPendingEntries, base::Unretained(this)),
111         base::TimeDelta::FromMilliseconds(kNetLogEventDelayMilliseconds));
112   }
113   pending_entries_->Append(entry.ToValue());
114 }
115
116 void LogPrivateAPI::PostPendingEntries() {
117   BrowserThread::PostTask(
118       BrowserThread::UI, FROM_HERE,
119       base::Bind(&LogPrivateAPI:: AddEntriesOnUI,
120                  base::Unretained(this),
121                  base::Passed(&pending_entries_)));
122 }
123
124 void LogPrivateAPI::AddEntriesOnUI(scoped_ptr<base::ListValue> value) {
125   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126
127   for (std::set<std::string>::iterator ix = net_internal_watches_.begin();
128        ix != net_internal_watches_.end(); ++ix) {
129     // Create the event's arguments value.
130     scoped_ptr<base::ListValue> event_args(new base::ListValue());
131     event_args->Append(value->DeepCopy());
132     scoped_ptr<Event> event(new Event(events::kOnAddNetInternalsEntries,
133                                       event_args.Pass()));
134     ExtensionSystem::Get(profile_)->event_router()->DispatchEventToExtension(
135         *ix, event.Pass());
136   }
137 }
138
139 void LogPrivateAPI::MaybeStartNetInternalLogging() {
140   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
141   if (!logging_net_internals_) {
142     g_browser_process->io_thread()->net_log()->AddThreadSafeObserver(
143         this, net::NetLog::LOG_ALL_BUT_BYTES);
144     logging_net_internals_ = true;
145   }
146 }
147
148 void LogPrivateAPI::MaybeStopNetInternalLogging() {
149   if (net_internal_watches_.empty()) {
150     BrowserThread::PostTask(
151         BrowserThread::IO, FROM_HERE,
152         base::Bind(&LogPrivateAPI:: StopNetInternalLogging,
153                    base::Unretained(this)));
154   }
155 }
156
157 void LogPrivateAPI::StopNetInternalLogging() {
158   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
159   if (net_log() && logging_net_internals_) {
160     net_log()->RemoveThreadSafeObserver(this);
161     logging_net_internals_ = false;
162   }
163 }
164
165 void LogPrivateAPI::Observe(int type,
166                             const content::NotificationSource& source,
167                             const content::NotificationDetails& details) {
168   if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
169     const Extension* extension =
170         content::Details<const UnloadedExtensionInfo>(details)->extension;
171     StopNetInternalsWatch(extension->id());
172   }
173 }
174
175 LogPrivateGetHistoricalFunction::LogPrivateGetHistoricalFunction() {
176 }
177
178 LogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() {
179 }
180
181 bool LogPrivateGetHistoricalFunction::RunImpl() {
182   // Get parameters
183   scoped_ptr<api::log_private::GetHistorical::Params> params(
184       api::log_private::GetHistorical::Params::Create(*args_));
185   EXTENSION_FUNCTION_VALIDATE(params.get());
186   filter_handler_.reset(new FilterHandler(params->filter));
187
188   system_logs::SystemLogsFetcherBase* fetcher;
189   if ((params->filter).scrub) {
190     fetcher = new system_logs::ScrubbedSystemLogsFetcher();
191   } else {
192     fetcher = new system_logs::AboutSystemLogsFetcher();
193   }
194   fetcher->Fetch(
195       base::Bind(&LogPrivateGetHistoricalFunction::OnSystemLogsLoaded, this));
196
197   return true;
198 }
199
200 void LogPrivateGetHistoricalFunction::OnSystemLogsLoaded(
201     scoped_ptr<system_logs::SystemLogsResponse> sys_info) {
202   std::vector<linked_ptr<api::log_private::LogEntry> > data;
203
204   CollectLogInfo(filter_handler_.get(), sys_info.get(), &data);
205
206   // Prepare result
207   api::log_private::Result result;
208   result.data = data;
209   api::log_private::Filter::Populate(
210       *((filter_handler_->GetFilter())->ToValue()), &result.filter);
211   SetResult(result.ToValue().release());
212   SendResponse(true);
213 }
214
215 LogPrivateStartNetInternalsWatchFunction::
216 LogPrivateStartNetInternalsWatchFunction() {
217 }
218
219 LogPrivateStartNetInternalsWatchFunction::
220 ~LogPrivateStartNetInternalsWatchFunction() {
221 }
222
223 bool LogPrivateStartNetInternalsWatchFunction::RunImpl() {
224   LogPrivateAPI::Get(GetProfile())->StartNetInternalsWatch(extension_id());
225   return true;
226 }
227
228 LogPrivateStopNetInternalsWatchFunction::
229 LogPrivateStopNetInternalsWatchFunction() {
230 }
231
232 LogPrivateStopNetInternalsWatchFunction::
233 ~LogPrivateStopNetInternalsWatchFunction() {
234 }
235
236 bool LogPrivateStopNetInternalsWatchFunction::RunImpl() {
237   LogPrivateAPI::Get(GetProfile())->StopNetInternalsWatch(extension_id());
238   return true;
239 }
240
241 }  // namespace extensions