15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_about_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/lifetime/application_lifetime.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/net/url_fixer_upper.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WillHandleBrowserAboutURL(GURL* url,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               content::BrowserContext* browser_context) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(msw): Eliminate "about:*" constants and literals from code and tests,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //            then hopefully we can remove this forced fixup.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *url = URLFixerUpper::FixupURL(url->possibly_invalid_spec(), std::string());
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that about: URLs are fixed up to chrome: by URLFixerUpper::FixupURL.
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK((*url == GURL(content::kAboutBlankURL)) ||
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !url->SchemeIs(chrome::kAboutScheme));
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only handle chrome://foo/, URLFixerUpper::FixupURL translates about:foo.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url->SchemeIs(chrome::kChromeUIScheme))
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host(url->host());
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replace about with chrome-urls.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host == chrome::kChromeUIAboutHost)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUIChromeURLsHost;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replace cache with view-http-cache.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host == chrome::kChromeUICacheHost) {
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    host = content::kChromeUINetworkViewCacheHost;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replace sync with sync-internals (for legacy reasons).
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (host == chrome::kChromeUISyncHost) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUISyncInternalsHost;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Redirect chrome://extensions.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (host == chrome::kChromeUIExtensionsHost) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUIUberHost;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path = chrome::kChromeUIExtensionsHost + url->path();
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Redirect chrome://settings/extensions (legacy URL).
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (host == chrome::kChromeUISettingsHost &&
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url->path() == std::string("/") + chrome::kExtensionsSubPage) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUIUberHost;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path = chrome::kChromeUIExtensionsHost;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Redirect chrome://history.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (host == chrome::kChromeUIHistoryHost) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On Android, redirect directly to chrome://history-frame since
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // uber page is unsupported.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host = chrome::kChromeUIHistoryFrameHost;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUIUberHost;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path = chrome::kChromeUIHistoryHost + url->path();
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Redirect chrome://settings
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (host == chrome::kChromeUISettingsHost) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUIUberHost;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path = chrome::kChromeUISettingsHost + url->path();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Redirect chrome://help
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (host == chrome::kChromeUIHelpHost) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host = chrome::kChromeUIUberHost;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path = chrome::kChromeUIHelpHost + url->path();
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else if (host == chrome::kChromeUIRestartHost) {
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Call AttemptRestart after chrome::Navigate() completes to avoid access of
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // gtk objects after they are destoyed by BrowserWindowGtk::Close().
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::MessageLoop::current()->PostTask(FROM_HERE,
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&chrome::AttemptRestart));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL::Replacements replacements;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  replacements.SetHostStr(host);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!path.empty())
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replacements.SetPathStr(path);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *url = url->ReplaceComponents(replacements);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Having re-written the URL, make the chrome: handler process it.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HandleNonNavigationAboutURL(const GURL& url) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome://ipc/ is currently buggy, so we disable it for official builds.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OFFICIAL_BUILD)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Run the dialog. This will re-use the existing one if it's already up.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::ShowAboutIPCDialog();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OFFICIAL_BUILD
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105