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/ui/webui/system_info_ui.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/memory/ref_counted_memory.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/memory/weak_ptr.h"
12#include "base/message_loop/message_loop.h"
13#include "base/path_service.h"
14#include "base/strings/string_piece.h"
15#include "base/strings/string_util.h"
16#include "base/strings/utf_string_conversions.h"
17#include "base/synchronization/waitable_event.h"
18#include "base/threading/thread.h"
19#include "base/time/time.h"
20#include "base/values.h"
21#include "chrome/browser/feedback/system_logs/about_system_logs_fetcher.h"
22#include "chrome/browser/profiles/profile.h"
23#include "chrome/common/chrome_paths.h"
24#include "chrome/common/url_constants.h"
25#include "chrome/grit/chromium_strings.h"
26#include "chrome/grit/generated_resources.h"
27#include "chrome/grit/locale_settings.h"
28#include "content/public/browser/url_data_source.h"
29#include "content/public/browser/web_contents.h"
30#include "content/public/browser/web_ui.h"
31#include "content/public/browser/web_ui_message_handler.h"
32#include "grit/browser_resources.h"
33#include "net/base/directory_lister.h"
34#include "net/base/escape.h"
35#include "ui/base/l10n/l10n_util.h"
36#include "ui/base/resource/resource_bundle.h"
37#include "ui/base/webui/jstemplate_builder.h"
38#include "ui/base/webui/web_ui_util.h"
39
40using content::WebContents;
41using content::WebUIMessageHandler;
42using system_logs::SystemLogsResponse;
43using system_logs::AboutSystemLogsFetcher;
44
45class SystemInfoUIHTMLSource : public content::URLDataSource{
46 public:
47  SystemInfoUIHTMLSource();
48
49  // content::URLDataSource implementation.
50  virtual std::string GetSource() const OVERRIDE;
51  virtual void StartDataRequest(
52      const std::string& path,
53      int render_process_id,
54      int render_frame_id,
55      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
56  virtual std::string GetMimeType(const std::string&) const OVERRIDE {
57    return "text/html";
58  }
59  virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
60    return false;
61  }
62
63 private:
64  virtual ~SystemInfoUIHTMLSource() {}
65
66  void SysInfoComplete(scoped_ptr<SystemLogsResponse> response);
67  void RequestComplete();
68  void WaitForData();
69
70  // Stored data from StartDataRequest()
71  std::string path_;
72  content::URLDataSource::GotDataCallback callback_;
73
74  scoped_ptr<SystemLogsResponse> response_;
75  base::WeakPtrFactory<SystemInfoUIHTMLSource> weak_ptr_factory_;
76  DISALLOW_COPY_AND_ASSIGN(SystemInfoUIHTMLSource);
77};
78
79// The handler for Javascript messages related to the "system" view.
80class SystemInfoHandler : public WebUIMessageHandler,
81                          public base::SupportsWeakPtr<SystemInfoHandler> {
82 public:
83  SystemInfoHandler();
84  virtual ~SystemInfoHandler();
85
86  // WebUIMessageHandler implementation.
87  virtual void RegisterMessages() OVERRIDE;
88
89 private:
90  DISALLOW_COPY_AND_ASSIGN(SystemInfoHandler);
91};
92
93////////////////////////////////////////////////////////////////////////////////
94//
95// SystemInfoUIHTMLSource
96//
97////////////////////////////////////////////////////////////////////////////////
98
99SystemInfoUIHTMLSource::SystemInfoUIHTMLSource() : weak_ptr_factory_(this) {}
100
101std::string SystemInfoUIHTMLSource::GetSource() const {
102  return chrome::kChromeUISystemInfoHost;
103}
104
105void SystemInfoUIHTMLSource::StartDataRequest(
106    const std::string& path,
107    int render_process_id,
108    int render_frame_id,
109    const content::URLDataSource::GotDataCallback& callback) {
110  path_ = path;
111  callback_ = callback;
112
113  AboutSystemLogsFetcher* fetcher = new AboutSystemLogsFetcher();
114  fetcher->Fetch(base::Bind(&SystemInfoUIHTMLSource::SysInfoComplete,
115                            weak_ptr_factory_.GetWeakPtr()));
116}
117
118
119void SystemInfoUIHTMLSource::SysInfoComplete(
120    scoped_ptr<SystemLogsResponse> sys_info) {
121  response_ = sys_info.Pass();
122  RequestComplete();
123}
124
125void SystemInfoUIHTMLSource::RequestComplete() {
126  base::DictionaryValue strings;
127  strings.SetString("title", l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TITLE));
128  strings.SetString("description",
129                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_DESC));
130  strings.SetString("tableTitle",
131                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TABLE_TITLE));
132  strings.SetString(
133      "logFileTableTitle",
134      l10n_util::GetStringUTF16(IDS_ABOUT_SYS_LOG_FILE_TABLE_TITLE));
135  strings.SetString("expandAllBtn",
136                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_EXPAND_ALL));
137  strings.SetString("collapseAllBtn",
138                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE_ALL));
139  strings.SetString("expandBtn",
140                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_EXPAND));
141  strings.SetString("collapseBtn",
142                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE));
143  strings.SetString("parseError",
144                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_PARSE_ERROR));
145  webui::SetFontAndTextDirection(&strings);
146  if (response_.get()) {
147    base::ListValue* details = new base::ListValue();
148    strings.Set("details", details);
149    for (SystemLogsResponse::const_iterator it = response_->begin();
150         it != response_->end();
151         ++it) {
152      base::DictionaryValue* val = new base::DictionaryValue;
153      val->SetString("statName", it->first);
154      val->SetString("statValue", it->second);
155      details->Append(val);
156    }
157  }
158  static const base::StringPiece systeminfo_html(
159      ResourceBundle::GetSharedInstance().GetRawDataResource(
160          IDR_ABOUT_SYS_HTML));
161  webui::UseVersion2 version2;
162  std::string full_html = webui::GetI18nTemplateHtml(systeminfo_html, &strings);
163  callback_.Run(base::RefCountedString::TakeString(&full_html));
164}
165
166////////////////////////////////////////////////////////////////////////////////
167//
168// SystemInfoHandler
169//
170////////////////////////////////////////////////////////////////////////////////
171SystemInfoHandler::SystemInfoHandler() {
172}
173
174SystemInfoHandler::~SystemInfoHandler() {
175}
176
177void SystemInfoHandler::RegisterMessages() {
178  // TODO(stevenjb): add message registration, callbacks...
179}
180
181////////////////////////////////////////////////////////////////////////////////
182//
183// SystemInfoUI
184//
185////////////////////////////////////////////////////////////////////////////////
186
187SystemInfoUI::SystemInfoUI(content::WebUI* web_ui) : WebUIController(web_ui) {
188  SystemInfoHandler* handler = new SystemInfoHandler();
189  web_ui->AddMessageHandler(handler);
190  SystemInfoUIHTMLSource* html_source = new SystemInfoUIHTMLSource();
191
192  // Set up the chrome://system/ source.
193  Profile* profile = Profile::FromWebUI(web_ui);
194  content::URLDataSource::Add(profile, html_source);
195}
196