15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/webui/system_info_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/feedback/system_logs/about_system_logs_fetcher.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/chromium_strings.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/locale_settings.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/url_data_source.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/directory_lister.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/jstemplate_builder.h"
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/web_ui_util.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebUIMessageHandler;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using system_logs::SystemLogsResponse;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using system_logs::AboutSystemLogsFetcher;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SystemInfoUIHTMLSource : public content::URLDataSource{
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemInfoUIHTMLSource();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // content::URLDataSource implementation.
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::string GetSource() const OVERRIDE;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StartDataRequest(
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& path,
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int render_process_id,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int render_frame_id,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetMimeType(const std::string&) const OVERRIDE {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return "text/html";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SystemInfoUIHTMLSource() {}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SysInfoComplete(scoped_ptr<SystemLogsResponse> response);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RequestComplete();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WaitForData();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stored data from StartDataRequest()
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path_;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::URLDataSource::GotDataCallback callback_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SystemLogsResponse> response_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<SystemInfoUIHTMLSource> weak_ptr_factory_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SystemInfoUIHTMLSource);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The handler for Javascript messages related to the "system" view.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SystemInfoHandler : public WebUIMessageHandler,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          public base::SupportsWeakPtr<SystemInfoHandler> {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemInfoHandler();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SystemInfoHandler();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebUIMessageHandler implementation.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SystemInfoHandler);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SystemInfoUIHTMLSource
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SystemInfoUIHTMLSource::SystemInfoUIHTMLSource() : weak_ptr_factory_(this) {}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string SystemInfoUIHTMLSource::GetSource() const {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return chrome::kChromeUISystemInfoHost;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemInfoUIHTMLSource::StartDataRequest(
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path,
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int render_process_id,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int render_frame_id,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::URLDataSource::GotDataCallback& callback) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path_ = path;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_ = callback;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AboutSystemLogsFetcher* fetcher = new AboutSystemLogsFetcher();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->Fetch(base::Bind(&SystemInfoUIHTMLSource::SysInfoComplete,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            weak_ptr_factory_.GetWeakPtr()));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemInfoUIHTMLSource::SysInfoComplete(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SystemLogsResponse> sys_info) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_ = sys_info.Pass();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestComplete();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemInfoUIHTMLSource::RequestComplete() {
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue strings;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings.SetString("title", l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TITLE));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings.SetString("description",
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_DESC));
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString("tableTitle",
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TABLE_TITLE));
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString(
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "logFileTableTitle",
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_ABOUT_SYS_LOG_FILE_TABLE_TITLE));
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString("expandAllBtn",
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_EXPAND_ALL));
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString("collapseAllBtn",
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE_ALL));
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString("expandBtn",
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_EXPAND));
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString("collapseBtn",
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE));
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  strings.SetString("parseError",
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                    l10n_util::GetStringUTF16(IDS_ABOUT_SYS_PARSE_ERROR));
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webui::SetFontAndTextDirection(&strings);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_.get()) {
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue* details = new base::ListValue();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strings.Set("details", details);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (SystemLogsResponse::const_iterator it = response_->begin();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != response_->end();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++it) {
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue* val = new base::DictionaryValue;
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      val->SetString("statName", it->first);
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      val->SetString("statValue", it->second);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      details->Append(val);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const base::StringPiece systeminfo_html(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IDR_ABOUT_SYS_HTML));
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  webui::UseVersion2 version2;
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string full_html = webui::GetI18nTemplateHtml(systeminfo_html, &strings);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_.Run(base::RefCountedString::TakeString(&full_html));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SystemInfoHandler
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SystemInfoHandler::SystemInfoHandler() {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SystemInfoHandler::~SystemInfoHandler() {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemInfoHandler::RegisterMessages() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(stevenjb): add message registration, callbacks...
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SystemInfoUI
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SystemInfoUI::SystemInfoUI(content::WebUI* web_ui) : WebUIController(web_ui) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemInfoHandler* handler = new SystemInfoHandler();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->AddMessageHandler(handler);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemInfoUIHTMLSource* html_source = new SystemInfoUIHTMLSource();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up the chrome://system/ source.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::URLDataSource::Add(profile, html_source);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
196