• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
OptionsUIHTMLSource(DictionaryValue * localized_strings)102 OptionsUIHTMLSource::OptionsUIHTMLSource(DictionaryValue* localized_strings)
103     : DataSource(chrome::kChromeUISettingsHost, MessageLoop::current()) {
104   DCHECK(localized_strings);
105   localized_strings_.reset(localized_strings);
106 }
107 
~OptionsUIHTMLSource()108 OptionsUIHTMLSource::~OptionsUIHTMLSource() {}
109 
StartDataRequest(const std::string & path,bool is_incognito,int request_id)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 
GetMimeType(const std::string &) const128 std::string OptionsUIHTMLSource::GetMimeType(const std::string&) const {
129   return "text/html";
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 //
134 // OptionsPageUIHandler
135 //
136 ////////////////////////////////////////////////////////////////////////////////
137 
OptionsPageUIHandler()138 OptionsPageUIHandler::OptionsPageUIHandler() {
139 }
140 
~OptionsPageUIHandler()141 OptionsPageUIHandler::~OptionsPageUIHandler() {
142 }
143 
IsEnabled()144 bool OptionsPageUIHandler::IsEnabled() {
145   return true;
146 }
147 
UserMetricsRecordAction(const UserMetricsAction & action)148 void OptionsPageUIHandler::UserMetricsRecordAction(
149     const UserMetricsAction& action) {
150   UserMetrics::RecordAction(action, web_ui_->GetProfile());
151 }
152 
153 // static
RegisterStrings(DictionaryValue * localized_strings,const OptionsStringResource * resources,size_t length)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 
RegisterTitle(DictionaryValue * localized_strings,const std::string & variable_name,int title_id)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 
OptionsUI(TabContents * contents)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 
~OptionsUI()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.
RenderViewCreated(RenderViewHost * render_view_host)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 
DidBecomeActiveForReusedRenderView()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
GetFaviconResourceBytes()301 RefCountedMemory* OptionsUI::GetFaviconResourceBytes() {
302   return ResourceBundle::GetSharedInstance().
303       LoadDataResourceBytes(IDR_SETTINGS_FAVICON);
304 }
305 
InitializeHandlers()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 
AddOptionsPageUIHandler(DictionaryValue * localized_strings,OptionsPageUIHandler * handler_raw)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