Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h" | 5 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h" |
| 6 | 6 |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "base/time/time.h" | 8 #include "base/time/time.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "chrome/browser/search/search.h" | |
| 11 #include "chrome/browser/ssl/chrome_security_state_model_client.h" | |
| 12 #include "chrome/browser/ui/toolbar/toolbar_model_delegate.h" | 10 #include "chrome/browser/ui/toolbar/toolbar_model_delegate.h" |
| 13 #include "chrome/common/url_constants.h" | |
| 14 #include "chrome/grit/generated_resources.h" | 11 #include "chrome/grit/generated_resources.h" |
| 15 #include "components/google/core/browser/google_util.h" | 12 #include "components/google/core/browser/google_util.h" |
| 16 #include "components/prefs/pref_service.h" | 13 #include "components/prefs/pref_service.h" |
| 17 #include "components/security_state/security_state_model.h" | 14 #include "components/security_state/security_state_model.h" |
| 18 #include "components/url_formatter/elide_url.h" | 15 #include "components/url_formatter/elide_url.h" |
| 19 #include "components/url_formatter/url_formatter.h" | 16 #include "components/url_formatter/url_formatter.h" |
| 20 #include "content/public/browser/cert_store.h" | |
| 21 #include "content/public/browser/navigation_controller.h" | |
| 22 #include "content/public/browser/navigation_entry.h" | |
| 23 #include "content/public/browser/web_contents.h" | |
| 24 #include "content/public/browser/web_ui.h" | |
| 25 #include "content/public/common/content_constants.h" | |
| 26 #include "content/public/common/ssl_status.h" | |
| 27 #include "grit/components_scaled_resources.h" | 17 #include "grit/components_scaled_resources.h" |
| 28 #include "net/cert/cert_status_flags.h" | 18 #include "net/cert/cert_status_flags.h" |
| 29 #include "net/cert/x509_certificate.h" | 19 #include "net/cert/x509_certificate.h" |
| 30 #include "net/ssl/ssl_connection_status_flags.h" | 20 #include "net/ssl/ssl_connection_status_flags.h" |
| 31 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 32 #include "ui/gfx/text_elider.h" | 22 #include "ui/gfx/text_elider.h" |
| 33 #include "ui/gfx/vector_icons_public.h" | 23 #include "ui/gfx/vector_icons_public.h" |
| 34 | 24 |
| 35 using content::NavigationController; | |
| 36 using content::NavigationEntry; | |
| 37 using content::WebContents; | |
| 38 using security_state::SecurityStateModel; | 25 using security_state::SecurityStateModel; |
| 39 | 26 |
| 40 ToolbarModelImpl::ToolbarModelImpl(ToolbarModelDelegate* delegate) | 27 ToolbarModelImpl::ToolbarModelImpl(ToolbarModelDelegate* delegate, |
| 41 : delegate_(delegate) { | 28 size_t max_url_display_chars) |
| 42 } | 29 : delegate_(delegate), max_url_display_chars_(max_url_display_chars) {} |
| 43 | 30 |
| 44 ToolbarModelImpl::~ToolbarModelImpl() { | 31 ToolbarModelImpl::~ToolbarModelImpl() { |
| 45 } | 32 } |
| 46 | 33 |
| 47 // ToolbarModelImpl Implementation. | 34 // ToolbarModelImpl Implementation. |
| 48 base::string16 ToolbarModelImpl::GetText() const { | 35 base::string16 ToolbarModelImpl::GetText() const { |
| 49 base::string16 search_terms(GetSearchTerms(false)); | 36 base::string16 search_terms(GetSearchTerms(false)); |
| 50 if (!search_terms.empty()) | 37 if (!search_terms.empty()) |
| 51 return search_terms; | 38 return search_terms; |
| 52 | 39 |
| 53 return GetFormattedURL(NULL); | 40 return GetFormattedURL(NULL); |
| 54 } | 41 } |
| 55 | 42 |
| 56 base::string16 ToolbarModelImpl::GetFormattedURL(size_t* prefix_end) const { | 43 base::string16 ToolbarModelImpl::GetFormattedURL(size_t* prefix_end) const { |
| 57 // May be empty during initialization. | 44 // May be empty during initialization. |
| 58 std::string languages = delegate_->GetAcceptLanguages(); | 45 std::string languages = delegate_->GetAcceptLanguages(); |
| 59 | 46 |
| 60 GURL url(GetURL()); | 47 GURL url(GetURL()); |
| 61 // Note that we can't unescape spaces here, because if the user copies this | 48 // Note that we can't unescape spaces here, because if the user copies this |
| 62 // and pastes it into another program, that program may think the URL ends at | 49 // and pastes it into another program, that program may think the URL ends at |
| 63 // the space. | 50 // the space. |
| 64 const base::string16 formatted_text = | 51 const base::string16 formatted_text = |
| 65 delegate_->FormattedStringWithEquivalentMeaning( | 52 delegate_->FormattedStringWithEquivalentMeaning( |
| 66 url, url_formatter::FormatUrl( | 53 url, url_formatter::FormatUrl( |
| 67 url, languages, url_formatter::kFormatUrlOmitAll, | 54 url, languages, url_formatter::kFormatUrlOmitAll, |
| 68 net::UnescapeRule::NORMAL, nullptr, prefix_end, nullptr)); | 55 net::UnescapeRule::NORMAL, nullptr, prefix_end, nullptr)); |
| 69 if (formatted_text.length() <= content::kMaxURLDisplayChars) | 56 if (formatted_text.length() <= max_url_display_chars_) |
| 70 return formatted_text; | 57 return formatted_text; |
| 71 | 58 |
| 72 // Truncating the URL breaks editing and then pressing enter, but hopefully | 59 // Truncating the URL breaks editing and then pressing enter, but hopefully |
| 73 // people won't try to do much with such enormous URLs anyway. If this becomes | 60 // people won't try to do much with such enormous URLs anyway. If this becomes |
| 74 // a real problem, we could perhaps try to keep some sort of different "elided | 61 // a real problem, we could perhaps try to keep some sort of different "elided |
| 75 // visible URL" where editing affects and reloads the "real underlying URL", | 62 // visible URL" where editing affects and reloads the "real underlying URL", |
| 76 // but this seems very tricky for little gain. | 63 // but this seems very tricky for little gain. |
| 77 return gfx::TruncateString(formatted_text, content::kMaxURLDisplayChars - 1, | 64 return gfx::TruncateString(formatted_text, max_url_display_chars_ - 1, |
| 78 gfx::CHARACTER_BREAK) + | 65 gfx::CHARACTER_BREAK) + |
| 79 gfx::kEllipsisUTF16; | 66 gfx::kEllipsisUTF16; |
| 80 } | 67 } |
| 81 | 68 |
| 82 base::string16 ToolbarModelImpl::GetCorpusNameForMobile() const { | 69 base::string16 ToolbarModelImpl::GetCorpusNameForMobile() const { |
| 83 if (!WouldPerformSearchTermReplacement(false)) | 70 if (!WouldPerformSearchTermReplacement(false)) |
| 84 return base::string16(); | 71 return base::string16(); |
| 85 GURL url(GetURL()); | 72 GURL url(GetURL()); |
| 86 // If there is a query in the url fragment look for the corpus name there, | 73 // If there is a query in the url fragment look for the corpus name there, |
| 87 // otherwise look for the corpus name in the query parameters. | 74 // otherwise look for the corpus name in the query parameters. |
| 88 const std::string& query_str(google_util::HasGoogleSearchQueryParam( | 75 const std::string& query_str(google_util::HasGoogleSearchQueryParam( |
| 89 url.ref_piece()) ? url.ref() : url.query()); | 76 url.ref_piece()) ? url.ref() : url.query()); |
| 90 url::Component query(0, query_str.length()), key, value; | 77 url::Component query(0, query_str.length()), key, value; |
| 91 const char kChipKey[] = "sboxchip"; | 78 const char kChipKey[] = "sboxchip"; |
| 92 while (url::ExtractQueryKeyValue(query_str.c_str(), &query, &key, &value)) { | 79 while (url::ExtractQueryKeyValue(query_str.c_str(), &query, &key, &value)) { |
| 93 if (key.is_nonempty() && query_str.substr(key.begin, key.len) == kChipKey) { | 80 if (key.is_nonempty() && query_str.substr(key.begin, key.len) == kChipKey) { |
| 94 return net::UnescapeAndDecodeUTF8URLComponent( | 81 return net::UnescapeAndDecodeUTF8URLComponent( |
| 95 query_str.substr(value.begin, value.len), | 82 query_str.substr(value.begin, value.len), |
| 96 net::UnescapeRule::NORMAL); | 83 net::UnescapeRule::NORMAL); |
| 97 } | 84 } |
| 98 } | 85 } |
| 99 return base::string16(); | 86 return base::string16(); |
| 100 } | 87 } |
| 101 | 88 |
| 102 GURL ToolbarModelImpl::GetURL() const { | 89 GURL ToolbarModelImpl::GetURL() const { |
| 103 const NavigationController* navigation_controller = GetNavigationController(); | 90 GURL url; |
| 104 if (navigation_controller) { | 91 if (delegate_->GetURL(&url)) |
| 105 const NavigationEntry* entry = navigation_controller->GetVisibleEntry(); | 92 return url; |
|
Peter Kasting
2016/02/02 23:51:30
Nit: Shorter:
return delegate_->GetURL(&url) ?
sdefresne
2016/02/03 13:14:17
Done.
| |
| 106 if (entry) | |
| 107 return ShouldDisplayURL() ? entry->GetVirtualURL() : GURL(); | |
| 108 } | |
| 109 | 93 |
| 110 return GURL(url::kAboutBlankURL); | 94 return GURL(url::kAboutBlankURL); |
| 111 } | 95 } |
| 112 | 96 |
| 113 bool ToolbarModelImpl::WouldPerformSearchTermReplacement( | 97 bool ToolbarModelImpl::WouldPerformSearchTermReplacement( |
| 114 bool ignore_editing) const { | 98 bool ignore_editing) const { |
| 115 return !GetSearchTerms(ignore_editing).empty(); | 99 return !GetSearchTerms(ignore_editing).empty(); |
| 116 } | 100 } |
| 117 | 101 |
| 118 SecurityStateModel::SecurityLevel ToolbarModelImpl::GetSecurityLevel( | 102 SecurityStateModel::SecurityLevel ToolbarModelImpl::GetSecurityLevel( |
| 119 bool ignore_editing) const { | 103 bool ignore_editing) const { |
| 120 const content::WebContents* web_contents = delegate_->GetActiveWebContents(); | 104 // When editing, assume no security style. |
| 121 // If there is no active WebContents (which can happen during toolbar | 105 if (input_in_progress() && !ignore_editing) |
| 122 // initialization), assume no security style. | |
| 123 if (!web_contents) | |
| 124 return SecurityStateModel::NONE; | 106 return SecurityStateModel::NONE; |
| 125 const ChromeSecurityStateModelClient* model_client = | 107 return delegate_->GetSecurityLevel(); |
|
Peter Kasting
2016/02/02 23:51:31
Nit: Shorter:
return (input_in_progress() && !i
sdefresne
2016/02/03 13:14:17
Done.
| |
| 126 ChromeSecurityStateModelClient::FromWebContents(web_contents); | |
| 127 | |
| 128 // When editing, assume no security style. | |
| 129 return (input_in_progress() && !ignore_editing) | |
| 130 ? SecurityStateModel::NONE | |
| 131 : model_client->GetSecurityInfo().security_level; | |
| 132 } | 108 } |
| 133 | 109 |
| 134 int ToolbarModelImpl::GetIcon() const { | 110 int ToolbarModelImpl::GetIcon() const { |
| 135 switch (GetSecurityLevel(false)) { | 111 switch (GetSecurityLevel(false)) { |
| 136 case SecurityStateModel::NONE: | 112 case SecurityStateModel::NONE: |
| 137 return IDR_LOCATION_BAR_HTTP; | 113 return IDR_LOCATION_BAR_HTTP; |
| 138 case SecurityStateModel::EV_SECURE: | 114 case SecurityStateModel::EV_SECURE: |
| 139 case SecurityStateModel::SECURE: | 115 case SecurityStateModel::SECURE: |
| 140 return IDR_OMNIBOX_HTTPS_VALID; | 116 return IDR_OMNIBOX_HTTPS_VALID; |
| 141 case SecurityStateModel::SECURITY_WARNING: | 117 case SecurityStateModel::SECURITY_WARNING: |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 170 #endif | 146 #endif |
| 171 | 147 |
| 172 NOTREACHED(); | 148 NOTREACHED(); |
| 173 return gfx::VectorIconId::VECTOR_ICON_NONE; | 149 return gfx::VectorIconId::VECTOR_ICON_NONE; |
| 174 } | 150 } |
| 175 | 151 |
| 176 base::string16 ToolbarModelImpl::GetEVCertName() const { | 152 base::string16 ToolbarModelImpl::GetEVCertName() const { |
| 177 if (GetSecurityLevel(false) != SecurityStateModel::EV_SECURE) | 153 if (GetSecurityLevel(false) != SecurityStateModel::EV_SECURE) |
| 178 return base::string16(); | 154 return base::string16(); |
| 179 | 155 |
| 180 // Note: Navigation controller and active entry are guaranteed non-NULL or | 156 // Note: cert is guaranteed non-NULL or the security level would be NONE. |
| 181 // the security level would be NONE. | 157 scoped_refptr<net::X509Certificate> cert = delegate_->GetCertificate(); |
| 182 scoped_refptr<net::X509Certificate> cert; | 158 DCHECK(cert.get()); |
| 183 content::CertStore::GetInstance()->RetrieveCert( | |
| 184 GetNavigationController()->GetVisibleEntry()->GetSSL().cert_id, &cert); | |
| 185 | 159 |
| 186 // EV are required to have an organization name and country. | 160 // EV are required to have an organization name and country. |
| 187 DCHECK(!cert->subject().organization_names.empty()); | 161 DCHECK(!cert->subject().organization_names.empty()); |
| 188 DCHECK(!cert->subject().country_name.empty()); | 162 DCHECK(!cert->subject().country_name.empty()); |
| 189 return l10n_util::GetStringFUTF16( | 163 return l10n_util::GetStringFUTF16( |
| 190 IDS_SECURE_CONNECTION_EV, | 164 IDS_SECURE_CONNECTION_EV, |
| 191 base::UTF8ToUTF16(cert->subject().organization_names[0]), | 165 base::UTF8ToUTF16(cert->subject().organization_names[0]), |
| 192 base::UTF8ToUTF16(cert->subject().country_name)); | 166 base::UTF8ToUTF16(cert->subject().country_name)); |
| 193 } | 167 } |
| 194 | 168 |
| 195 bool ToolbarModelImpl::ShouldDisplayURL() const { | 169 bool ToolbarModelImpl::ShouldDisplayURL() const { |
| 196 // Note: The order here is important. | 170 return delegate_->ShouldDisplayURL(); |
| 197 // - The WebUI test must come before the extension scheme test because there | |
| 198 // can be WebUIs that have extension schemes (e.g. the bookmark manager). In | |
| 199 // that case, we should prefer what the WebUI instance says. | |
| 200 // - The view-source test must come before the NTP test because of the case | |
| 201 // of view-source:chrome://newtab, which should display its URL despite what | |
| 202 // chrome://newtab says. | |
| 203 NavigationController* controller = GetNavigationController(); | |
| 204 NavigationEntry* entry = controller ? controller->GetVisibleEntry() : NULL; | |
| 205 if (entry) { | |
| 206 if (entry->IsViewSourceMode() || | |
| 207 entry->GetPageType() == content::PAGE_TYPE_INTERSTITIAL) { | |
| 208 return true; | |
| 209 } | |
| 210 | |
| 211 GURL url = entry->GetURL(); | |
| 212 GURL virtual_url = entry->GetVirtualURL(); | |
| 213 if (url.SchemeIs(content::kChromeUIScheme) || | |
| 214 virtual_url.SchemeIs(content::kChromeUIScheme)) { | |
| 215 if (!url.SchemeIs(content::kChromeUIScheme)) | |
| 216 url = virtual_url; | |
| 217 return url.host() != chrome::kChromeUINewTabHost; | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 return !search::IsInstantNTP(delegate_->GetActiveWebContents()); | |
| 222 } | |
| 223 | |
| 224 NavigationController* ToolbarModelImpl::GetNavigationController() const { | |
| 225 // This |current_tab| can be NULL during the initialization of the | |
| 226 // toolbar during window creation (i.e. before any tabs have been added | |
| 227 // to the window). | |
| 228 WebContents* current_tab = delegate_->GetActiveWebContents(); | |
| 229 return current_tab ? ¤t_tab->GetController() : NULL; | |
| 230 } | 171 } |
| 231 | 172 |
| 232 base::string16 ToolbarModelImpl::GetSearchTerms(bool ignore_editing) const { | 173 base::string16 ToolbarModelImpl::GetSearchTerms(bool ignore_editing) const { |
| 233 if (!url_replacement_enabled() || (input_in_progress() && !ignore_editing)) | 174 if (!url_replacement_enabled() || (input_in_progress() && !ignore_editing)) |
| 234 return base::string16(); | 175 return base::string16(); |
| 235 | 176 |
| 236 const WebContents* web_contents = delegate_->GetActiveWebContents(); | 177 return delegate_->GetSearchTerms(GetSecurityLevel(ignore_editing)); |
| 237 base::string16 search_terms(search::GetSearchTerms(web_contents)); | |
| 238 if (search_terms.empty()) { | |
| 239 // We mainly do this to enforce the subsequent DCHECK. | |
| 240 return base::string16(); | |
| 241 } | |
| 242 | |
| 243 // If the page is still loading and the security style is unknown, consider | |
| 244 // the page secure. Without this, after the user hit enter on some search | |
| 245 // terms, the omnibox would change to displaying the loading URL before | |
| 246 // changing back to the search terms once they could be extracted, thus | |
| 247 // causing annoying flicker. | |
| 248 DCHECK(web_contents); | |
| 249 const NavigationController& nav_controller = web_contents->GetController(); | |
| 250 const NavigationEntry* entry = nav_controller.GetVisibleEntry(); | |
| 251 if ((entry != nav_controller.GetLastCommittedEntry()) && | |
| 252 (entry->GetSSL().security_style == content::SECURITY_STYLE_UNKNOWN)) | |
| 253 return search_terms; | |
| 254 | |
| 255 // If the URL is using a Google base URL specified via the command line, we | |
| 256 // bypass the security check below. | |
| 257 if (entry && | |
| 258 google_util::StartsWithCommandLineGoogleBaseURL(entry->GetVirtualURL())) | |
| 259 return search_terms; | |
| 260 | |
| 261 // Otherwise, extract search terms for HTTPS pages that do not have a security | |
| 262 // error. | |
| 263 SecurityStateModel::SecurityLevel security_level = | |
| 264 GetSecurityLevel(ignore_editing); | |
| 265 return ((security_level == SecurityStateModel::NONE) || | |
| 266 (security_level == SecurityStateModel::SECURITY_ERROR)) | |
| 267 ? base::string16() | |
| 268 : search_terms; | |
| 269 } | 178 } |
| OLD | NEW |