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.
5 #include "chrome/browser/ui/webui/options/options_ui.h"
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/browser_about_handler.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/webui/metrics_handler.h"
25 #include "chrome/browser/ui/webui/options/autofill_options_handler.h"
26 #include "chrome/browser/ui/webui/options/automatic_settings_reset_handler.h"
27 #include "chrome/browser/ui/webui/options/browser_options_handler.h"
28 #include "chrome/browser/ui/webui/options/clear_browser_data_handler.h"
29 #include "chrome/browser/ui/webui/options/content_settings_handler.h"
30 #include "chrome/browser/ui/webui/options/cookies_view_handler.h"
31 #include "chrome/browser/ui/webui/options/core_options_handler.h"
32 #include "chrome/browser/ui/webui/options/create_profile_handler.h"
33 #include "chrome/browser/ui/webui/options/easy_unlock_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/help_overlay_handler.h"
37 #include "chrome/browser/ui/webui/options/home_page_overlay_handler.h"
38 #include "chrome/browser/ui/webui/options/import_data_handler.h"
39 #include "chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h"
40 #include "chrome/browser/ui/webui/options/language_options_handler.h"
41 #include "chrome/browser/ui/webui/options/manage_profile_handler.h"
42 #include "chrome/browser/ui/webui/options/media_devices_selection_handler.h"
43 #include "chrome/browser/ui/webui/options/password_manager_handler.h"
44 #include "chrome/browser/ui/webui/options/reset_profile_settings_handler.h"
45 #include "chrome/browser/ui/webui/options/search_engine_manager_handler.h"
46 #include "chrome/browser/ui/webui/options/startup_pages_handler.h"
47 #include "chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h"
48 #include "chrome/browser/ui/webui/options/supervised_user_import_handler.h"
49 #include "chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h"
50 #include "chrome/browser/ui/webui/options/sync_setup_handler.h"
51 #include "chrome/browser/ui/webui/options/website_settings_handler.h"
52 #include "chrome/browser/ui/webui/theme_source.h"
53 #include "chrome/common/url_constants.h"
54 #include "chrome/grit/generated_resources.h"
55 #include "chrome/grit/locale_settings.h"
56 #include "components/omnibox/autocomplete_match.h"
57 #include "components/omnibox/autocomplete_result.h"
58 #include "content/public/browser/notification_types.h"
59 #include "content/public/browser/render_frame_host.h"
60 #include "content/public/browser/url_data_source.h"
61 #include "content/public/browser/web_contents.h"
62 #include "content/public/browser/web_contents_delegate.h"
63 #include "content/public/browser/web_ui.h"
64 #include "grit/options_resources.h"
65 #include "grit/theme_resources.h"
66 #include "net/base/escape.h"
67 #include "ui/base/l10n/l10n_util.h"
68 #include "ui/base/resource/resource_bundle.h"
69 #include "ui/base/webui/jstemplate_builder.h"
70 #include "ui/base/webui/web_ui_util.h"
73 #if defined(ENABLE_SUPERVISED_USERS)
74 #include "chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h"
75 #include "chrome/browser/ui/webui/options/supervised_user_import_handler.h"
76 #include "chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h"
79 #if defined(OS_CHROMEOS)
80 #include "chrome/browser/browser_process_platform_part.h"
81 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
82 #include "chrome/browser/chromeos/policy/consumer_management_service.h"
83 #include "chrome/browser/chromeos/system/pointer_device_observer.h"
84 #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
85 #include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h"
86 #include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h"
87 #include "chrome/browser/ui/webui/options/chromeos/consumer_management_handler.h"
88 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
89 #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h"
90 #include "chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h"
91 #include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h"
92 #include "chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h"
93 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
94 #include "chrome/browser/ui/webui/options/chromeos/keyboard_handler.h"
95 #include "chrome/browser/ui/webui/options/chromeos/pointer_handler.h"
96 #include "chrome/browser/ui/webui/options/chromeos/power_handler.h"
97 #include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h"
98 #include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h"
99 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
103 #include "chrome/browser/ui/webui/options/certificate_manager_handler.h"
106 #if defined(ENABLE_GOOGLE_NOW)
107 #include "chrome/browser/ui/webui/options/geolocation_options_handler.h"
110 using content::RenderViewHost
;
114 const char kLocalizedStringsFile
[] = "strings.js";
115 const char kOptionsBundleJsFile
[] = "options_bundle.js";
121 ////////////////////////////////////////////////////////////////////////////////
123 // OptionsUIHTMLSource
125 ////////////////////////////////////////////////////////////////////////////////
127 class OptionsUIHTMLSource
: public content::URLDataSource
{
129 // The constructor takes over ownership of |localized_strings|.
130 explicit OptionsUIHTMLSource(base::DictionaryValue
* localized_strings
);
132 // content::URLDataSource implementation.
133 std::string
GetSource() const override
;
134 void StartDataRequest(
135 const std::string
& path
,
136 int render_process_id
,
138 const content::URLDataSource::GotDataCallback
& callback
) override
;
139 std::string
GetMimeType(const std::string
&) const override
;
140 bool ShouldDenyXFrameOptions() const override
;
143 ~OptionsUIHTMLSource() override
;
145 // Localized strings collection.
146 scoped_ptr
<base::DictionaryValue
> localized_strings_
;
148 DISALLOW_COPY_AND_ASSIGN(OptionsUIHTMLSource
);
151 OptionsUIHTMLSource::OptionsUIHTMLSource(
152 base::DictionaryValue
* localized_strings
) {
153 DCHECK(localized_strings
);
154 localized_strings_
.reset(localized_strings
);
157 std::string
OptionsUIHTMLSource::GetSource() const {
158 return chrome::kChromeUISettingsFrameHost
;
161 void OptionsUIHTMLSource::StartDataRequest(
162 const std::string
& path
,
163 int render_process_id
,
165 const content::URLDataSource::GotDataCallback
& callback
) {
166 scoped_refptr
<base::RefCountedMemory
> response_bytes
;
167 const std::string
& app_locale
= g_browser_process
->GetApplicationLocale();
168 webui::SetLoadTimeDataDefaults(app_locale
, localized_strings_
.get());
170 if (path
== kLocalizedStringsFile
) {
171 // Return dynamically-generated strings from memory.
172 std::string strings_js
;
173 webui::AppendJsonJS(localized_strings_
.get(), &strings_js
);
174 response_bytes
= base::RefCountedString::TakeString(&strings_js
);
175 } else if (path
== kOptionsBundleJsFile
) {
176 // Return (and cache) the options javascript code.
177 response_bytes
= ui::ResourceBundle::GetSharedInstance().
178 LoadDataResourceBytes(IDR_OPTIONS_BUNDLE_JS
);
180 // Return (and cache) the main options html page as the default.
181 response_bytes
= ui::ResourceBundle::GetSharedInstance().
182 LoadDataResourceBytes(IDR_OPTIONS_HTML
);
185 callback
.Run(response_bytes
.get());
188 std::string
OptionsUIHTMLSource::GetMimeType(const std::string
& path
) const {
189 if (path
== kLocalizedStringsFile
|| path
== kOptionsBundleJsFile
)
190 return "application/javascript";
195 bool OptionsUIHTMLSource::ShouldDenyXFrameOptions() const {
199 OptionsUIHTMLSource::~OptionsUIHTMLSource() {}
201 ////////////////////////////////////////////////////////////////////////////////
203 // OptionsPageUIHandler
205 ////////////////////////////////////////////////////////////////////////////////
207 const char OptionsPageUIHandler::kSettingsAppKey
[] = "settingsApp";
209 OptionsPageUIHandler::OptionsPageUIHandler() {
212 OptionsPageUIHandler::~OptionsPageUIHandler() {
215 bool OptionsPageUIHandler::IsEnabled() {
220 void OptionsPageUIHandler::RegisterStrings(
221 base::DictionaryValue
* localized_strings
,
222 const OptionsStringResource
* resources
,
224 for (size_t i
= 0; i
< length
; ++i
) {
225 base::string16 value
;
226 if (resources
[i
].substitution_id
== 0) {
227 value
= l10n_util::GetStringUTF16(resources
[i
].id
);
229 value
= l10n_util::GetStringFUTF16(
231 l10n_util::GetStringUTF16(resources
[i
].substitution_id
));
233 localized_strings
->SetString(resources
[i
].name
, value
);
237 void OptionsPageUIHandler::RegisterTitle(
238 base::DictionaryValue
* localized_strings
,
239 const std::string
& variable_name
,
241 localized_strings
->SetString(variable_name
,
242 l10n_util::GetStringUTF16(title_id
));
243 localized_strings
->SetString(variable_name
+ "TabTitle",
244 l10n_util::GetStringFUTF16(IDS_OPTIONS_TAB_TITLE
,
245 l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE
),
246 l10n_util::GetStringUTF16(title_id
)));
249 ////////////////////////////////////////////////////////////////////////////////
253 ////////////////////////////////////////////////////////////////////////////////
255 OptionsUI::OptionsUI(content::WebUI
* web_ui
)
256 : WebUIController(web_ui
),
257 WebContentsObserver(web_ui
->GetWebContents()),
258 initialized_handlers_(false) {
259 base::DictionaryValue
* localized_strings
= new base::DictionaryValue();
260 localized_strings
->Set(OptionsPageUIHandler::kSettingsAppKey
,
261 new base::DictionaryValue());
263 CoreOptionsHandler
* core_handler
;
264 #if defined(OS_CHROMEOS)
265 core_handler
= new chromeos::options::CoreChromeOSOptionsHandler();
267 core_handler
= new CoreOptionsHandler();
269 core_handler
->set_handlers_host(this);
270 AddOptionsPageUIHandler(localized_strings
, core_handler
);
272 AddOptionsPageUIHandler(localized_strings
, new AutofillOptionsHandler());
273 AddOptionsPageUIHandler(localized_strings
,
274 new AutomaticSettingsResetHandler());
276 BrowserOptionsHandler
* browser_options_handler
= new BrowserOptionsHandler();
277 AddOptionsPageUIHandler(localized_strings
, browser_options_handler
);
279 AddOptionsPageUIHandler(localized_strings
, new ClearBrowserDataHandler());
280 AddOptionsPageUIHandler(localized_strings
, new ContentSettingsHandler());
281 AddOptionsPageUIHandler(localized_strings
, new CookiesViewHandler());
282 AddOptionsPageUIHandler(localized_strings
, new CreateProfileHandler());
283 AddOptionsPageUIHandler(localized_strings
, new EasyUnlockHandler());
284 AddOptionsPageUIHandler(localized_strings
, new FontSettingsHandler());
285 #if defined(ENABLE_GOOGLE_NOW)
286 AddOptionsPageUIHandler(localized_strings
, new GeolocationOptionsHandler());
288 AddOptionsPageUIHandler(localized_strings
, new options::HelpOverlayHandler());
289 AddOptionsPageUIHandler(localized_strings
, new HomePageOverlayHandler());
290 AddOptionsPageUIHandler(localized_strings
,
291 new MediaDevicesSelectionHandler());
292 #if defined(OS_CHROMEOS)
293 AddOptionsPageUIHandler(localized_strings
,
294 new chromeos::options::CrosLanguageOptionsHandler());
296 AddOptionsPageUIHandler(localized_strings
, new LanguageOptionsHandler());
298 AddOptionsPageUIHandler(localized_strings
,
299 new LanguageDictionaryOverlayHandler());
300 AddOptionsPageUIHandler(localized_strings
, new ManageProfileHandler());
301 AddOptionsPageUIHandler(localized_strings
, new PasswordManagerHandler());
302 AddOptionsPageUIHandler(localized_strings
, new ResetProfileSettingsHandler());
303 AddOptionsPageUIHandler(localized_strings
, new SearchEngineManagerHandler());
304 AddOptionsPageUIHandler(localized_strings
, new ImportDataHandler());
305 AddOptionsPageUIHandler(localized_strings
, new StartupPagesHandler());
306 #if defined(ENABLE_SUPERVISED_USERS)
307 AddOptionsPageUIHandler(localized_strings
,
308 new SupervisedUserCreateConfirmHandler());
309 AddOptionsPageUIHandler(localized_strings
, new SupervisedUserImportHandler());
310 AddOptionsPageUIHandler(localized_strings
,
311 new SupervisedUserLearnMoreHandler());
313 AddOptionsPageUIHandler(localized_strings
, new SyncSetupHandler(
314 g_browser_process
->profile_manager()));
315 AddOptionsPageUIHandler(localized_strings
, new WebsiteSettingsHandler());
316 #if defined(OS_CHROMEOS)
317 AddOptionsPageUIHandler(localized_strings
,
318 new chromeos::options::AccountsOptionsHandler());
319 AddOptionsPageUIHandler(localized_strings
,
320 new chromeos::options::BluetoothOptionsHandler());
321 AddOptionsPageUIHandler(localized_strings
,
322 new chromeos::options::DateTimeOptionsHandler());
323 AddOptionsPageUIHandler(localized_strings
,
324 new chromeos::options::DisplayOptionsHandler());
325 AddOptionsPageUIHandler(localized_strings
,
326 new chromeos::options::DisplayOverscanHandler());
327 AddOptionsPageUIHandler(localized_strings
,
328 new chromeos::options::PowerHandler());
329 AddOptionsPageUIHandler(localized_strings
,
330 new chromeos::options::InternetOptionsHandler());
331 AddOptionsPageUIHandler(localized_strings
,
332 new chromeos::options::KeyboardHandler());
334 chromeos::options::PointerHandler
* pointer_handler
=
335 new chromeos::options::PointerHandler();
336 AddOptionsPageUIHandler(localized_strings
, pointer_handler
);
338 AddOptionsPageUIHandler(localized_strings
,
339 new chromeos::options::ProxyHandler());
340 AddOptionsPageUIHandler(
342 new chromeos::options::ChangePictureOptionsHandler());
343 AddOptionsPageUIHandler(localized_strings
,
344 new chromeos::options::StatsOptionsHandler());
346 policy::ConsumerManagementService
* consumer_management
=
347 g_browser_process
->platform_part()->browser_policy_connector_chromeos()->
348 GetConsumerManagementService();
349 chromeos::options::ConsumerManagementHandler
* consumer_management_handler
=
350 new chromeos::options::ConsumerManagementHandler(consumer_management
);
351 AddOptionsPageUIHandler(localized_strings
, consumer_management_handler
);
354 AddOptionsPageUIHandler(localized_strings
,
355 new CertificateManagerHandler(false));
357 AddOptionsPageUIHandler(localized_strings
, new HandlerOptionsHandler());
359 web_ui
->AddMessageHandler(new MetricsHandler());
361 // |localized_strings| ownership is taken over by this constructor.
362 OptionsUIHTMLSource
* html_source
=
363 new OptionsUIHTMLSource(localized_strings
);
365 // Set up the chrome://settings-frame/ source.
366 Profile
* profile
= Profile::FromWebUI(web_ui
);
367 content::URLDataSource::Add(profile
, html_source
);
369 // Set up the chrome://theme/ source.
370 ThemeSource
* theme
= new ThemeSource(profile
);
371 content::URLDataSource::Add(profile
, theme
);
373 #if defined(OS_CHROMEOS)
374 // Set up the chrome://userimage/ source.
375 chromeos::options::UserImageSource
* user_image_source
=
376 new chromeos::options::UserImageSource();
377 content::URLDataSource::Add(profile
, user_image_source
);
379 pointer_device_observer_
.reset(
380 new chromeos::system::PointerDeviceObserver());
381 pointer_device_observer_
->AddObserver(browser_options_handler
);
382 pointer_device_observer_
->AddObserver(pointer_handler
);
386 OptionsUI::~OptionsUI() {
387 // Uninitialize all registered handlers. Deleted by WebUIImpl.
388 for (size_t i
= 0; i
< handlers_
.size(); ++i
)
389 handlers_
[i
]->Uninitialize();
392 scoped_ptr
<OptionsUI::OnFinishedLoadingCallbackList::Subscription
>
393 OptionsUI::RegisterOnFinishedLoadingCallback(const base::Closure
& callback
) {
394 return on_finished_loading_callbacks_
.Add(callback
);
398 void OptionsUI::ProcessAutocompleteSuggestions(
399 const AutocompleteResult
& result
,
400 base::ListValue
* const suggestions
) {
401 for (size_t i
= 0; i
< result
.size(); ++i
) {
402 const AutocompleteMatch
& match
= result
.match_at(i
);
403 AutocompleteMatchType::Type type
= match
.type
;
404 if (type
!= AutocompleteMatchType::HISTORY_URL
&&
405 type
!= AutocompleteMatchType::HISTORY_TITLE
&&
406 type
!= AutocompleteMatchType::HISTORY_BODY
&&
407 type
!= AutocompleteMatchType::HISTORY_KEYWORD
&&
408 type
!= AutocompleteMatchType::NAVSUGGEST
&&
409 type
!= AutocompleteMatchType::NAVSUGGEST_PERSONALIZED
) {
412 base::DictionaryValue
* entry
= new base::DictionaryValue();
413 entry
->SetString("title", match
.description
);
414 entry
->SetString("displayURL", match
.contents
);
415 entry
->SetString("url", match
.destination_url
.spec());
416 suggestions
->Append(entry
);
421 base::RefCountedMemory
* OptionsUI::GetFaviconResourceBytes(
422 ui::ScaleFactor scale_factor
) {
423 return ui::ResourceBundle::GetSharedInstance().
424 LoadDataResourceBytesForScale(IDR_SETTINGS_FAVICON
, scale_factor
);
427 void OptionsUI::DidStartProvisionalLoadForFrame(
428 content::RenderFrameHost
* render_frame_host
,
429 const GURL
& validated_url
,
431 bool is_iframe_srcdoc
) {
432 if (render_frame_host
->GetRenderViewHost() ==
433 web_ui()->GetWebContents()->GetRenderViewHost() &&
434 validated_url
.host() == chrome::kChromeUISettingsFrameHost
) {
435 for (size_t i
= 0; i
< handlers_
.size(); ++i
)
436 handlers_
[i
]->PageLoadStarted();
440 void OptionsUI::InitializeHandlers() {
441 Profile
* profile
= Profile::FromWebUI(web_ui());
442 DCHECK(!profile
->IsOffTheRecord() || profile
->IsGuestSession());
444 // A new web page DOM has been brought up in an existing renderer, causing
445 // this method to be called twice. If that happens, ignore the second call.
446 if (!initialized_handlers_
) {
447 for (size_t i
= 0; i
< handlers_
.size(); ++i
)
448 handlers_
[i
]->InitializeHandler();
449 initialized_handlers_
= true;
451 #if defined(OS_CHROMEOS)
452 pointer_device_observer_
->Init();
456 #if defined(OS_CHROMEOS)
457 pointer_device_observer_
->CheckDevices();
460 // Always initialize the page as when handlers are left over we still need to
461 // do various things like show/hide sections and send data to the Javascript.
462 for (size_t i
= 0; i
< handlers_
.size(); ++i
)
463 handlers_
[i
]->InitializePage();
465 web_ui()->CallJavascriptFunction(
466 "BrowserOptions.notifyInitializationComplete");
469 void OptionsUI::OnFinishedLoading() {
470 on_finished_loading_callbacks_
.Notify();
473 void OptionsUI::AddOptionsPageUIHandler(
474 base::DictionaryValue
* localized_strings
,
475 OptionsPageUIHandler
* handler_raw
) {
476 scoped_ptr
<OptionsPageUIHandler
> handler(handler_raw
);
477 DCHECK(handler
.get());
478 // Add only if handler's service is enabled.
479 if (handler
->IsEnabled()) {
480 // Add handler to the list and also pass the ownership.
481 web_ui()->AddMessageHandler(handler
.release());
482 handler_raw
->GetLocalizedValues(localized_strings
);
483 handlers_
.push_back(handler_raw
);
487 } // namespace options