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