Home | History | Annotate | Download | only in options
      1 // Copyright (c) 2011 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/options/options_ui.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "base/callback.h"
     11 #include "base/command_line.h"
     12 #include "base/memory/singleton.h"
     13 #include "base/message_loop.h"
     14 #include "base/string_piece.h"
     15 #include "base/string_util.h"
     16 #include "base/threading/thread.h"
     17 #include "base/time.h"
     18 #include "base/values.h"
     19 #include "chrome/browser/browser_about_handler.h"
     20 #include "chrome/browser/metrics/user_metrics.h"
     21 #include "chrome/browser/profiles/profile.h"
     22 #include "chrome/browser/ui/webui/options/about_page_handler.h"
     23 #include "chrome/browser/ui/webui/options/advanced_options_handler.h"
     24 #include "chrome/browser/ui/webui/options/autofill_options_handler.h"
     25 #include "chrome/browser/ui/webui/options/browser_options_handler.h"
     26 #include "chrome/browser/ui/webui/options/clear_browser_data_handler.h"
     27 #include "chrome/browser/ui/webui/options/content_settings_handler.h"
     28 #include "chrome/browser/ui/webui/options/cookies_view_handler.h"
     29 #include "chrome/browser/ui/webui/options/core_options_handler.h"
     30 #include "chrome/browser/ui/webui/options/font_settings_handler.h"
     31 #include "chrome/browser/ui/webui/options/import_data_handler.h"
     32 #include "chrome/browser/ui/webui/options/language_options_handler.h"
     33 #include "chrome/browser/ui/webui/options/password_manager_handler.h"
     34 #include "chrome/browser/ui/webui/options/personal_options_handler.h"
     35 #include "chrome/browser/ui/webui/options/search_engine_manager_handler.h"
     36 #include "chrome/browser/ui/webui/options/stop_syncing_handler.h"
     37 #include "chrome/browser/ui/webui/options/sync_setup_handler.h"
     38 #include "chrome/browser/ui/webui/theme_source.h"
     39 #include "chrome/common/jstemplate_builder.h"
     40 #include "chrome/common/time_format.h"
     41 #include "chrome/common/url_constants.h"
     42 #include "content/browser/browser_thread.h"
     43 #include "content/browser/renderer_host/render_view_host.h"
     44 #include "content/browser/tab_contents/tab_contents.h"
     45 #include "content/browser/tab_contents/tab_contents_delegate.h"
     46 #include "content/common/notification_type.h"
     47 #include "grit/browser_resources.h"
     48 #include "grit/chromium_strings.h"
     49 #include "grit/generated_resources.h"
     50 #include "grit/locale_settings.h"
     51 #include "grit/theme_resources.h"
     52 #include "net/base/escape.h"
     53 #include "ui/base/resource/resource_bundle.h"
     54 
     55 #if defined(OS_CHROMEOS)
     56 #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
     57 #include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h"
     58 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
     59 #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h"
     60 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
     61 #include "chrome/browser/ui/webui/options/chromeos/language_chewing_handler.h"
     62 #include "chrome/browser/ui/webui/options/chromeos/language_customize_modifier_keys_handler.h"
     63 #include "chrome/browser/ui/webui/options/chromeos/language_hangul_handler.h"
     64 #include "chrome/browser/ui/webui/options/chromeos/language_mozc_handler.h"
     65 #include "chrome/browser/ui/webui/options/chromeos/language_pinyin_handler.h"
     66 #include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h"
     67 #include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h"
     68 #include "chrome/browser/ui/webui/options/chromeos/system_options_handler.h"
     69 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
     70 #endif
     71 
     72 #if defined(USE_NSS)
     73 #include "chrome/browser/ui/webui/options/certificate_manager_handler.h"
     74 #endif
     75 
     76 ////////////////////////////////////////////////////////////////////////////////
     77 //
     78 // OptionsUIHTMLSource
     79 //
     80 ////////////////////////////////////////////////////////////////////////////////
     81 
     82 class OptionsUIHTMLSource : public ChromeURLDataManager::DataSource {
     83  public:
     84   // The constructor takes over ownership of |localized_strings|.
     85   explicit OptionsUIHTMLSource(DictionaryValue* localized_strings);
     86   virtual ~OptionsUIHTMLSource();
     87 
     88   // Called when the network layer has requested a resource underneath
     89   // the path we registered.
     90   virtual void StartDataRequest(const std::string& path,
     91                                 bool is_incognito,
     92                                 int request_id);
     93   virtual std::string GetMimeType(const std::string&) const;
     94 
     95  private:
     96    // Localized strings collection.
     97   scoped_ptr<DictionaryValue> localized_strings_;
     98 
     99   DISALLOW_COPY_AND_ASSIGN(OptionsUIHTMLSource);
    100 };
    101 
    102 OptionsUIHTMLSource::OptionsUIHTMLSource(DictionaryValue* localized_strings)
    103     : DataSource(chrome::kChromeUISettingsHost, MessageLoop::current()) {
    104   DCHECK(localized_strings);
    105   localized_strings_.reset(localized_strings);
    106 }
    107 
    108 OptionsUIHTMLSource::~OptionsUIHTMLSource() {}
    109 
    110 void OptionsUIHTMLSource::StartDataRequest(const std::string& path,
    111                                            bool is_incognito,
    112                                            int request_id) {
    113   SetFontAndTextDirection(localized_strings_.get());
    114 
    115   static const base::StringPiece options_html(
    116       ResourceBundle::GetSharedInstance().GetRawDataResource(
    117           IDR_OPTIONS_HTML));
    118   const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
    119       options_html, localized_strings_.get());
    120 
    121   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
    122   html_bytes->data.resize(full_html.size());
    123   std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
    124 
    125   SendResponse(request_id, html_bytes);
    126 }
    127 
    128 std::string OptionsUIHTMLSource::GetMimeType(const std::string&) const {
    129   return "text/html";
    130 }
    131 
    132 ////////////////////////////////////////////////////////////////////////////////
    133 //
    134 // OptionsPageUIHandler
    135 //
    136 ////////////////////////////////////////////////////////////////////////////////
    137 
    138 OptionsPageUIHandler::OptionsPageUIHandler() {
    139 }
    140 
    141 OptionsPageUIHandler::~OptionsPageUIHandler() {
    142 }
    143 
    144 bool OptionsPageUIHandler::IsEnabled() {
    145   return true;
    146 }
    147 
    148 void OptionsPageUIHandler::UserMetricsRecordAction(
    149     const UserMetricsAction& action) {
    150   UserMetrics::RecordAction(action, web_ui_->GetProfile());
    151 }
    152 
    153 // static
    154 void OptionsPageUIHandler::RegisterStrings(
    155     DictionaryValue* localized_strings,
    156     const OptionsStringResource* resources,
    157     size_t length) {
    158   for (size_t i = 0; i < length; ++i) {
    159     localized_strings->SetString(
    160         resources[i].name, l10n_util::GetStringUTF16(resources[i].id));
    161   }
    162 }
    163 
    164 void OptionsPageUIHandler::RegisterTitle(DictionaryValue* localized_strings,
    165                                          const std::string& variable_name,
    166                                          int title_id) {
    167   localized_strings->SetString(variable_name,
    168       l10n_util::GetStringUTF16(title_id));
    169   localized_strings->SetString(variable_name + "TabTitle",
    170       l10n_util::GetStringFUTF16(IDS_OPTIONS_TAB_TITLE,
    171           l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE),
    172           l10n_util::GetStringUTF16(title_id)));
    173 }
    174 
    175 ////////////////////////////////////////////////////////////////////////////////
    176 //
    177 // OptionsUI
    178 //
    179 ////////////////////////////////////////////////////////////////////////////////
    180 
    181 OptionsUI::OptionsUI(TabContents* contents)
    182     : WebUI(contents), initialized_handlers_(false) {
    183   DictionaryValue* localized_strings = new DictionaryValue();
    184 
    185   CoreOptionsHandler* core_handler;
    186 #if defined(OS_CHROMEOS)
    187   core_handler = new chromeos::CoreChromeOSOptionsHandler();
    188 #else
    189   core_handler = new CoreOptionsHandler();
    190 #endif
    191   core_handler->set_handlers_host(this);
    192   AddOptionsPageUIHandler(localized_strings, core_handler);
    193 
    194   AddOptionsPageUIHandler(localized_strings, new AdvancedOptionsHandler());
    195   AddOptionsPageUIHandler(localized_strings, new AutofillOptionsHandler());
    196   AddOptionsPageUIHandler(localized_strings, new BrowserOptionsHandler());
    197   AddOptionsPageUIHandler(localized_strings, new ClearBrowserDataHandler());
    198   AddOptionsPageUIHandler(localized_strings, new ContentSettingsHandler());
    199   AddOptionsPageUIHandler(localized_strings, new CookiesViewHandler());
    200   AddOptionsPageUIHandler(localized_strings, new FontSettingsHandler());
    201 #if defined(OS_CHROMEOS)
    202   AddOptionsPageUIHandler(localized_strings,
    203                           new chromeos::CrosLanguageOptionsHandler());
    204 #else
    205   AddOptionsPageUIHandler(localized_strings, new LanguageOptionsHandler());
    206 #endif
    207   AddOptionsPageUIHandler(localized_strings, new PasswordManagerHandler());
    208   AddOptionsPageUIHandler(localized_strings, new PersonalOptionsHandler());
    209   AddOptionsPageUIHandler(localized_strings, new SearchEngineManagerHandler());
    210   AddOptionsPageUIHandler(localized_strings, new ImportDataHandler());
    211   AddOptionsPageUIHandler(localized_strings, new StopSyncingHandler());
    212   AddOptionsPageUIHandler(localized_strings, new SyncSetupHandler());
    213 #if defined(OS_CHROMEOS)
    214   AddOptionsPageUIHandler(localized_strings, new AboutPageHandler());
    215   AddOptionsPageUIHandler(localized_strings,
    216                           new chromeos::AccountsOptionsHandler());
    217   AddOptionsPageUIHandler(localized_strings, new InternetOptionsHandler());
    218   AddOptionsPageUIHandler(localized_strings,
    219                           new chromeos::LanguageChewingHandler());
    220   AddOptionsPageUIHandler(localized_strings,
    221                           new chromeos::LanguageCustomizeModifierKeysHandler());
    222   AddOptionsPageUIHandler(localized_strings,
    223                           new chromeos::LanguageHangulHandler());
    224   AddOptionsPageUIHandler(localized_strings,
    225                           new chromeos::LanguageMozcHandler());
    226   AddOptionsPageUIHandler(localized_strings,
    227                           new chromeos::LanguagePinyinHandler());
    228   AddOptionsPageUIHandler(localized_strings, new chromeos::ProxyHandler());
    229   AddOptionsPageUIHandler(localized_strings,
    230                           new chromeos::ChangePictureOptionsHandler());
    231   AddOptionsPageUIHandler(localized_strings,
    232                           new chromeos::StatsOptionsHandler());
    233   AddOptionsPageUIHandler(localized_strings, new SystemOptionsHandler());
    234 #endif
    235 #if defined(USE_NSS)
    236   AddOptionsPageUIHandler(localized_strings, new CertificateManagerHandler());
    237 #endif
    238 
    239   // |localized_strings| ownership is taken over by this constructor.
    240   OptionsUIHTMLSource* html_source =
    241       new OptionsUIHTMLSource(localized_strings);
    242 
    243   // Set up the chrome://settings/ source.
    244   contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
    245 
    246   // Set up the chrome://theme/ source.
    247   ThemeSource* theme = new ThemeSource(contents->profile());
    248   contents->profile()->GetChromeURLDataManager()->AddDataSource(theme);
    249 
    250 #if defined(OS_CHROMEOS)
    251   // Set up the chrome://userimage/ source.
    252   chromeos::UserImageSource* user_image_source =
    253       new chromeos::UserImageSource();
    254   contents->profile()->GetChromeURLDataManager()->AddDataSource(
    255       user_image_source);
    256 #endif
    257 
    258   // Initialize the chrome://about/ source in case the user clicks the credits
    259   // link.
    260   InitializeAboutDataSource(contents->profile());
    261 }
    262 
    263 OptionsUI::~OptionsUI() {
    264   // Uninitialize all registered handlers. The base class owns them and it will
    265   // eventually delete them. Skip over the generic handler.
    266   for (std::vector<WebUIMessageHandler*>::iterator iter = handlers_.begin() + 1;
    267        iter != handlers_.end();
    268        ++iter) {
    269     static_cast<OptionsPageUIHandler*>(*iter)->Uninitialize();
    270   }
    271 }
    272 
    273 // Override.
    274 void OptionsUI::RenderViewCreated(RenderViewHost* render_view_host) {
    275   std::string command_line_string;
    276 
    277 #if defined(OS_WIN)
    278   std::wstring wstr = CommandLine::ForCurrentProcess()->command_line_string();
    279   command_line_string = WideToASCII(wstr);
    280 #else
    281   command_line_string = CommandLine::ForCurrentProcess()->command_line_string();
    282 #endif
    283 
    284   render_view_host->SetWebUIProperty("commandLineString", command_line_string);
    285   WebUI::RenderViewCreated(render_view_host);
    286 }
    287 
    288 void OptionsUI::DidBecomeActiveForReusedRenderView() {
    289   // When the renderer is re-used (e.g., for back/forward navigation within
    290   // options), the handlers are torn down and rebuilt, so are no longer
    291   // initialized, but the web page's DOM may remain intact, in which case onload
    292   // won't fire to initilize the handlers. To make sure initialization always
    293   // happens, call reinitializeCore (which is a no-op unless the DOM was already
    294   // initialized).
    295   CallJavascriptFunction("OptionsPage.reinitializeCore");
    296 
    297   WebUI::DidBecomeActiveForReusedRenderView();
    298 }
    299 
    300 // static
    301 RefCountedMemory* OptionsUI::GetFaviconResourceBytes() {
    302   return ResourceBundle::GetSharedInstance().
    303       LoadDataResourceBytes(IDR_SETTINGS_FAVICON);
    304 }
    305 
    306 void OptionsUI::InitializeHandlers() {
    307   DCHECK(!GetProfile()->IsOffTheRecord() || Profile::IsGuestSession());
    308 
    309   // The reinitialize call from DidBecomeActiveForReusedRenderView end up being
    310   // delivered after a new web page DOM has been brought up in an existing
    311   // renderer (due to IPC delays), causing this method to be called twice. If
    312   // that happens, ignore the second call.
    313   if (initialized_handlers_)
    314     return;
    315   initialized_handlers_ = true;
    316 
    317   std::vector<WebUIMessageHandler*>::iterator iter;
    318   // Skip over the generic handler.
    319   for (iter = handlers_.begin() + 1; iter != handlers_.end(); ++iter) {
    320     (static_cast<OptionsPageUIHandler*>(*iter))->Initialize();
    321   }
    322 }
    323 
    324 void OptionsUI::AddOptionsPageUIHandler(DictionaryValue* localized_strings,
    325                                         OptionsPageUIHandler* handler_raw) {
    326   scoped_ptr<OptionsPageUIHandler> handler(handler_raw);
    327   DCHECK(handler.get());
    328   // Add only if handler's service is enabled.
    329   if (handler->IsEnabled()) {
    330     handler->GetLocalizedValues(localized_strings);
    331     // Add handler to the list and also pass the ownership.
    332     AddMessageHandler(handler.release()->Attach(this));
    333   }
    334 }
    335