Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chrome_web_ui_controller_factory.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/chrome_web_ui_controller_factory.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/location.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/about_flags.h"
13 #include "chrome/browser/bookmarks/enhanced_bookmarks_features.h"
14 #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
15 #include "chrome/browser/extensions/extension_web_ui.h"
16 #include "chrome/browser/history/history_types.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/ui/webui/about_ui.h"
20 #include "chrome/browser/ui/webui/app_launcher_page_ui.h"
21 #include "chrome/browser/ui/webui/bookmarks_ui.h"
22 #include "chrome/browser/ui/webui/components_ui.h"
23 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
24 #include "chrome/browser/ui/webui/crashes_ui.h"
25 #include "chrome/browser/ui/webui/devtools_ui.h"
26 #include "chrome/browser/ui/webui/downloads_ui.h"
27 #include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
28 #include "chrome/browser/ui/webui/extensions/extensions_ui.h"
29 #include "chrome/browser/ui/webui/flags_ui.h"
30 #include "chrome/browser/ui/webui/flash_ui.h"
31 #include "chrome/browser/ui/webui/gcm_internals_ui.h"
32 #include "chrome/browser/ui/webui/help/help_ui.h"
33 #include "chrome/browser/ui/webui/history_ui.h"
34 #include "chrome/browser/ui/webui/identity_internals_ui.h"
35 #include "chrome/browser/ui/webui/inspect_ui.h"
36 #include "chrome/browser/ui/webui/instant_ui.h"
37 #include "chrome/browser/ui/webui/invalidations_ui.h"
38 #include "chrome/browser/ui/webui/memory_internals/memory_internals_ui.h"
39 #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
40 #include "chrome/browser/ui/webui/omnibox/omnibox_ui.h"
41 #include "chrome/browser/ui/webui/options/options_ui.h"
42 #include "chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h"
43 #include "chrome/browser/ui/webui/performance_monitor/performance_monitor_ui.h"
44 #include "chrome/browser/ui/webui/plugins_ui.h"
45 #include "chrome/browser/ui/webui/predictors/predictors_ui.h"
46 #include "chrome/browser/ui/webui/profiler_ui.h"
47 #include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
48 #include "chrome/browser/ui/webui/signin/inline_login_ui.h"
49 #include "chrome/browser/ui/webui/signin/profile_signin_confirmation_ui.h"
50 #include "chrome/browser/ui/webui/signin/user_manager_ui.h"
51 #include "chrome/browser/ui/webui/signin_internals_ui.h"
52 #include "chrome/browser/ui/webui/sync_internals_ui.h"
53 #include "chrome/browser/ui/webui/translate_internals/translate_internals_ui.h"
54 #include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
55 #include "chrome/browser/ui/webui/version_ui.h"
56 #include "chrome/common/chrome_switches.h"
57 #include "chrome/common/extensions/extension_constants.h"
58 #include "chrome/common/pref_names.h"
59 #include "chrome/common/url_constants.h"
60 #include "components/dom_distiller/core/dom_distiller_constants.h"
61 #include "components/dom_distiller/core/dom_distiller_service.h"
62 #include "components/dom_distiller/webui/dom_distiller_ui.h"
63 #include "components/password_manager/core/common/password_manager_switches.h"
64 #include "components/signin/core/common/profile_management_switches.h"
65 #include "content/public/browser/web_contents.h"
66 #include "content/public/browser/web_ui.h"
67 #include "content/public/common/content_client.h"
68 #include "content/public/common/url_utils.h"
69 #include "extensions/browser/extension_registry.h"
70 #include "extensions/browser/extension_system.h"
71 #include "extensions/common/constants.h"
72 #include "extensions/common/extension.h"
73 #include "extensions/common/feature_switch.h"
74 #include "extensions/common/manifest.h"
75 #include "ui/gfx/favicon_size.h"
76 #include "ui/web_dialogs/web_dialog_ui.h"
77 #include "url/gurl.h"
78
79 #if !defined(DISABLE_NACL)
80 #include "chrome/browser/ui/webui/nacl_ui.h"
81 #endif
82
83 #if defined(ENABLE_CONFIGURATION_POLICY)
84 #include "chrome/browser/ui/webui/policy_ui.h"
85 #endif
86
87 #if defined(ENABLE_WEBRTC)
88 #include "chrome/browser/ui/webui/media/webrtc_logs_ui.h"
89 #endif
90
91 #if defined(ENABLE_FULL_PRINTING)
92 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
93 #endif
94
95 #if defined(OS_ANDROID)
96 #include "chrome/browser/ui/webui/welcome_ui_android.h"
97 #else
98 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
99 #include "chrome/browser/ui/webui/suggestions_internals/suggestions_internals_ui.h"
100 #include "chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_ui.h"
101 #include "chrome/browser/ui/webui/system_info_ui.h"
102 #include "chrome/browser/ui/webui/uber/uber_ui.h"
103 #endif
104
105 #if defined(OS_ANDROID) || defined(OS_IOS)
106 #include "chrome/browser/ui/webui/net_export_ui.h"
107 #endif
108
109 #if defined(OS_CHROMEOS)
110 #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_ui.h"
111 #include "chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.h"
112 #include "chrome/browser/ui/webui/chromeos/charger_replacement_ui.h"
113 #include "chrome/browser/ui/webui/chromeos/choose_mobile_network_ui.h"
114 #include "chrome/browser/ui/webui/chromeos/cryptohome_ui.h"
115 #include "chrome/browser/ui/webui/chromeos/drive_internals_ui.h"
116 #include "chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h"
117 #include "chrome/browser/ui/webui/chromeos/imageburner/imageburner_ui.h"
118 #include "chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.h"
119 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
120 #include "chrome/browser/ui/webui/chromeos/mobile_setup_ui.h"
121 #include "chrome/browser/ui/webui/chromeos/network_ui.h"
122 #include "chrome/browser/ui/webui/chromeos/nfc_debug_ui.h"
123 #include "chrome/browser/ui/webui/chromeos/power_ui.h"
124 #include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h"
125 #include "chrome/browser/ui/webui/chromeos/salsa_ui.h"
126 #include "chrome/browser/ui/webui/chromeos/set_time_ui.h"
127 #include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h"
128 #include "chrome/browser/ui/webui/chromeos/slow_trace_ui.h"
129 #include "chrome/browser/ui/webui/chromeos/slow_ui.h"
130 #endif
131
132 #if defined(USE_AURA)
133 #include "chrome/browser/ui/webui/gesture_config_ui.h"
134 #endif
135
136 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
137 #include "chrome/browser/ui/sync/sync_promo_ui.h"
138 #endif
139
140 #if defined(OS_WIN)
141 #include "chrome/browser/ui/webui/conflicts_ui.h"
142 #include "chrome/browser/ui/webui/set_as_default_browser_ui.h"
143 #endif
144
145 #if (defined(USE_NSS) || defined(USE_OPENSSL)) && defined(USE_AURA)
146 #include "chrome/browser/ui/webui/certificate_viewer_ui.h"
147 #endif
148
149 #if defined(ENABLE_SERVICE_DISCOVERY)
150 #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui.h"
151 #endif
152
153 #if defined(ENABLE_APP_LIST)
154 #include "chrome/browser/ui/webui/app_list/start_page_ui.h"
155 #endif
156
157 using content::WebUI;
158 using content::WebUIController;
159 using ui::ExternalWebDialogUI;
160 using ui::WebDialogUI;
161
162 namespace {
163
164 // A function for creating a new WebUI. The caller owns the return value, which
165 // may be NULL (for example, if the URL refers to an non-existent extension).
166 typedef WebUIController* (*WebUIFactoryFunction)(WebUI* web_ui,
167                                                  const GURL& url);
168
169 // Template for defining WebUIFactoryFunction.
170 template<class T>
171 WebUIController* NewWebUI(WebUI* web_ui, const GURL& url) {
172   return new T(web_ui);
173 }
174
175 #if defined(ENABLE_EXTENSIONS)
176 // Special cases for extensions.
177 template<>
178 WebUIController* NewWebUI<ExtensionWebUI>(WebUI* web_ui,
179                                           const GURL& url) {
180   return new ExtensionWebUI(web_ui, url);
181 }
182 #endif  // defined(ENABLE_EXTENSIONS)
183
184 // Special case for older about: handlers.
185 template<>
186 WebUIController* NewWebUI<AboutUI>(WebUI* web_ui, const GURL& url) {
187   return new AboutUI(web_ui, url.host());
188 }
189
190 #if defined(OS_CHROMEOS)
191 template<>
192 WebUIController* NewWebUI<chromeos::OobeUI>(WebUI* web_ui, const GURL& url) {
193   return new chromeos::OobeUI(web_ui, url);
194 }
195 #endif
196
197 // Special cases for DOM distiller.
198 template<>
199 WebUIController* NewWebUI<dom_distiller::DomDistillerUi>(WebUI* web_ui,
200                                                          const GURL& url) {
201   // The DomDistillerUi can not depend on components/dom_distiller/content,
202   // so inject the correct DomDistillerService from chrome/.
203   content::BrowserContext* browser_context =
204       web_ui->GetWebContents()->GetBrowserContext();
205   dom_distiller::DomDistillerService* service =
206       dom_distiller::DomDistillerServiceFactory::GetForBrowserContext(
207           browser_context);
208   return new dom_distiller::DomDistillerUi(web_ui,
209                                            service,
210                                            chrome::kDomDistillerScheme);
211 }
212
213 // Only create ExtensionWebUI for URLs that are allowed extension bindings,
214 // hosted by actual tabs.
215 bool NeedsExtensionWebUI(Profile* profile, const GURL& url) {
216   if (!profile)
217     return false;
218
219   const extensions::Extension* extension =
220       extensions::ExtensionRegistry::Get(profile)->enabled_extensions().
221           GetExtensionOrAppByURL(url);
222   // Allow bindings for all packaged extensions and component hosted apps.
223   return extension &&
224       (!extension->is_hosted_app() ||
225        extension->location() == extensions::Manifest::COMPONENT);
226 }
227
228 // Returns a function that can be used to create the right type of WebUI for a
229 // tab, based on its URL. Returns NULL if the URL doesn't have WebUI associated
230 // with it.
231 WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
232                                              Profile* profile,
233                                              const GURL& url) {
234 #if defined(ENABLE_EXTENSIONS)
235   if (NeedsExtensionWebUI(profile, url))
236     return &NewWebUI<ExtensionWebUI>;
237 #endif
238
239   // This will get called a lot to check all URLs, so do a quick check of other
240   // schemes to filter out most URLs.
241   if (!url.SchemeIs(content::kChromeDevToolsScheme) &&
242       !url.SchemeIs(content::kChromeUIScheme)) {
243     return NULL;
244   }
245
246   /****************************************************************************
247    * Please keep this in alphabetical order. If #ifs or special logics are
248    * required, add it below in the appropriate section.
249    ***************************************************************************/
250   // We must compare hosts only since some of the Web UIs append extra stuff
251   // after the host name.
252   // All platform builds of Chrome will need to have a cloud printing
253   // dialog as backup.  It's just that on Chrome OS, it's the only
254   // print dialog.
255   if (url.host() == chrome::kChromeUICloudPrintResourcesHost)
256     return &NewWebUI<ExternalWebDialogUI>;
257   if (url.host() == chrome::kChromeUICloudPrintSetupHost)
258     return &NewWebUI<WebDialogUI>;
259   if (url.host() == chrome::kChromeUIComponentsHost)
260     return &NewWebUI<ComponentsUI>;
261   if (url.spec() == chrome::kChromeUIConstrainedHTMLTestURL)
262     return &NewWebUI<ConstrainedWebDialogUI>;
263   if (url.host() == chrome::kChromeUICrashesHost)
264     return &NewWebUI<CrashesUI>;
265 #if defined(ENABLE_SERVICE_DISCOVERY)
266   if (url.host() == chrome::kChromeUIDevicesHost &&
267       !CommandLine::ForCurrentProcess()->HasSwitch(
268            switches::kDisableDeviceDiscovery)) {
269     return &NewWebUI<LocalDiscoveryUI>;
270   }
271 #endif
272   if (url.host() == chrome::kChromeUIFlagsHost)
273     return &NewWebUI<FlagsUI>;
274   if (url.host() == chrome::kChromeUIHistoryFrameHost)
275     return &NewWebUI<HistoryUI>;
276   if (url.host() == chrome::kChromeUIInstantHost)
277     return &NewWebUI<InstantUI>;
278   if (url.host() == chrome::kChromeUIInvalidationsHost)
279     return &NewWebUI<InvalidationsUI>;
280   if (url.host() == chrome::kChromeUIManagedUserPassphrasePageHost)
281     return &NewWebUI<ConstrainedWebDialogUI>;
282   if (url.host() == chrome::kChromeUIMemoryInternalsHost)
283     return &NewWebUI<MemoryInternalsUI>;
284 #if !defined(DISABLE_NACL)
285   if (url.host() == chrome::kChromeUINaClHost)
286     return &NewWebUI<NaClUI>;
287 #endif
288 #if defined(OS_ANDROID) || defined(OS_IOS)
289   if (url.host() == chrome::kChromeUINetExportHost)
290     return &NewWebUI<NetExportUI>;
291 #endif
292   if (url.host() == chrome::kChromeUINetInternalsHost)
293     return &NewWebUI<NetInternalsUI>;
294 #if !defined(OS_ANDROID)
295   if (url.host() == chrome::kChromeUINewTabHost)
296     return &NewWebUI<NewTabUI>;
297 #endif
298   if (url.host() == chrome::kChromeUIOmniboxHost)
299     return &NewWebUI<OmniboxUI>;
300   if (url.host() == chrome::kChromeUIPasswordManagerInternalsHost &&
301       CommandLine::ForCurrentProcess()->HasSwitch(
302           password_manager::switches::kEnablePasswordManagerInternalsUI)) {
303     return &NewWebUI<PasswordManagerInternalsUI>;
304   }
305   if (url.host() == chrome::kChromeUIPredictorsHost)
306     return &NewWebUI<PredictorsUI>;
307   if (url.host() == chrome::kChromeUIProfilerHost)
308     return &NewWebUI<ProfilerUI>;
309   if (url.host() == chrome::kChromeUIQuotaInternalsHost)
310     return &NewWebUI<QuotaInternalsUI>;
311   if (url.host() == chrome::kChromeUISignInInternalsHost)
312     return &NewWebUI<SignInInternalsUI>;
313   if (url.host() == chrome::kChromeUISyncInternalsHost)
314     return &NewWebUI<SyncInternalsUI>;
315   if (url.host() == chrome::kChromeUISyncResourcesHost)
316     return &NewWebUI<WebDialogUI>;
317   if (url.host() == chrome::kChromeUITranslateInternalsHost)
318     return &NewWebUI<TranslateInternalsUI>;
319   if (url.host() == chrome::kChromeUIUserActionsHost)
320     return &NewWebUI<UserActionsUI>;
321   if (url.host() == chrome::kChromeUIVersionHost)
322     return &NewWebUI<VersionUI>;
323 #if defined(ENABLE_WEBRTC)
324   if (url.host() == chrome::kChromeUIWebRtcLogsHost)
325     return &NewWebUI<WebRtcLogsUI>;
326 #endif
327 #if defined(ENABLE_APP_LIST)
328   if (url.host() == chrome::kChromeUIAppListStartPageHost)
329     return &NewWebUI<app_list::StartPageUI>;
330 #endif
331
332   /****************************************************************************
333    * OS Specific #defines
334    ***************************************************************************/
335 #if defined(OS_ANDROID)
336   if (url.host() == chrome::kChromeUIWelcomeHost)
337     return &NewWebUI<WelcomeUI>;
338 #else
339   // AppLauncherPage is not needed on Android.
340   if (url.host() == chrome::kChromeUIAppLauncherPageHost &&
341       profile && extensions::ExtensionSystem::Get(profile)->
342           extension_service()) {
343     return &NewWebUI<AppLauncherPageUI>;
344   }
345   // Bookmarks are part of NTP on Android.
346   if (url.host() == chrome::kChromeUIBookmarksHost)
347     return &NewWebUI<BookmarksUI>;
348   if (url.SchemeIs(content::kChromeDevToolsScheme))
349     return &NewWebUI<DevToolsUI>;
350   // Downloads list on Android uses the built-in download manager.
351   if (url.host() == chrome::kChromeUIDownloadsHost)
352     return &NewWebUI<DownloadsUI>;
353   // Flash is not available on android.
354   if (url.host() == chrome::kChromeUIFlashHost)
355     return &NewWebUI<FlashUI>;
356   if (url.host() == chrome::kChromeUIGCMInternalsHost)
357     return &NewWebUI<GCMInternalsUI>;
358   // Help is implemented with native UI elements on Android.
359   if (url.host() == chrome::kChromeUIHelpFrameHost)
360     return &NewWebUI<HelpUI>;
361   // Identity API is not available on Android.
362   if (url.host() == chrome::kChromeUIIdentityInternalsHost)
363     return &NewWebUI<IdentityInternalsUI>;
364   // chrome://inspect isn't supported on Android. Page debugging is handled by a
365   // remote devtools on the host machine, and other elements (Shared Workers,
366   // extensions, etc) aren't supported.
367   if (url.host() == chrome::kChromeUIInspectHost)
368     return &NewWebUI<InspectUI>;
369   // Performance monitoring page is not on Android for now.
370   if (url.host() == chrome::kChromeUIPerformanceMonitorHost)
371     return &NewWebUI<performance_monitor::PerformanceMonitorUI>;
372   // Android does not support plugins for now.
373   if (url.host() == chrome::kChromeUIPluginsHost)
374     return &NewWebUI<PluginsUI>;
375   // Settings are implemented with native UI elements on Android.
376   if (url.host() == chrome::kChromeUISettingsFrameHost)
377     return &NewWebUI<options::OptionsUI>;
378   if (url.host() == chrome::kChromeUISuggestionsInternalsHost)
379     return &NewWebUI<SuggestionsInternalsUI>;
380   if (url.host() == chrome::kChromeUISyncFileSystemInternalsHost)
381     return &NewWebUI<SyncFileSystemInternalsUI>;
382   if (url.host() == chrome::kChromeUISystemInfoHost)
383     return &NewWebUI<SystemInfoUI>;
384   // Uber frame is not used on Android.
385   if (url.host() == chrome::kChromeUIUberFrameHost)
386     return &NewWebUI<UberFrameUI>;
387   // Uber page is not used on Android.
388   if (url.host() == chrome::kChromeUIUberHost)
389     return &NewWebUI<UberUI>;
390 #endif
391 #if defined(OS_WIN)
392   if (url.host() == chrome::kChromeUIConflictsHost)
393     return &NewWebUI<ConflictsUI>;
394   if (url.host() == chrome::kChromeUIMetroFlowHost)
395     return &NewWebUI<SetAsDefaultBrowserUI>;
396 #endif
397 #if (defined(USE_NSS) || defined(USE_OPENSSL)) && defined(USE_AURA)
398   if (url.host() == chrome::kChromeUICertificateViewerHost)
399     return &NewWebUI<CertificateViewerUI>;
400 #if defined(OS_CHROMEOS)
401   if (url.host() == chrome::kChromeUICertificateViewerDialogHost)
402     return &NewWebUI<CertificateViewerModalDialogUI>;
403 #endif
404 #endif
405 #if defined(OS_CHROMEOS)
406   if (url.host() == chrome::kChromeUIBluetoothPairingHost)
407     return &NewWebUI<chromeos::BluetoothPairingUI>;
408   if (url.host() == chrome::kChromeUICertificateManagerHost)
409     return &NewWebUI<chromeos::CertificateManagerDialogUI>;
410   if (url.host() == chrome::kChromeUIChargerReplacementHost)
411     return &NewWebUI<chromeos::ChargerReplacementUI>;
412   if (url.host() == chrome::kChromeUIChooseMobileNetworkHost)
413     return &NewWebUI<chromeos::ChooseMobileNetworkUI>;
414   if (url.host() == chrome::kChromeUICryptohomeHost)
415     return &NewWebUI<chromeos::CryptohomeUI>;
416   if (url.host() == chrome::kChromeUIDriveInternalsHost)
417     return &NewWebUI<chromeos::DriveInternalsUI>;
418   if (url.host() == chrome::kChromeUIFirstRunHost)
419     return &NewWebUI<chromeos::FirstRunUI>;
420   if (url.host() == chrome::kChromeUIImageBurnerHost)
421     return &NewWebUI<ImageBurnUI>;
422   if (url.host() == chrome::kChromeUIKeyboardOverlayHost)
423     return &NewWebUI<KeyboardOverlayUI>;
424   if (url.host() == chrome::kChromeUIMobileSetupHost)
425     return &NewWebUI<MobileSetupUI>;
426   if (url.host() == chrome::kChromeUINfcDebugHost)
427     return &NewWebUI<chromeos::NfcDebugUI>;
428   if (url.host() == chrome::kChromeUIOobeHost)
429     return &NewWebUI<chromeos::OobeUI>;
430   if (url.host() == chrome::kChromeUIProxySettingsHost)
431     return &NewWebUI<chromeos::ProxySettingsUI>;
432   if (url.host() == chrome::kChromeUISalsaHost)
433     return &NewWebUI<SalsaUI>;
434   if (url.host() == chrome::kChromeUISetTimeHost)
435     return &NewWebUI<chromeos::SetTimeUI>;
436   if (url.host() == chrome::kChromeUISimUnlockHost)
437     return &NewWebUI<chromeos::SimUnlockUI>;
438   if (url.host() == chrome::kChromeUISlowHost)
439     return &NewWebUI<chromeos::SlowUI>;
440   if (url.host() == chrome::kChromeUISlowTraceHost)
441     return &NewWebUI<chromeos::SlowTraceController>;
442   if (url.host() == chrome::kChromeUINetworkHost)
443     return &NewWebUI<chromeos::NetworkUI>;
444   if (url.host() == chrome::kChromeUIPowerHost)
445     return &NewWebUI<chromeos::PowerUI>;
446 #endif  // defined(OS_CHROMEOS)
447 #if !defined(OS_ANDROID) && !defined(OS_IOS)
448   if (url.host() == chrome::kChromeUIChromeSigninHost)
449     return &NewWebUI<InlineLoginUI>;
450 #endif
451
452   /****************************************************************************
453    * Other #defines and special logics.
454    ***************************************************************************/
455 #if defined(ENABLE_CONFIGURATION_POLICY)
456   if (url.host() == chrome::kChromeUIPolicyHost)
457     return &NewWebUI<PolicyUI>;
458
459 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
460   if (url.host() == chrome::kChromeUIProfileSigninConfirmationHost)
461     return &NewWebUI<ProfileSigninConfirmationUI>;
462 #endif
463
464 #endif  // defined(ENABLE_CONFIGURATION_POLICY)
465
466 #if (defined(OS_LINUX) && defined(TOOLKIT_VIEWS)) || defined(USE_AURA)
467   if (url.host() == chrome::kChromeUITabModalConfirmDialogHost) {
468     return &NewWebUI<ConstrainedWebDialogUI>;
469   }
470 #endif
471
472 #if defined(USE_AURA)
473   if (url.host() == chrome::kChromeUIGestureConfigHost)
474     return &NewWebUI<GestureConfigUI>;
475 #endif
476
477 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS)
478   if (url.host() == chrome::kChromeUIUserManagerHost &&
479       switches::IsNewProfileManagement()) {
480     return &NewWebUI<UserManagerUI>;
481   }
482 #endif
483
484   if (url.host() == chrome::kChromeUIChromeURLsHost ||
485       url.host() == chrome::kChromeUICreditsHost ||
486       url.host() == chrome::kChromeUIDNSHost ||
487       url.host() == chrome::kChromeUIMemoryHost ||
488       url.host() == chrome::kChromeUIMemoryRedirectHost ||
489       url.host() == chrome::kChromeUIStatsHost ||
490       url.host() == chrome::kChromeUITermsHost
491 #if defined(OS_LINUX) || defined(OS_OPENBSD)
492       || url.host() == chrome::kChromeUILinuxProxyConfigHost
493       || url.host() == chrome::kChromeUISandboxHost
494 #endif
495 #if defined(OS_CHROMEOS)
496       || url.host() == chrome::kChromeUIDiscardsHost
497       || url.host() == chrome::kChromeUIOSCreditsHost
498 #endif
499 #if defined(WEBUI_TASK_MANAGER)
500       || url.host() == chrome::kChromeUITaskManagerHost
501 #endif
502       ) {
503     return &NewWebUI<AboutUI>;
504   }
505
506 #if defined(ENABLE_EXTENSIONS)
507   if (url.host() == chrome::kChromeUIExtensionsFrameHost)
508     return &NewWebUI<extensions::ExtensionsUI>;
509 #endif
510 #if defined(ENABLE_FULL_PRINTING)
511   if (url.host() == chrome::kChromeUIPrintHost &&
512       !profile->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled))
513     return &NewWebUI<PrintPreviewUI>;
514 #endif
515
516   if (IsEnableDomDistillerSet() &&
517       url.host() == dom_distiller::kChromeUIDomDistillerHost) {
518     return &NewWebUI<dom_distiller::DomDistillerUi>;
519   }
520
521   return NULL;
522 }
523
524 void RunFaviconCallbackAsync(
525     const FaviconService::FaviconResultsCallback& callback,
526     const std::vector<favicon_base::FaviconBitmapResult>* results) {
527   base::MessageLoopProxy::current()->PostTask(
528       FROM_HERE,
529       base::Bind(&FaviconService::FaviconResultsCallbackRunner,
530                  callback, base::Owned(results)));
531 }
532
533 }  // namespace
534
535 WebUI::TypeID ChromeWebUIControllerFactory::GetWebUIType(
536       content::BrowserContext* browser_context, const GURL& url) const {
537   Profile* profile = Profile::FromBrowserContext(browser_context);
538   WebUIFactoryFunction function = GetWebUIFactoryFunction(NULL, profile, url);
539   return function ? reinterpret_cast<WebUI::TypeID>(function) : WebUI::kNoWebUI;
540 }
541
542 bool ChromeWebUIControllerFactory::UseWebUIForURL(
543     content::BrowserContext* browser_context, const GURL& url) const {
544   return GetWebUIType(browser_context, url) != WebUI::kNoWebUI;
545 }
546
547 bool ChromeWebUIControllerFactory::UseWebUIBindingsForURL(
548     content::BrowserContext* browser_context, const GURL& url) const {
549   // Extensions are rendered via WebUI in tabs, but don't actually need WebUI
550   // bindings (see the ExtensionWebUI constructor).
551   return
552       !NeedsExtensionWebUI(Profile::FromBrowserContext(browser_context), url) &&
553       UseWebUIForURL(browser_context, url);
554 }
555
556 WebUIController* ChromeWebUIControllerFactory::CreateWebUIControllerForURL(
557     WebUI* web_ui,
558     const GURL& url) const {
559   Profile* profile = Profile::FromWebUI(web_ui);
560   WebUIFactoryFunction function = GetWebUIFactoryFunction(web_ui, profile, url);
561   if (!function)
562     return NULL;
563
564   return (*function)(web_ui, url);
565 }
566
567 void ChromeWebUIControllerFactory::GetFaviconForURL(
568     Profile* profile,
569     const GURL& page_url,
570     const std::vector<ui::ScaleFactor>& scale_factors,
571     const FaviconService::FaviconResultsCallback& callback) const {
572   // Before determining whether page_url is an extension url, we must handle
573   // overrides. This changes urls in |kChromeUIScheme| to extension urls, and
574   // allows to use ExtensionWebUI::GetFaviconForURL.
575   GURL url(page_url);
576   ExtensionWebUI::HandleChromeURLOverride(&url, profile);
577
578   // All extensions but the bookmark manager get their favicon from the icons
579   // part of the manifest.
580   if (url.SchemeIs(extensions::kExtensionScheme) &&
581       url.host() != extension_misc::kBookmarkManagerId) {
582 #if defined(ENABLE_EXTENSIONS)
583     ExtensionWebUI::GetFaviconForURL(profile, url, callback);
584 #else
585     RunFaviconCallbackAsync(
586         callback, new std::vector<favicon_base::FaviconBitmapResult>());
587 #endif
588     return;
589   }
590
591   std::vector<favicon_base::FaviconBitmapResult>* favicon_bitmap_results =
592       new std::vector<favicon_base::FaviconBitmapResult>();
593
594   for (size_t i = 0; i < scale_factors.size(); ++i) {
595     scoped_refptr<base::RefCountedMemory> bitmap(GetFaviconResourceBytes(
596           url, scale_factors[i]));
597     if (bitmap.get() && bitmap->size()) {
598       favicon_base::FaviconBitmapResult bitmap_result;
599       bitmap_result.bitmap_data = bitmap;
600       // Leave |bitmap_result|'s icon URL as the default of GURL().
601       bitmap_result.icon_type = favicon_base::FAVICON;
602       favicon_bitmap_results->push_back(bitmap_result);
603
604       // Assume that |bitmap| is |gfx::kFaviconSize| x |gfx::kFaviconSize|
605       // DIP.
606       float scale = ui::GetImageScale(scale_factors[i]);
607       int edge_pixel_size =
608           static_cast<int>(gfx::kFaviconSize * scale + 0.5f);
609       bitmap_result.pixel_size = gfx::Size(edge_pixel_size, edge_pixel_size);
610     }
611   }
612
613   RunFaviconCallbackAsync(callback, favicon_bitmap_results);
614 }
615
616 // static
617 ChromeWebUIControllerFactory* ChromeWebUIControllerFactory::GetInstance() {
618   return Singleton<ChromeWebUIControllerFactory>::get();
619 }
620
621 ChromeWebUIControllerFactory::ChromeWebUIControllerFactory() {
622 }
623
624 ChromeWebUIControllerFactory::~ChromeWebUIControllerFactory() {
625 }
626
627 base::RefCountedMemory* ChromeWebUIControllerFactory::GetFaviconResourceBytes(
628     const GURL& page_url, ui::ScaleFactor scale_factor) const {
629 #if !defined(OS_ANDROID)  // Bookmarks are part of NTP on Android.
630   // The bookmark manager is a chrome extension, so we have to check for it
631   // before we check for extension scheme.
632   if (page_url.host() == extension_misc::kBookmarkManagerId)
633     return BookmarksUI::GetFaviconResourceBytes(scale_factor);
634
635   // The extension scheme is handled in GetFaviconForURL.
636   if (page_url.SchemeIs(extensions::kExtensionScheme)) {
637     NOTREACHED();
638     return NULL;
639   }
640 #endif
641
642   if (!content::HasWebUIScheme(page_url))
643     return NULL;
644
645   if (page_url.host() == chrome::kChromeUIComponentsHost)
646     return ComponentsUI::GetFaviconResourceBytes(scale_factor);
647
648 #if defined(OS_WIN)
649   if (page_url.host() == chrome::kChromeUIConflictsHost)
650     return ConflictsUI::GetFaviconResourceBytes(scale_factor);
651 #endif
652
653   if (page_url.host() == chrome::kChromeUICrashesHost)
654     return CrashesUI::GetFaviconResourceBytes(scale_factor);
655
656   if (page_url.host() == chrome::kChromeUIFlagsHost)
657     return FlagsUI::GetFaviconResourceBytes(scale_factor);
658
659   if (page_url.host() == chrome::kChromeUIHistoryHost)
660     return HistoryUI::GetFaviconResourceBytes(scale_factor);
661
662 #if !defined(OS_ANDROID)
663   // The Apps launcher page is not available on android.
664   if (page_url.host() == chrome::kChromeUIAppLauncherPageHost)
665     return AppLauncherPageUI::GetFaviconResourceBytes(scale_factor);
666
667   // Flash is not available on android.
668   if (page_url.host() == chrome::kChromeUIFlashHost)
669     return FlashUI::GetFaviconResourceBytes(scale_factor);
670
671   // Android uses the native download manager.
672   if (page_url.host() == chrome::kChromeUIDownloadsHost)
673     return DownloadsUI::GetFaviconResourceBytes(scale_factor);
674
675   // Android doesn't use the Options pages.
676   if (page_url.host() == chrome::kChromeUISettingsHost ||
677       page_url.host() == chrome::kChromeUISettingsFrameHost)
678     return options::OptionsUI::GetFaviconResourceBytes(scale_factor);
679
680 #if defined(ENABLE_EXTENSIONS)
681   if (page_url.host() == chrome::kChromeUIExtensionsHost ||
682       page_url.host() == chrome::kChromeUIExtensionsFrameHost)
683     return extensions::ExtensionsUI::GetFaviconResourceBytes(scale_factor);
684 #endif
685
686   // Android doesn't use the plugins pages.
687   if (page_url.host() == chrome::kChromeUIPluginsHost)
688     return PluginsUI::GetFaviconResourceBytes(scale_factor);
689
690 #endif
691
692   return NULL;
693 }