OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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_factory.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "chrome/browser/about_flags.h" | |
9 #include "chrome/browser/extensions/extension_service.h" | |
10 #include "chrome/browser/extensions/extension_web_ui.h" | |
11 #include "chrome/browser/extensions/extensions_ui.h" | |
12 #include "chrome/browser/profiles/profile.h" | |
13 #include "chrome/browser/ui/webui/bookmarks_ui.h" | |
14 #include "chrome/browser/ui/webui/bug_report_ui.h" | |
15 #include "chrome/browser/ui/webui/constrained_html_ui.h" | |
16 #include "chrome/browser/ui/webui/crashes_ui.h" | |
17 #include "chrome/browser/ui/webui/devtools_ui.h" | |
18 #include "chrome/browser/ui/webui/downloads_ui.h" | |
19 #include "chrome/browser/ui/webui/flags_ui.h" | |
20 #include "chrome/browser/ui/webui/gpu_internals_ui.h" | |
21 #include "chrome/browser/ui/webui/history2_ui.h" | |
22 #include "chrome/browser/ui/webui/history_ui.h" | |
23 #include "chrome/browser/ui/webui/html_dialog_ui.h" | |
24 #include "chrome/browser/ui/webui/net_internals_ui.h" | |
25 #include "chrome/browser/ui/webui/new_tab_ui.h" | |
26 #include "chrome/browser/ui/webui/options/options_ui.h" | |
27 #include "chrome/browser/ui/webui/plugins_ui.h" | |
28 #include "chrome/browser/ui/webui/print_preview_ui.h" | |
29 #include "chrome/browser/ui/webui/remoting_ui.h" | |
30 #include "chrome/browser/ui/webui/slideshow_ui.h" | |
31 #include "chrome/browser/ui/webui/sync_internals_ui.h" | |
32 #include "chrome/browser/ui/webui/textfields_ui.h" | |
33 #include "chrome/common/chrome_switches.h" | |
34 #include "chrome/common/extensions/extension_constants.h" | |
35 #include "chrome/common/url_constants.h" | |
36 #include "content/browser/tab_contents/tab_contents.h" | |
37 #include "content/browser/webui/web_ui.h" | |
38 #include "googleurl/src/gurl.h" | |
39 | |
40 #if defined(OS_CHROMEOS) | |
41 #include "chrome/browser/ui/webui/chromeos/imageburner_ui.h" | |
42 #include "chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.h" | |
43 #include "chrome/browser/ui/webui/chromeos/mobile_setup_ui.h" | |
44 #include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h" | |
45 #include "chrome/browser/ui/webui/chromeos/register_page_ui.h" | |
46 #include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h" | |
47 #include "chrome/browser/ui/webui/chromeos/system_info_ui.h" | |
48 #include "chrome/browser/ui/webui/filebrowse_ui.h" | |
49 #include "chrome/browser/ui/webui/mediaplayer_ui.h" | |
50 #endif | |
51 | |
52 #if defined(TOUCH_UI) | |
53 #include "chrome/browser/ui/webui/keyboard_ui.h" | |
54 #endif | |
55 | |
56 #if defined(TOUCH_UI) && defined(OS_CHROMEOS) | |
57 #include "chrome/browser/ui/webui/chromeos/login/login_container_ui.h" | |
58 #include "chrome/browser/ui/webui/chromeos/login/login_ui.h" | |
59 #endif | |
60 | |
61 #if defined(OS_WIN) | |
62 #include "chrome/browser/ui/webui/conflicts_ui.h" | |
63 #endif | |
64 | |
65 namespace { | |
66 | |
67 // A function for creating a new WebUI. The caller owns the return value, which | |
68 // may be NULL (for example, if the URL refers to an non-existent extension). | |
69 typedef WebUI* (*WebUIFactoryFunction)(TabContents* tab_contents, | |
70 const GURL& url); | |
71 | |
72 // Template for defining WebUIFactoryFunction. | |
73 template<class T> | |
74 WebUI* NewWebUI(TabContents* contents, const GURL& url) { | |
75 return new T(contents); | |
76 } | |
77 | |
78 // Special case for extensions. | |
79 template<> | |
80 WebUI* NewWebUI<ExtensionWebUI>(TabContents* contents, const GURL& url) { | |
81 // Don't use a WebUI for incognito tabs because we require extensions to run | |
82 // within a single process. | |
83 ExtensionService* service = contents->profile()->GetExtensionService(); | |
84 if (service && | |
85 service->ExtensionBindingsAllowed(url)) { | |
86 return new ExtensionWebUI(contents, url); | |
87 } | |
88 return NULL; | |
89 } | |
90 | |
91 // Returns a function that can be used to create the right type of WebUI for a | |
92 // tab, based on its URL. Returns NULL if the URL doesn't have WebUI associated | |
93 // with it. Even if the factory function is valid, it may yield a NULL WebUI | |
94 // when invoked for a particular tab - see NewWebUI<ExtensionWebUI>. | |
95 static WebUIFactoryFunction GetWebUIFactoryFunction(Profile* profile, | |
96 const GURL& url) { | |
97 if (url.host() == chrome::kChromeUIDialogHost) | |
98 return &NewWebUI<ConstrainedHtmlUI>; | |
99 | |
100 ExtensionService* service = profile ? profile->GetExtensionService() : NULL; | |
101 if (service && service->ExtensionBindingsAllowed(url)) | |
102 return &NewWebUI<ExtensionWebUI>; | |
103 | |
104 // All platform builds of Chrome will need to have a cloud printing | |
105 // dialog as backup. It's just that on Chrome OS, it's the only | |
106 // print dialog. | |
107 if (url.host() == chrome::kCloudPrintResourcesHost) | |
108 return &NewWebUI<ExternalHtmlDialogUI>; | |
109 | |
110 // This will get called a lot to check all URLs, so do a quick check of other | |
111 // schemes to filter out most URLs. | |
112 if (!url.SchemeIs(chrome::kChromeDevToolsScheme) && | |
113 !url.SchemeIs(chrome::kChromeInternalScheme) && | |
114 !url.SchemeIs(chrome::kChromeUIScheme)) | |
115 return NULL; | |
116 | |
117 if (url.host() == chrome::kChromeUISyncResourcesHost || | |
118 url.host() == chrome::kChromeUIRemotingResourcesHost || | |
119 url.host() == chrome::kCloudPrintSetupHost) | |
120 return &NewWebUI<HtmlDialogUI>; | |
121 | |
122 // Special case the new tab page. In older versions of Chrome, the new tab | |
123 // page was hosted at chrome-internal:<blah>. This might be in people's saved | |
124 // sessions or bookmarks, so we say any URL with that scheme triggers the new | |
125 // tab page. | |
126 if (url.host() == chrome::kChromeUINewTabHost || | |
127 url.SchemeIs(chrome::kChromeInternalScheme)) | |
128 return &NewWebUI<NewTabUI>; | |
129 | |
130 // Give about:about a generic Web UI so it can navigate to pages with Web UIs. | |
131 if (url.spec() == chrome::kChromeUIAboutAboutURL) | |
132 return &NewWebUI<WebUI>; | |
133 | |
134 // We must compare hosts only since some of the Web UIs append extra stuff | |
135 // after the host name. | |
136 if (url.host() == chrome::kChromeUIBookmarksHost) | |
137 return &NewWebUI<BookmarksUI>; | |
138 if (url.host() == chrome::kChromeUIBugReportHost) | |
139 return &NewWebUI<BugReportUI>; | |
140 if (url.host() == chrome::kChromeUICrashesHost) | |
141 return &NewWebUI<CrashesUI>; | |
142 if (url.host() == chrome::kChromeUIDevToolsHost) | |
143 return &NewWebUI<DevToolsUI>; | |
144 #if defined(OS_WIN) | |
145 if (url.host() == chrome::kChromeUIConflictsHost) | |
146 return &NewWebUI<ConflictsUI>; | |
147 #endif | |
148 if (url.host() == chrome::kChromeUIDownloadsHost) | |
149 return &NewWebUI<DownloadsUI>; | |
150 if (url.host() == chrome::kChromeUITextfieldsHost) | |
151 return &NewWebUI<TextfieldsUI>; | |
152 if (url.host() == chrome::kChromeUIExtensionsHost) | |
153 return &NewWebUI<ExtensionsUI>; | |
154 if (url.host() == chrome::kChromeUIHistoryHost) | |
155 return &NewWebUI<HistoryUI>; | |
156 if (url.host() == chrome::kChromeUIHistory2Host) | |
157 return &NewWebUI<HistoryUI2>; | |
158 if (url.host() == chrome::kChromeUIFlagsHost) | |
159 return &NewWebUI<FlagsUI>; | |
160 #if defined(TOUCH_UI) | |
161 if (url.host() == chrome::kChromeUIKeyboardHost) | |
162 return &NewWebUI<KeyboardUI>; | |
163 #endif | |
164 if (url.host() == chrome::kChromeUIGpuInternalsHost) | |
165 return &NewWebUI<GpuInternalsUI>; | |
166 if (url.host() == chrome::kChromeUINetInternalsHost) | |
167 return &NewWebUI<NetInternalsUI>; | |
168 if (url.host() == chrome::kChromeUIPluginsHost) | |
169 return &NewWebUI<PluginsUI>; | |
170 if (url.host() == chrome::kChromeUISyncInternalsHost) | |
171 return &NewWebUI<SyncInternalsUI>; | |
172 #if defined(ENABLE_REMOTING) | |
173 if (url.host() == chrome::kChromeUIRemotingHost) { | |
174 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
175 switches::kEnableRemoting)) { | |
176 return &NewWebUI<RemotingUI>; | |
177 } | |
178 } | |
179 #endif | |
180 | |
181 #if defined(OS_CHROMEOS) | |
182 if (url.host() == chrome::kChromeUICollectedCookiesHost || | |
183 url.host() == chrome::kChromeUIHttpAuthHost) { | |
184 return &NewWebUI<ConstrainedHtmlUI>; | |
185 } | |
186 if (url.host() == chrome::kChromeUIFileBrowseHost) | |
187 return &NewWebUI<FileBrowseUI>; | |
188 if (url.host() == chrome::kChromeUIImageBurnerHost) | |
189 return &NewWebUI<ImageBurnUI>; | |
190 if (url.host() == chrome::kChromeUIKeyboardOverlayHost) | |
191 return &NewWebUI<KeyboardOverlayUI>; | |
192 if (url.host() == chrome::kChromeUIMediaplayerHost) | |
193 return &NewWebUI<MediaplayerUI>; | |
194 if (url.host() == chrome::kChromeUIMobileSetupHost) | |
195 return &NewWebUI<MobileSetupUI>; | |
196 if (url.host() == chrome::kChromeUIProxySettingsHost) | |
197 return &NewWebUI<chromeos::ProxySettingsUI>; | |
198 if (url.host() == chrome::kChromeUIRegisterPageHost) | |
199 return &NewWebUI<RegisterPageUI>; | |
200 if (url.host() == chrome::kChromeUISettingsHost) | |
201 return &NewWebUI<OptionsUI>; | |
202 if (url.host() == chrome::kChromeUISlideshowHost) | |
203 return &NewWebUI<SlideshowUI>; | |
204 if (url.host() == chrome::kChromeUISimUnlockHost) | |
205 return &NewWebUI<chromeos::SimUnlockUI>; | |
206 if (url.host() == chrome::kChromeUISystemInfoHost) | |
207 return &NewWebUI<SystemInfoUI>; | |
208 #else | |
209 if (url.host() == chrome::kChromeUISettingsHost) | |
210 return &NewWebUI<OptionsUI>; | |
211 if (url.host() == chrome::kChromeUIPrintHost) { | |
212 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
213 switches::kEnablePrintPreview)) { | |
214 return &NewWebUI<PrintPreviewUI>; | |
215 } | |
216 } | |
217 #endif // defined(OS_CHROMEOS) | |
218 | |
219 #if defined(TOUCH_UI) && defined(OS_CHROMEOS) | |
220 if (url.host() == chrome::kChromeUILoginHost) | |
221 return &NewWebUI<chromeos::LoginUI>; | |
222 if (url.host() == chrome::kChromeUILoginContainerHost) | |
223 return &NewWebUI<chromeos::LoginContainerUI>; | |
224 #endif | |
225 | |
226 if (url.spec() == chrome::kChromeUIConstrainedHTMLTestURL) | |
227 return &NewWebUI<ConstrainedHtmlUI>; | |
228 | |
229 return NULL; | |
230 } | |
231 | |
232 } // namespace | |
233 | |
234 WebUI::TypeID ChromeWebUIFactory::GetWebUIType(Profile* profile, | |
235 const GURL& url) const { | |
236 WebUIFactoryFunction function = GetWebUIFactoryFunction(profile, url); | |
237 return function ? reinterpret_cast<WebUI::TypeID>(function) : WebUI::kNoWebUI; | |
238 } | |
239 | |
240 bool ChromeWebUIFactory::UseWebUIForURL(Profile* profile, | |
241 const GURL& url) const { | |
242 return GetWebUIType(profile, url) != WebUI::kNoWebUI; | |
243 } | |
244 | |
245 bool ChromeWebUIFactory::HasWebUIScheme(const GURL& url) const { | |
246 return url.SchemeIs(chrome::kChromeDevToolsScheme) || | |
247 url.SchemeIs(chrome::kChromeInternalScheme) || | |
248 url.SchemeIs(chrome::kChromeUIScheme) || | |
249 url.SchemeIs(chrome::kExtensionScheme); | |
250 } | |
251 | |
252 bool ChromeWebUIFactory::IsURLAcceptableForWebUI(Profile* profile, | |
253 const GURL& url) const { | |
254 return UseWebUIForURL(profile, url) || | |
255 // javacsript: URLs are allowed to run in Web UI pages | |
256 url.SchemeIs(chrome::kJavaScriptScheme) || | |
257 // It's possible to load about:blank in a Web UI renderer. | |
258 // See http://crbug.com/42547 | |
259 url.spec() == chrome::kAboutBlankURL || | |
260 // about:crash, about:kill, about:hang, and about:shorthang are allowed. | |
261 url.spec() == chrome::kAboutCrashURL || | |
262 url.spec() == chrome::kAboutKillURL || | |
263 url.spec() == chrome::kAboutHangURL || | |
264 url.spec() == chrome::kAboutShorthangURL; | |
265 } | |
266 | |
267 WebUI* ChromeWebUIFactory::CreateWebUIForURL(TabContents* tab_contents, | |
268 const GURL& url) const { | |
269 WebUIFactoryFunction function = GetWebUIFactoryFunction( | |
270 tab_contents->profile(), url); | |
271 if (!function) | |
272 return NULL; | |
273 return (*function)(tab_contents, url); | |
274 } | |
275 | |
276 void ChromeWebUIFactory::GetFaviconForURL(Profile* profile, | |
277 FaviconService::GetFaviconRequest* request, | |
278 const GURL& page_url) const { | |
279 // All extensions but the bookmark manager get their favicon from the icons | |
280 // part of the manifest. | |
281 if (page_url.SchemeIs(chrome::kExtensionScheme) && | |
282 page_url.host() != extension_misc::kBookmarkManagerId) { | |
283 ExtensionWebUI::GetFaviconForURL(profile, request, page_url); | |
284 } else { | |
285 history::FaviconData favicon; | |
286 favicon.image_data = scoped_refptr<RefCountedMemory>( | |
287 GetFaviconResourceBytes(profile, page_url)); | |
288 favicon.known_icon = favicon.image_data.get() != NULL && | |
289 favicon.image_data->size() > 0; | |
290 request->ForwardResultAsync( | |
291 FaviconService::FaviconDataCallback::TupleType(request->handle(), | |
292 favicon)); | |
293 } | |
294 } | |
295 | |
296 // static | |
297 ChromeWebUIFactory* ChromeWebUIFactory::GetInstance() { | |
298 return Singleton<ChromeWebUIFactory>::get(); | |
299 } | |
300 | |
301 ChromeWebUIFactory::ChromeWebUIFactory() { | |
302 } | |
303 | |
304 ChromeWebUIFactory::~ChromeWebUIFactory() { | |
305 } | |
306 | |
307 RefCountedMemory* ChromeWebUIFactory::GetFaviconResourceBytes( | |
308 Profile* profile, | |
309 const GURL& page_url) const { | |
310 // The bookmark manager is a chrome extension, so we have to check for it | |
311 // before we check for extension scheme. | |
312 if (page_url.host() == extension_misc::kBookmarkManagerId) | |
313 return BookmarksUI::GetFaviconResourceBytes(); | |
314 | |
315 // The extension scheme is handled in GetFaviconForURL. | |
316 if (page_url.SchemeIs(chrome::kExtensionScheme)) { | |
317 NOTREACHED(); | |
318 return NULL; | |
319 } | |
320 | |
321 if (!HasWebUIScheme(page_url)) | |
322 return NULL; | |
323 | |
324 #if defined(OS_WIN) | |
325 if (page_url.host() == chrome::kChromeUIConflictsHost) | |
326 return ConflictsUI::GetFaviconResourceBytes(); | |
327 #endif | |
328 | |
329 if (page_url.host() == chrome::kChromeUICrashesHost) | |
330 return CrashesUI::GetFaviconResourceBytes(); | |
331 | |
332 if (page_url.host() == chrome::kChromeUIDownloadsHost) | |
333 return DownloadsUI::GetFaviconResourceBytes(); | |
334 | |
335 if (page_url.host() == chrome::kChromeUIExtensionsHost) | |
336 return ExtensionsUI::GetFaviconResourceBytes(); | |
337 | |
338 if (page_url.host() == chrome::kChromeUIHistoryHost) | |
339 return HistoryUI::GetFaviconResourceBytes(); | |
340 | |
341 if (page_url.host() == chrome::kChromeUIHistory2Host) | |
342 return HistoryUI2::GetFaviconResourceBytes(); | |
343 | |
344 if (page_url.host() == chrome::kChromeUIFlagsHost) | |
345 return FlagsUI::GetFaviconResourceBytes(); | |
346 | |
347 if (page_url.host() == chrome::kChromeUISettingsHost) | |
348 return OptionsUI::GetFaviconResourceBytes(); | |
349 | |
350 if (page_url.host() == chrome::kChromeUIPluginsHost) | |
351 return PluginsUI::GetFaviconResourceBytes(); | |
352 | |
353 #if defined(ENABLE_REMOTING) | |
354 if (page_url.host() == chrome::kChromeUIRemotingHost) | |
355 return RemotingUI::GetFaviconResourceBytes(); | |
356 #endif | |
357 | |
358 return NULL; | |
359 } | |
OLD | NEW |