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