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