e5c2916c69ca504a7fe73f21ccfc706d36d281fe
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / options_ui.cc
1 // Copyright (c) 2012 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/basictypes.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/memory/singleton.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/strings/string_piece.h"
17 #include "base/strings/string_util.h"
18 #include "base/threading/thread.h"
19 #include "base/time/time.h"
20 #include "base/values.h"
21 #include "chrome/browser/autocomplete/autocomplete_match.h"
22 #include "chrome/browser/autocomplete/autocomplete_result.h"
23 #include "chrome/browser/browser_about_handler.h"
24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/webui/metrics_handler.h"
27 #include "chrome/browser/ui/webui/options/autofill_options_handler.h"
28 #include "chrome/browser/ui/webui/options/browser_options_handler.h"
29 #include "chrome/browser/ui/webui/options/clear_browser_data_handler.h"
30 #include "chrome/browser/ui/webui/options/content_settings_handler.h"
31 #include "chrome/browser/ui/webui/options/cookies_view_handler.h"
32 #include "chrome/browser/ui/webui/options/core_options_handler.h"
33 #include "chrome/browser/ui/webui/options/create_profile_handler.h"
34 #include "chrome/browser/ui/webui/options/font_settings_handler.h"
35 #include "chrome/browser/ui/webui/options/handler_options_handler.h"
36 #include "chrome/browser/ui/webui/options/home_page_overlay_handler.h"
37 #include "chrome/browser/ui/webui/options/import_data_handler.h"
38 #include "chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h"
39 #include "chrome/browser/ui/webui/options/language_options_handler.h"
40 #include "chrome/browser/ui/webui/options/manage_profile_handler.h"
41 #include "chrome/browser/ui/webui/options/managed_user_create_confirm_handler.h"
42 #include "chrome/browser/ui/webui/options/managed_user_import_handler.h"
43 #include "chrome/browser/ui/webui/options/managed_user_learn_more_handler.h"
44 #include "chrome/browser/ui/webui/options/media_devices_selection_handler.h"
45 #include "chrome/browser/ui/webui/options/media_galleries_handler.h"
46 #include "chrome/browser/ui/webui/options/password_manager_handler.h"
47 #include "chrome/browser/ui/webui/options/reset_profile_settings_handler.h"
48 #include "chrome/browser/ui/webui/options/search_engine_manager_handler.h"
49 #include "chrome/browser/ui/webui/options/startup_pages_handler.h"
50 #include "chrome/browser/ui/webui/sync_setup_handler.h"
51 #include "chrome/browser/ui/webui/theme_source.h"
52 #include "chrome/common/url_constants.h"
53 #include "content/public/browser/notification_types.h"
54 #include "content/public/browser/render_view_host.h"
55 #include "content/public/browser/url_data_source.h"
56 #include "content/public/browser/web_contents.h"
57 #include "content/public/browser/web_contents_delegate.h"
58 #include "content/public/browser/web_ui.h"
59 #include "grit/chromium_strings.h"
60 #include "grit/generated_resources.h"
61 #include "grit/locale_settings.h"
62 #include "grit/options_resources.h"
63 #include "grit/theme_resources.h"
64 #include "net/base/escape.h"
65 #include "ui/base/l10n/l10n_util.h"
66 #include "ui/base/resource/resource_bundle.h"
67 #include "ui/base/webui/jstemplate_builder.h"
68 #include "ui/base/webui/web_ui_util.h"
69 #include "url/gurl.h"
70
71 #if defined(OS_CHROMEOS)
72 #include "chrome/browser/chromeos/system/pointer_device_observer.h"
73 #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
74 #include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h"
75 #include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h"
76 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
77 #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h"
78 #include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h"
79 #include "chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h"
80 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
81 #include "chrome/browser/ui/webui/options/chromeos/keyboard_handler.h"
82 #include "chrome/browser/ui/webui/options/chromeos/pointer_handler.h"
83 #include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h"
84 #include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h"
85 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
86 #endif
87
88 #if defined(USE_NSS)
89 #include "chrome/browser/ui/webui/options/certificate_manager_handler.h"
90 #endif
91
92 #if defined(ENABLE_GOOGLE_NOW)
93 #include "chrome/browser/ui/webui/options/geolocation_options_handler.h"
94 #endif
95
96 using content::RenderViewHost;
97
98 namespace {
99
100 const char kLocalizedStringsFile[] = "strings.js";
101 const char kOptionsBundleJsFile[]  = "options_bundle.js";
102
103 }  // namespace
104
105 namespace options {
106
107 ////////////////////////////////////////////////////////////////////////////////
108 //
109 // OptionsUIHTMLSource
110 //
111 ////////////////////////////////////////////////////////////////////////////////
112
113 class OptionsUIHTMLSource : public content::URLDataSource {
114  public:
115   // The constructor takes over ownership of |localized_strings|.
116   explicit OptionsUIHTMLSource(base::DictionaryValue* localized_strings);
117
118   // content::URLDataSource implementation.
119   virtual std::string GetSource() const OVERRIDE;
120   virtual void StartDataRequest(
121       const std::string& path,
122       int render_process_id,
123       int render_frame_id,
124       const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
125   virtual std::string GetMimeType(const std::string&) const OVERRIDE;
126   virtual bool ShouldDenyXFrameOptions() const OVERRIDE;
127
128  private:
129   virtual ~OptionsUIHTMLSource();
130
131   // Localized strings collection.
132   scoped_ptr<base::DictionaryValue> localized_strings_;
133
134   DISALLOW_COPY_AND_ASSIGN(OptionsUIHTMLSource);
135 };
136
137 OptionsUIHTMLSource::OptionsUIHTMLSource(
138     base::DictionaryValue* localized_strings) {
139   DCHECK(localized_strings);
140   localized_strings_.reset(localized_strings);
141 }
142
143 std::string OptionsUIHTMLSource::GetSource() const {
144   return chrome::kChromeUISettingsFrameHost;
145 }
146
147 void OptionsUIHTMLSource::StartDataRequest(
148     const std::string& path,
149     int render_process_id,
150     int render_frame_id,
151     const content::URLDataSource::GotDataCallback& callback) {
152   scoped_refptr<base::RefCountedMemory> response_bytes;
153   webui::SetFontAndTextDirection(localized_strings_.get());
154
155   if (path == kLocalizedStringsFile) {
156     // Return dynamically-generated strings from memory.
157     webui::UseVersion2 version;
158     std::string strings_js;
159     webui::AppendJsonJS(localized_strings_.get(), &strings_js);
160     response_bytes = base::RefCountedString::TakeString(&strings_js);
161   } else if (path == kOptionsBundleJsFile) {
162     // Return (and cache) the options javascript code.
163     response_bytes = ui::ResourceBundle::GetSharedInstance().
164         LoadDataResourceBytes(IDR_OPTIONS_BUNDLE_JS);
165   } else {
166     // Return (and cache) the main options html page as the default.
167     response_bytes = ui::ResourceBundle::GetSharedInstance().
168         LoadDataResourceBytes(IDR_OPTIONS_HTML);
169   }
170
171   callback.Run(response_bytes.get());
172 }
173
174 std::string OptionsUIHTMLSource::GetMimeType(const std::string& path) const {
175   if (path == kLocalizedStringsFile || path == kOptionsBundleJsFile)
176     return "application/javascript";
177
178   return "text/html";
179 }
180
181 bool OptionsUIHTMLSource::ShouldDenyXFrameOptions() const {
182   return false;
183 }
184
185 OptionsUIHTMLSource::~OptionsUIHTMLSource() {}
186
187 ////////////////////////////////////////////////////////////////////////////////
188 //
189 // OptionsPageUIHandler
190 //
191 ////////////////////////////////////////////////////////////////////////////////
192
193 const char OptionsPageUIHandler::kSettingsAppKey[] = "settingsApp";
194
195 OptionsPageUIHandler::OptionsPageUIHandler() {
196 }
197
198 OptionsPageUIHandler::~OptionsPageUIHandler() {
199 }
200
201 bool OptionsPageUIHandler::IsEnabled() {
202   return true;
203 }
204
205 // static
206 void OptionsPageUIHandler::RegisterStrings(
207     base::DictionaryValue* localized_strings,
208     const OptionsStringResource* resources,
209     size_t length) {
210   for (size_t i = 0; i < length; ++i) {
211     base::string16 value;
212     if (resources[i].substitution_id == 0) {
213       value = l10n_util::GetStringUTF16(resources[i].id);
214     } else {
215       value = l10n_util::GetStringFUTF16(
216           resources[i].id,
217           l10n_util::GetStringUTF16(resources[i].substitution_id));
218     }
219     localized_strings->SetString(resources[i].name, value);
220   }
221 }
222
223 void OptionsPageUIHandler::RegisterTitle(
224     base::DictionaryValue* localized_strings,
225     const std::string& variable_name,
226     int title_id) {
227   localized_strings->SetString(variable_name,
228       l10n_util::GetStringUTF16(title_id));
229   localized_strings->SetString(variable_name + "TabTitle",
230       l10n_util::GetStringFUTF16(IDS_OPTIONS_TAB_TITLE,
231           l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE),
232           l10n_util::GetStringUTF16(title_id)));
233 }
234
235 ////////////////////////////////////////////////////////////////////////////////
236 //
237 // OptionsUI
238 //
239 ////////////////////////////////////////////////////////////////////////////////
240
241 OptionsUI::OptionsUI(content::WebUI* web_ui)
242     : WebUIController(web_ui),
243       WebContentsObserver(web_ui->GetWebContents()),
244       initialized_handlers_(false) {
245   base::DictionaryValue* localized_strings = new base::DictionaryValue();
246   localized_strings->Set(OptionsPageUIHandler::kSettingsAppKey,
247                          new base::DictionaryValue());
248
249   CoreOptionsHandler* core_handler;
250 #if defined(OS_CHROMEOS)
251   core_handler = new chromeos::options::CoreChromeOSOptionsHandler();
252 #else
253   core_handler = new CoreOptionsHandler();
254 #endif
255   core_handler->set_handlers_host(this);
256   AddOptionsPageUIHandler(localized_strings, core_handler);
257
258   AddOptionsPageUIHandler(localized_strings, new AutofillOptionsHandler());
259
260   BrowserOptionsHandler* browser_options_handler = new BrowserOptionsHandler();
261   AddOptionsPageUIHandler(localized_strings, browser_options_handler);
262
263   AddOptionsPageUIHandler(localized_strings, new ClearBrowserDataHandler());
264   AddOptionsPageUIHandler(localized_strings, new ContentSettingsHandler());
265   AddOptionsPageUIHandler(localized_strings, new CookiesViewHandler());
266   AddOptionsPageUIHandler(localized_strings, new CreateProfileHandler());
267   AddOptionsPageUIHandler(localized_strings, new FontSettingsHandler());
268 #if defined(ENABLE_GOOGLE_NOW)
269   AddOptionsPageUIHandler(localized_strings, new GeolocationOptionsHandler());
270 #endif
271   AddOptionsPageUIHandler(localized_strings, new HomePageOverlayHandler());
272   AddOptionsPageUIHandler(localized_strings,
273                           new MediaDevicesSelectionHandler());
274   AddOptionsPageUIHandler(localized_strings, new MediaGalleriesHandler());
275 #if defined(OS_CHROMEOS)
276   AddOptionsPageUIHandler(localized_strings,
277                           new chromeos::options::CrosLanguageOptionsHandler());
278 #else
279   AddOptionsPageUIHandler(localized_strings, new LanguageOptionsHandler());
280 #endif
281   AddOptionsPageUIHandler(localized_strings,
282                           new LanguageDictionaryOverlayHandler());
283   AddOptionsPageUIHandler(localized_strings, new ManageProfileHandler());
284   AddOptionsPageUIHandler(localized_strings,
285                           new ManagedUserCreateConfirmHandler());
286   AddOptionsPageUIHandler(localized_strings, new ManagedUserImportHandler());
287   AddOptionsPageUIHandler(localized_strings, new ManagedUserLearnMoreHandler());
288   AddOptionsPageUIHandler(localized_strings, new PasswordManagerHandler());
289   AddOptionsPageUIHandler(localized_strings, new ResetProfileSettingsHandler());
290   AddOptionsPageUIHandler(localized_strings, new SearchEngineManagerHandler());
291   AddOptionsPageUIHandler(localized_strings, new ImportDataHandler());
292   AddOptionsPageUIHandler(localized_strings, new StartupPagesHandler());
293   AddOptionsPageUIHandler(localized_strings, new SyncSetupHandler(
294       g_browser_process->profile_manager()));
295 #if defined(OS_CHROMEOS)
296   AddOptionsPageUIHandler(localized_strings,
297                           new chromeos::options::AccountsOptionsHandler());
298   AddOptionsPageUIHandler(localized_strings,
299                           new chromeos::options::BluetoothOptionsHandler());
300   AddOptionsPageUIHandler(localized_strings,
301                           new chromeos::options::DisplayOptionsHandler());
302   AddOptionsPageUIHandler(localized_strings,
303                           new chromeos::options::DisplayOverscanHandler());
304   AddOptionsPageUIHandler(localized_strings,
305                           new chromeos::options::InternetOptionsHandler());
306   AddOptionsPageUIHandler(localized_strings,
307                           new chromeos::options::KeyboardHandler());
308
309   chromeos::options::PointerHandler* pointer_handler =
310       new chromeos::options::PointerHandler();
311   AddOptionsPageUIHandler(localized_strings, pointer_handler);
312
313   AddOptionsPageUIHandler(localized_strings,
314                           new chromeos::options::ProxyHandler());
315   AddOptionsPageUIHandler(
316       localized_strings,
317       new chromeos::options::ChangePictureOptionsHandler());
318   AddOptionsPageUIHandler(localized_strings,
319                           new chromeos::options::StatsOptionsHandler());
320 #endif
321 #if defined(USE_NSS)
322   AddOptionsPageUIHandler(localized_strings, new CertificateManagerHandler());
323 #endif
324   AddOptionsPageUIHandler(localized_strings, new HandlerOptionsHandler());
325
326   web_ui->AddMessageHandler(new MetricsHandler());
327
328   // |localized_strings| ownership is taken over by this constructor.
329   OptionsUIHTMLSource* html_source =
330       new OptionsUIHTMLSource(localized_strings);
331
332   // Set up the chrome://settings-frame/ source.
333   Profile* profile = Profile::FromWebUI(web_ui);
334   content::URLDataSource::Add(profile, html_source);
335
336   // Set up the chrome://theme/ source.
337   ThemeSource* theme = new ThemeSource(profile);
338   content::URLDataSource::Add(profile, theme);
339
340 #if defined(OS_CHROMEOS)
341   // Set up the chrome://userimage/ source.
342   chromeos::options::UserImageSource* user_image_source =
343       new chromeos::options::UserImageSource();
344   content::URLDataSource::Add(profile, user_image_source);
345
346   pointer_device_observer_.reset(
347       new chromeos::system::PointerDeviceObserver());
348   pointer_device_observer_->AddObserver(browser_options_handler);
349   pointer_device_observer_->AddObserver(pointer_handler);
350 #endif
351 }
352
353 OptionsUI::~OptionsUI() {
354   // Uninitialize all registered handlers. Deleted by WebUIImpl.
355   for (size_t i = 0; i < handlers_.size(); ++i)
356     handlers_[i]->Uninitialize();
357 }
358
359 // static
360 void OptionsUI::ProcessAutocompleteSuggestions(
361     const AutocompleteResult& result,
362     base::ListValue* const suggestions) {
363   for (size_t i = 0; i < result.size(); ++i) {
364     const AutocompleteMatch& match = result.match_at(i);
365     AutocompleteMatchType::Type type = match.type;
366     if (type != AutocompleteMatchType::HISTORY_URL &&
367         type != AutocompleteMatchType::HISTORY_TITLE &&
368         type != AutocompleteMatchType::HISTORY_BODY &&
369         type != AutocompleteMatchType::HISTORY_KEYWORD &&
370         type != AutocompleteMatchType::NAVSUGGEST)
371       continue;
372     base::DictionaryValue* entry = new base::DictionaryValue();
373     entry->SetString("title", match.description);
374     entry->SetString("displayURL", match.contents);
375     entry->SetString("url", match.destination_url.spec());
376     suggestions->Append(entry);
377   }
378 }
379
380 // static
381 base::RefCountedMemory* OptionsUI::GetFaviconResourceBytes(
382       ui::ScaleFactor scale_factor) {
383   return ui::ResourceBundle::GetSharedInstance().
384       LoadDataResourceBytesForScale(IDR_SETTINGS_FAVICON, scale_factor);
385 }
386
387 void OptionsUI::DidStartProvisionalLoadForFrame(
388     int64 frame_id,
389     int64 parent_frame_id,
390     bool is_main_frame,
391     const GURL& validated_url,
392     bool is_error_page,
393     bool is_iframe_srcdoc,
394     content::RenderViewHost* render_view_host) {
395   if (render_view_host == web_ui()->GetWebContents()->GetRenderViewHost() &&
396       validated_url.host() == chrome::kChromeUISettingsFrameHost) {
397     for (size_t i = 0; i < handlers_.size(); ++i)
398       handlers_[i]->PageLoadStarted();
399   }
400 }
401
402 void OptionsUI::InitializeHandlers() {
403   Profile* profile = Profile::FromWebUI(web_ui());
404   DCHECK(!profile->IsOffTheRecord() || profile->IsGuestSession());
405
406   // A new web page DOM has been brought up in an existing renderer, causing
407   // this method to be called twice. If that happens, ignore the second call.
408   if (!initialized_handlers_) {
409     for (size_t i = 0; i < handlers_.size(); ++i)
410       handlers_[i]->InitializeHandler();
411     initialized_handlers_ = true;
412
413 #if defined(OS_CHROMEOS)
414     pointer_device_observer_->Init();
415 #endif
416   }
417
418 #if defined(OS_CHROMEOS)
419   pointer_device_observer_->CheckDevices();
420 #endif
421
422   // Always initialize the page as when handlers are left over we still need to
423   // do various things like show/hide sections and send data to the Javascript.
424   for (size_t i = 0; i < handlers_.size(); ++i)
425     handlers_[i]->InitializePage();
426
427   web_ui()->CallJavascriptFunction(
428       "BrowserOptions.notifyInitializationComplete");
429 }
430
431 void OptionsUI::AddOptionsPageUIHandler(
432     base::DictionaryValue* localized_strings,
433     OptionsPageUIHandler* handler_raw) {
434   scoped_ptr<OptionsPageUIHandler> handler(handler_raw);
435   DCHECK(handler.get());
436   // Add only if handler's service is enabled.
437   if (handler->IsEnabled()) {
438     // Add handler to the list and also pass the ownership.
439     web_ui()->AddMessageHandler(handler.release());
440     handler_raw->GetLocalizedValues(localized_strings);
441     handlers_.push_back(handler_raw);
442   }
443 }
444
445 }  // namespace options