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