Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: chrome/browser/autocomplete/search_provider.cc

Issue 131003011: Part 1 of search provider refactoring. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: change wrapping back Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/autocomplete/search_provider.h" 5 #include "chrome/browser/autocomplete/search_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/i18n/break_iterator.h" 11 #include "base/i18n/break_iterator.h"
12 #include "base/i18n/case_conversion.h" 12 #include "base/i18n/case_conversion.h"
13 #include "base/i18n/icu_string_conversions.h" 13 #include "base/i18n/icu_string_conversions.h"
14 #include "base/json/json_string_value_serializer.h" 14 #include "base/json/json_string_value_serializer.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_service.h" 17 #include "base/prefs/pref_service.h"
18 #include "base/strings/string16.h" 18 #include "base/strings/string16.h"
19 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "chrome/browser/autocomplete/autocomplete_classifier.h" 21 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
22 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" 22 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
23 #include "chrome/browser/autocomplete/autocomplete_match.h" 23 #include "chrome/browser/autocomplete/autocomplete_match.h"
msw 2014/02/03 22:53:14 nit: remove redundant includes from search_provide
Maria 2014/02/04 03:16:39 Done.
24 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" 24 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
25 #include "chrome/browser/autocomplete/autocomplete_result.h" 25 #include "chrome/browser/autocomplete/autocomplete_result.h"
26 #include "chrome/browser/autocomplete/base_search_provider.h"
msw 2014/02/03 22:53:14 nit: remove this; it's included in search_provider
Maria 2014/02/04 03:16:39 Done.
26 #include "chrome/browser/autocomplete/keyword_provider.h" 27 #include "chrome/browser/autocomplete/keyword_provider.h"
27 #include "chrome/browser/autocomplete/url_prefix.h" 28 #include "chrome/browser/autocomplete/url_prefix.h"
28 #include "chrome/browser/google/google_util.h" 29 #include "chrome/browser/google/google_util.h"
29 #include "chrome/browser/history/history_service.h" 30 #include "chrome/browser/history/history_service.h"
30 #include "chrome/browser/history/history_service_factory.h" 31 #include "chrome/browser/history/history_service_factory.h"
31 #include "chrome/browser/history/in_memory_database.h" 32 #include "chrome/browser/history/in_memory_database.h"
32 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" 33 #include "chrome/browser/metrics/variations/variations_http_header_provider.h"
33 #include "chrome/browser/omnibox/omnibox_field_trial.h" 34 #include "chrome/browser/omnibox/omnibox_field_trial.h"
34 #include "chrome/browser/profiles/profile.h" 35 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/search/search.h" 36 #include "chrome/browser/search/search.h"
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 DCHECK(source == deletion_fetcher_.get()); 169 DCHECK(source == deletion_fetcher_.get());
169 callback_.Run( 170 callback_.Run(
170 source->GetStatus().is_success() && (source->GetResponseCode() == 200), 171 source->GetStatus().is_success() && (source->GetResponseCode() == 200),
171 this); 172 this);
172 }; 173 };
173 174
174 175
175 // SearchProvider::Providers -------------------------------------------------- 176 // SearchProvider::Providers --------------------------------------------------
176 177
177 SearchProvider::Providers::Providers(TemplateURLService* template_url_service) 178 SearchProvider::Providers::Providers(TemplateURLService* template_url_service)
178 : template_url_service_(template_url_service) { 179 : template_url_service_(template_url_service) {}
179 }
180 180
181 const TemplateURL* SearchProvider::Providers::GetDefaultProviderURL() const { 181 const TemplateURL* SearchProvider::Providers::GetDefaultProviderURL() const {
182 return default_provider_.empty() ? NULL : 182 return default_provider_.empty() ? NULL :
183 template_url_service_->GetTemplateURLForKeyword(default_provider_); 183 template_url_service_->GetTemplateURLForKeyword(default_provider_);
184 } 184 }
185 185
186 const TemplateURL* SearchProvider::Providers::GetKeywordProviderURL() const { 186 const TemplateURL* SearchProvider::Providers::GetKeywordProviderURL() const {
187 return keyword_provider_.empty() ? NULL : 187 return keyword_provider_.empty() ? NULL :
188 template_url_service_->GetTemplateURLForKeyword(keyword_provider_); 188 template_url_service_->GetTemplateURLForKeyword(keyword_provider_);
189 } 189 }
190 190
191 191
192 // SearchProvider::Result -----------------------------------------------------
193
194 SearchProvider::Result::Result(bool from_keyword_provider,
195 int relevance,
196 bool relevance_from_server)
197 : from_keyword_provider_(from_keyword_provider),
198 relevance_(relevance),
199 relevance_from_server_(relevance_from_server) {
200 }
201
202 SearchProvider::Result::~Result() {
203 }
204
205
206 // SearchProvider::SuggestResult ----------------------------------------------
207
208 SearchProvider::SuggestResult::SuggestResult(
209 const base::string16& suggestion,
210 AutocompleteMatchType::Type type,
211 const base::string16& match_contents,
212 const base::string16& annotation,
213 const std::string& suggest_query_params,
214 const std::string& deletion_url,
215 bool from_keyword_provider,
216 int relevance,
217 bool relevance_from_server,
218 bool should_prefetch,
219 const base::string16& input_text)
220 : Result(from_keyword_provider, relevance, relevance_from_server),
221 suggestion_(suggestion),
222 type_(type),
223 annotation_(annotation),
224 suggest_query_params_(suggest_query_params),
225 deletion_url_(deletion_url),
226 should_prefetch_(should_prefetch) {
227 match_contents_ = match_contents;
228 DCHECK(!match_contents_.empty());
229 ClassifyMatchContents(true, input_text);
230 }
231
232 SearchProvider::SuggestResult::~SuggestResult() {
233 }
234
235 void SearchProvider::SuggestResult::ClassifyMatchContents(
236 const bool allow_bolding_all,
237 const base::string16& input_text) {
238 size_t input_position = match_contents_.find(input_text);
239 if (!allow_bolding_all && (input_position == base::string16::npos)) {
240 // Bail if the code below to update the bolding would bold the whole
241 // string. Note that the string may already be entirely bolded; if
242 // so, leave it as is.
243 return;
244 }
245 match_contents_class_.clear();
246 // We do intra-string highlighting for suggestions - the suggested segment
247 // will be highlighted, e.g. for input_text = "you" the suggestion may be
248 // "youtube", so we'll bold the "tube" section: you*tube*.
249 if (input_text != match_contents_) {
250 if (input_position == base::string16::npos) {
251 // The input text is not a substring of the query string, e.g. input
252 // text is "slasdot" and the query string is "slashdot", so we bold the
253 // whole thing.
254 match_contents_class_.push_back(ACMatchClassification(
255 0, ACMatchClassification::MATCH));
256 } else {
257 // We don't iterate over the string here annotating all matches because
258 // it looks odd to have every occurrence of a substring that may be as
259 // short as a single character highlighted in a query suggestion result,
260 // e.g. for input text "s" and query string "southwest airlines", it
261 // looks odd if both the first and last s are highlighted.
262 if (input_position != 0) {
263 match_contents_class_.push_back(ACMatchClassification(
264 0, ACMatchClassification::MATCH));
265 }
266 match_contents_class_.push_back(
267 ACMatchClassification(input_position, ACMatchClassification::NONE));
268 size_t next_fragment_position = input_position + input_text.length();
269 if (next_fragment_position < match_contents_.length()) {
270 match_contents_class_.push_back(ACMatchClassification(
271 next_fragment_position, ACMatchClassification::MATCH));
272 }
273 }
274 } else {
275 // Otherwise, match_contents_ is a verbatim (what-you-typed) match, either
276 // for the default provider or a keyword search provider.
277 match_contents_class_.push_back(ACMatchClassification(
278 0, ACMatchClassification::NONE));
279 }
280 }
281
282 bool SearchProvider::SuggestResult::IsInlineable(
283 const base::string16& input) const {
284 return StartsWith(suggestion_, input, false);
285 }
286
287 int SearchProvider::SuggestResult::CalculateRelevance(
288 const AutocompleteInput& input,
289 bool keyword_provider_requested) const {
290 if (!from_keyword_provider_ && keyword_provider_requested)
291 return 100;
292 return ((input.type() == AutocompleteInput::URL) ? 300 : 600);
293 }
294
295
296 // SearchProvider::NavigationResult -------------------------------------------
297
298 SearchProvider::NavigationResult::NavigationResult(
299 const AutocompleteProvider& provider,
300 const GURL& url,
301 const base::string16& description,
302 bool from_keyword_provider,
303 int relevance,
304 bool relevance_from_server,
305 const base::string16& input_text,
306 const std::string& languages)
307 : Result(from_keyword_provider, relevance, relevance_from_server),
308 url_(url),
309 formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning(
310 url, provider.StringForURLDisplay(url, true, false))),
311 description_(description) {
312 DCHECK(url_.is_valid());
313 CalculateAndClassifyMatchContents(true, input_text, languages);
314 }
315
316 SearchProvider::NavigationResult::~NavigationResult() {
317 }
318
319 void SearchProvider::NavigationResult::CalculateAndClassifyMatchContents(
320 const bool allow_bolding_nothing,
321 const base::string16& input_text,
322 const std::string& languages) {
323 // First look for the user's input inside the formatted url as it would be
324 // without trimming the scheme, so we can find matches at the beginning of the
325 // scheme.
326 const URLPrefix* prefix =
327 URLPrefix::BestURLPrefix(formatted_url_, input_text);
328 size_t match_start = (prefix == NULL) ?
329 formatted_url_.find(input_text) : prefix->prefix.length();
330 bool trim_http = !AutocompleteInput::HasHTTPScheme(input_text) &&
331 (!prefix || (match_start != 0));
332 const net::FormatUrlTypes format_types =
333 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
334
335 base::string16 match_contents = net::FormatUrl(url_, languages, format_types,
336 net::UnescapeRule::SPACES, NULL, NULL, &match_start);
337 // If the first match in the untrimmed string was inside a scheme that we
338 // trimmed, look for a subsequent match.
339 if (match_start == base::string16::npos)
340 match_start = match_contents.find(input_text);
341 // Update |match_contents_| and |match_contents_class_| if it's allowed.
342 if (allow_bolding_nothing || (match_start != base::string16::npos)) {
343 match_contents_ = match_contents;
344 // Safe if |match_start| is npos; also safe if the input is longer than the
345 // remaining contents after |match_start|.
346 AutocompleteMatch::ClassifyLocationInString(match_start,
347 input_text.length(), match_contents_.length(),
348 ACMatchClassification::URL, &match_contents_class_);
349 }
350 }
351
352 bool SearchProvider::NavigationResult::IsInlineable(
353 const base::string16& input) const {
354 return URLPrefix::BestURLPrefix(formatted_url_, input) != NULL;
355 }
356
357 int SearchProvider::NavigationResult::CalculateRelevance(
358 const AutocompleteInput& input,
359 bool keyword_provider_requested) const {
360 return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150;
361 }
362
363
364 // SearchProvider::CompareScoredResults --------------------------------------- 192 // SearchProvider::CompareScoredResults ---------------------------------------
365 193
366 class SearchProvider::CompareScoredResults { 194 class SearchProvider::CompareScoredResults {
367 public: 195 public:
368 bool operator()(const Result& a, const Result& b) { 196 bool operator()(const Result& a, const Result& b) {
369 // Sort in descending relevance order. 197 // Sort in descending relevance order.
370 return a.relevance() > b.relevance(); 198 return a.relevance() > b.relevance();
371 } 199 }
372 }; 200 };
373 201
374 202
375 // SearchProvider::Results ----------------------------------------------------
376
377 SearchProvider::Results::Results() : verbatim_relevance(-1) {
378 }
379
380 SearchProvider::Results::~Results() {
381 }
382
383 void SearchProvider::Results::Clear() {
384 suggest_results.clear();
385 navigation_results.clear();
386 verbatim_relevance = -1;
387 metadata.clear();
388 }
389
390 bool SearchProvider::Results::HasServerProvidedScores() const {
391 if (verbatim_relevance >= 0)
392 return true;
393
394 // Right now either all results of one type will be server-scored or they will
395 // all be locally scored, but in case we change this later, we'll just check
396 // them all.
397 for (SuggestResults::const_iterator i(suggest_results.begin());
398 i != suggest_results.end(); ++i) {
399 if (i->relevance_from_server())
400 return true;
401 }
402 for (NavigationResults::const_iterator i(navigation_results.begin());
403 i != navigation_results.end(); ++i) {
404 if (i->relevance_from_server())
405 return true;
406 }
407
408 return false;
409 }
410
411
412 // SearchProvider ------------------------------------------------------------- 203 // SearchProvider -------------------------------------------------------------
413 204
414 // static 205 // static
415 const int SearchProvider::kDefaultProviderURLFetcherID = 1; 206 const int SearchProvider::kDefaultProviderURLFetcherID = 1;
416 const int SearchProvider::kKeywordProviderURLFetcherID = 2; 207 const int SearchProvider::kKeywordProviderURLFetcherID = 2;
417 const int SearchProvider::kDeletionURLFetcherID = 3; 208 const int SearchProvider::kDeletionURLFetcherID = 3;
418 int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100; 209 int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100;
419 const char SearchProvider::kRelevanceFromServerKey[] = "relevance_from_server"; 210 const char SearchProvider::kRelevanceFromServerKey[] = "relevance_from_server";
420 const char SearchProvider::kShouldPrefetchKey[] = "should_prefetch"; 211 const char SearchProvider::kShouldPrefetchKey[] = "should_prefetch";
421 const char SearchProvider::kSuggestMetadataKey[] = "suggest_metadata"; 212 const char SearchProvider::kSuggestMetadataKey[] = "suggest_metadata";
422 const char SearchProvider::kDeletionUrlKey[] = "deletion_url"; 213 const char SearchProvider::kDeletionUrlKey[] = "deletion_url";
423 const char SearchProvider::kTrue[] = "true"; 214 const char SearchProvider::kTrue[] = "true";
424 const char SearchProvider::kFalse[] = "false"; 215 const char SearchProvider::kFalse[] = "false";
425 216
426 SearchProvider::SearchProvider(AutocompleteProviderListener* listener, 217 SearchProvider::SearchProvider(AutocompleteProviderListener* listener,
427 Profile* profile) 218 Profile* profile)
428 : AutocompleteProvider(listener, profile, 219 : BaseSearchProvider(listener, profile, AutocompleteProvider::TYPE_SEARCH),
429 AutocompleteProvider::TYPE_SEARCH),
430 providers_(TemplateURLServiceFactory::GetForProfile(profile)), 220 providers_(TemplateURLServiceFactory::GetForProfile(profile)),
431 suggest_results_pending_(0), 221 suggest_results_pending_(0),
432 field_trial_triggered_(false), 222 field_trial_triggered_(false),
433 field_trial_triggered_in_session_(false) { 223 field_trial_triggered_in_session_(false) {
434 } 224 }
435 225
436 // static 226 // static
437 AutocompleteMatch SearchProvider::CreateSearchSuggestion( 227 AutocompleteMatch SearchProvider::CreateSearchSuggestion(
438 AutocompleteProvider* autocomplete_provider, 228 AutocompleteProvider* autocomplete_provider,
439 const AutocompleteInput& input, 229 const AutocompleteInput& input,
(...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
2088 if (!OmniboxFieldTrial::InZeroSuggestFieldTrial() || 1878 if (!OmniboxFieldTrial::InZeroSuggestFieldTrial() ||
2089 service == NULL || 1879 service == NULL ||
2090 !service->IsSyncEnabledAndLoggedIn() || 1880 !service->IsSyncEnabledAndLoggedIn() ||
2091 !sync_prefs.GetPreferredDataTypes(syncer::UserTypes()).Has( 1881 !sync_prefs.GetPreferredDataTypes(syncer::UserTypes()).Has(
2092 syncer::PROXY_TABS) || 1882 syncer::PROXY_TABS) ||
2093 service->GetEncryptedDataTypes().Has(syncer::SESSIONS)) 1883 service->GetEncryptedDataTypes().Has(syncer::SESSIONS))
2094 return false; 1884 return false;
2095 1885
2096 return true; 1886 return true;
2097 } 1887 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698