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