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/browser_about_handler.h" 6 7 #include <string> 8 9 #include "base/logging.h" 10 #include "base/strings/string_util.h" 11 #include "chrome/browser/lifetime/application_lifetime.h" 12 #include "chrome/browser/ui/browser_dialogs.h" 13 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/url_constants.h" 15 #include "components/url_fixer/url_fixer.h" 16 17 bool WillHandleBrowserAboutURL(GURL* url, 18 content::BrowserContext* browser_context) { 19 // TODO(msw): Eliminate "about:*" constants and literals from code and tests, 20 // then hopefully we can remove this forced fixup. 21 *url = url_fixer::FixupURL(url->possibly_invalid_spec(), std::string()); 22 23 // Check that about: URLs are fixed up to chrome: by url_fixer::FixupURL. 24 DCHECK((*url == GURL(url::kAboutBlankURL)) || 25 !url->SchemeIs(url::kAboutScheme)); 26 27 // Only handle chrome://foo/, url_fixer::FixupURL translates about:foo. 28 if (!url->SchemeIs(content::kChromeUIScheme)) 29 return false; 30 31 std::string host(url->host()); 32 std::string path; 33 // Replace about with chrome-urls. 34 if (host == chrome::kChromeUIAboutHost) 35 host = chrome::kChromeUIChromeURLsHost; 36 // Replace cache with view-http-cache. 37 if (host == chrome::kChromeUICacheHost) { 38 host = content::kChromeUINetworkViewCacheHost; 39 // Replace sync with sync-internals (for legacy reasons). 40 } else if (host == chrome::kChromeUISyncHost) { 41 host = chrome::kChromeUISyncInternalsHost; 42 // Redirect chrome://extensions. 43 } else if (host == chrome::kChromeUIExtensionsHost) { 44 host = chrome::kChromeUIUberHost; 45 path = chrome::kChromeUIExtensionsHost + url->path(); 46 // Redirect chrome://settings/extensions (legacy URL). 47 } else if (host == chrome::kChromeUISettingsHost && 48 url->path() == std::string("/") + chrome::kExtensionsSubPage) { 49 host = chrome::kChromeUIUberHost; 50 path = chrome::kChromeUIExtensionsHost; 51 // Redirect chrome://history. 52 } else if (host == chrome::kChromeUIHistoryHost) { 53 #if defined(OS_ANDROID) 54 // On Android, redirect directly to chrome://history-frame since 55 // uber page is unsupported. 56 host = chrome::kChromeUIHistoryFrameHost; 57 #else 58 host = chrome::kChromeUIUberHost; 59 path = chrome::kChromeUIHistoryHost + url->path(); 60 #endif 61 // Redirect chrome://settings 62 } else if (host == chrome::kChromeUISettingsHost) { 63 if (::switches::AboutInSettingsEnabled()) { 64 host = chrome::kChromeUISettingsFrameHost; 65 } else { 66 host = chrome::kChromeUIUberHost; 67 path = chrome::kChromeUISettingsHost + url->path(); 68 } 69 // Redirect chrome://help 70 } else if (host == chrome::kChromeUIHelpHost) { 71 if (::switches::AboutInSettingsEnabled()) { 72 host = chrome::kChromeUISettingsFrameHost; 73 if (url->path().empty() || url->path() == "/") 74 path = chrome::kChromeUIHelpHost; 75 } else { 76 host = chrome::kChromeUIUberHost; 77 path = chrome::kChromeUIHelpHost + url->path(); 78 } 79 } 80 81 GURL::Replacements replacements; 82 replacements.SetHostStr(host); 83 if (!path.empty()) 84 replacements.SetPathStr(path); 85 *url = url->ReplaceComponents(replacements); 86 87 // Having re-written the URL, make the chrome: handler process it. 88 return false; 89 } 90 91 bool HandleNonNavigationAboutURL(const GURL& url) { 92 const std::string spec(url.spec()); 93 94 if (LowerCaseEqualsASCII(spec, chrome::kChromeUIRestartURL)) { 95 // Call AttemptRestart after chrome::Navigate() completes to avoid access of 96 // gtk objects after they are destroyed by BrowserWindowGtk::Close(). 97 base::MessageLoop::current()->PostTask(FROM_HERE, 98 base::Bind(&chrome::AttemptRestart)); 99 return true; 100 } else if (LowerCaseEqualsASCII(spec, chrome::kChromeUIQuitURL)) { 101 base::MessageLoop::current()->PostTask(FROM_HERE, 102 base::Bind(&chrome::AttemptExit)); 103 return true; 104 } 105 106 // chrome://ipc/ is currently buggy, so we disable it for official builds. 107 #if !defined(OFFICIAL_BUILD) 108 109 #if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED) 110 if (LowerCaseEqualsASCII(spec, chrome::kChromeUIIPCURL)) { 111 // Run the dialog. This will re-use the existing one if it's already up. 112 chrome::ShowAboutIPCDialog(); 113 return true; 114 } 115 #endif 116 117 #endif // OFFICIAL_BUILD 118 119 return false; 120 } 121