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 |