| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/toolbar/chrome_location_bar_model_delegate.h" |
| |
| #include "base/logging.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" |
| #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search/search.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "chrome/browser/ssl/security_state_tab_helper.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "components/google/core/common/google_util.h" |
| #include "components/offline_pages/buildflags/buildflags.h" |
| #include "components/omnibox/browser/autocomplete_input.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/security_interstitials/content/security_interstitial_tab_helper.h" |
| #include "components/security_state/core/security_state.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/ssl_status.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/url_constants.h" |
| #include "extensions/common/constants.h" |
| |
| #if !defined(OS_ANDROID) |
| #include "components/omnibox/browser/vector_icons.h" // nogncheck |
| #endif // !defined(OS_ANDROID) |
| |
| #if BUILDFLAG(ENABLE_OFFLINE_PAGES) |
| #include "chrome/browser/offline_pages/offline_page_utils.h" |
| #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| #include "extensions/browser/extension_registry.h" |
| |
| // Id for extension that enables users to report sites to Safe Browsing. |
| const char kPreventElisionExtensionId[] = "jknemblkbdhdcpllfgbfekkdciegfboi"; |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| |
| ChromeLocationBarModelDelegate::ChromeLocationBarModelDelegate() {} |
| |
| ChromeLocationBarModelDelegate::~ChromeLocationBarModelDelegate() {} |
| |
| content::NavigationEntry* ChromeLocationBarModelDelegate::GetNavigationEntry() |
| const { |
| content::NavigationController* controller = GetNavigationController(); |
| return controller ? controller->GetVisibleEntry() : nullptr; |
| } |
| |
| base::string16 |
| ChromeLocationBarModelDelegate::FormattedStringWithEquivalentMeaning( |
| const GURL& url, |
| const base::string16& formatted_url) const { |
| return AutocompleteInput::FormattedStringWithEquivalentMeaning( |
| url, formatted_url, ChromeAutocompleteSchemeClassifier(GetProfile()), |
| nullptr); |
| } |
| |
| bool ChromeLocationBarModelDelegate::GetURL(GURL* url) const { |
| DCHECK(url); |
| content::NavigationEntry* entry = GetNavigationEntry(); |
| if (!entry) |
| return false; |
| |
| *url = ShouldDisplayURL() ? entry->GetVirtualURL() : GURL(); |
| return true; |
| } |
| |
| bool ChromeLocationBarModelDelegate::ShouldPreventElision() const { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| Profile* const profile = GetProfile(); |
| return profile && extensions::ExtensionRegistry::Get(profile) |
| ->enabled_extensions() |
| .Contains(kPreventElisionExtensionId); |
| #else |
| return false; |
| #endif |
| } |
| |
| bool ChromeLocationBarModelDelegate::ShouldDisplayURL() const { |
| // Note: The order here is important. |
| // - The WebUI test must come before the extension scheme test because there |
| // can be WebUIs that have extension schemes (e.g. the bookmark manager). In |
| // that case, we should prefer what the WebUI instance says. |
| // - The view-source test must come before the NTP test because of the case |
| // of view-source:chrome://newtab, which should display its URL despite what |
| // chrome://newtab says. |
| content::NavigationEntry* entry = GetNavigationEntry(); |
| if (!entry) |
| return true; |
| |
| security_interstitials::SecurityInterstitialTabHelper* tab_helper = |
| security_interstitials::SecurityInterstitialTabHelper::FromWebContents( |
| GetActiveWebContents()); |
| if (tab_helper && tab_helper->IsDisplayingInterstitial()) |
| return tab_helper->ShouldDisplayURL(); |
| |
| if (entry->IsViewSourceMode() || |
| entry->GetPageType() == content::PAGE_TYPE_INTERSTITIAL) { |
| return true; |
| } |
| |
| GURL url = entry->GetURL(); |
| GURL virtual_url = entry->GetVirtualURL(); |
| if (url.SchemeIs(content::kChromeUIScheme) || |
| virtual_url.SchemeIs(content::kChromeUIScheme)) { |
| if (!url.SchemeIs(content::kChromeUIScheme)) |
| url = virtual_url; |
| return url.host() != chrome::kChromeUINewTabHost; |
| } |
| |
| Profile* profile = GetProfile(); |
| return !profile || !search::IsInstantNTPURL(url, profile); |
| } |
| |
| security_state::SecurityLevel ChromeLocationBarModelDelegate::GetSecurityLevel() |
| const { |
| content::WebContents* web_contents = GetActiveWebContents(); |
| // If there is no active WebContents (which can happen during toolbar |
| // initialization), assume no security style. |
| if (!web_contents) { |
| return security_state::NONE; |
| } |
| auto* helper = SecurityStateTabHelper::FromWebContents(web_contents); |
| return helper->GetSecurityLevel(); |
| } |
| |
| std::unique_ptr<security_state::VisibleSecurityState> |
| ChromeLocationBarModelDelegate::GetVisibleSecurityState() const { |
| content::WebContents* web_contents = GetActiveWebContents(); |
| // If there is no active WebContents (which can happen during toolbar |
| // initialization), assume no security info. |
| if (!web_contents) { |
| return std::make_unique<security_state::VisibleSecurityState>(); |
| } |
| auto* helper = SecurityStateTabHelper::FromWebContents(web_contents); |
| return helper->GetVisibleSecurityState(); |
| } |
| |
| scoped_refptr<net::X509Certificate> |
| ChromeLocationBarModelDelegate::GetCertificate() const { |
| content::NavigationEntry* entry = GetNavigationEntry(); |
| if (!entry) |
| return scoped_refptr<net::X509Certificate>(); |
| return entry->GetSSL().certificate; |
| } |
| |
| const gfx::VectorIcon* ChromeLocationBarModelDelegate::GetVectorIconOverride() |
| const { |
| #if !defined(OS_ANDROID) |
| GURL url; |
| GetURL(&url); |
| |
| if (url.SchemeIs(content::kChromeUIScheme)) |
| return &omnibox::kProductIcon; |
| |
| if (url.SchemeIs(extensions::kExtensionScheme)) |
| return &omnibox::kExtensionAppIcon; |
| #endif |
| |
| return nullptr; |
| } |
| |
| bool ChromeLocationBarModelDelegate::IsOfflinePage() const { |
| #if BUILDFLAG(ENABLE_OFFLINE_PAGES) |
| content::WebContents* web_contents = GetActiveWebContents(); |
| return web_contents && |
| offline_pages::OfflinePageUtils::GetOfflinePageFromWebContents( |
| web_contents); |
| #else |
| return false; |
| #endif |
| } |
| |
| bool ChromeLocationBarModelDelegate::IsInstantNTP() const { |
| return search::IsInstantNTP(GetActiveWebContents()); |
| } |
| |
| bool ChromeLocationBarModelDelegate::IsNewTabPage(const GURL& url) const { |
| return url.spec() == chrome::kChromeUINewTabURL; |
| } |
| |
| bool ChromeLocationBarModelDelegate::IsHomePage(const GURL& url) const { |
| Profile* const profile = GetProfile(); |
| if (!profile) |
| return false; |
| |
| return url.spec() == profile->GetPrefs()->GetString(prefs::kHomePage); |
| } |
| |
| content::NavigationController* |
| ChromeLocationBarModelDelegate::GetNavigationController() const { |
| // This |current_tab| can be null during the initialization of the toolbar |
| // during window creation (i.e. before any tabs have been added to the |
| // window). |
| content::WebContents* current_tab = GetActiveWebContents(); |
| return current_tab ? ¤t_tab->GetController() : nullptr; |
| } |
| |
| Profile* ChromeLocationBarModelDelegate::GetProfile() const { |
| content::NavigationController* controller = GetNavigationController(); |
| return controller |
| ? Profile::FromBrowserContext(controller->GetBrowserContext()) |
| : nullptr; |
| } |
| |
| AutocompleteClassifier* |
| ChromeLocationBarModelDelegate::GetAutocompleteClassifier() { |
| Profile* const profile = GetProfile(); |
| return profile ? AutocompleteClassifierFactory::GetForProfile(profile) |
| : nullptr; |
| } |
| |
| TemplateURLService* ChromeLocationBarModelDelegate::GetTemplateURLService() { |
| Profile* const profile = GetProfile(); |
| return profile ? TemplateURLServiceFactory::GetForProfile(profile) : nullptr; |
| } |