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 82class 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 102OptionsUIHTMLSource::OptionsUIHTMLSource(DictionaryValue* localized_strings) 103 : DataSource(chrome::kChromeUISettingsHost, MessageLoop::current()) { 104 DCHECK(localized_strings); 105 localized_strings_.reset(localized_strings); 106} 107 108OptionsUIHTMLSource::~OptionsUIHTMLSource() {} 109 110void 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 128std::string OptionsUIHTMLSource::GetMimeType(const std::string&) const { 129 return "text/html"; 130} 131 132//////////////////////////////////////////////////////////////////////////////// 133// 134// OptionsPageUIHandler 135// 136//////////////////////////////////////////////////////////////////////////////// 137 138OptionsPageUIHandler::OptionsPageUIHandler() { 139} 140 141OptionsPageUIHandler::~OptionsPageUIHandler() { 142} 143 144bool OptionsPageUIHandler::IsEnabled() { 145 return true; 146} 147 148void OptionsPageUIHandler::UserMetricsRecordAction( 149 const UserMetricsAction& action) { 150 UserMetrics::RecordAction(action, web_ui_->GetProfile()); 151} 152 153// static 154void 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 164void 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 181OptionsUI::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 263OptionsUI::~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. 274void 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 288void 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 301RefCountedMemory* OptionsUI::GetFaviconResourceBytes() { 302 return ResourceBundle::GetSharedInstance(). 303 LoadDataResourceBytes(IDR_SETTINGS_FAVICON); 304} 305 306void 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 324void 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