OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/autocomplete_controller.h" | 5 #include "chrome/browser/autocomplete/autocomplete_controller.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
16 #include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" | 16 #include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" |
17 #include "chrome/browser/autocomplete/bookmark_provider.h" | 17 #include "chrome/browser/autocomplete/bookmark_provider.h" |
18 #include "chrome/browser/autocomplete/builtin_provider.h" | 18 #include "chrome/browser/autocomplete/builtin_provider.h" |
19 #include "chrome/browser/autocomplete/history_quick_provider.h" | 19 #include "chrome/browser/autocomplete/history_quick_provider.h" |
20 #include "chrome/browser/autocomplete/history_url_provider.h" | 20 #include "chrome/browser/autocomplete/history_url_provider.h" |
21 #include "chrome/browser/autocomplete/keyword_provider.h" | 21 #include "chrome/browser/autocomplete/keyword_provider.h" |
22 #include "chrome/browser/autocomplete/search_provider.h" | 22 #include "chrome/browser/autocomplete/search_provider.h" |
23 #include "chrome/browser/autocomplete/shortcuts_provider.h" | 23 #include "chrome/browser/autocomplete/shortcuts_provider.h" |
24 #include "chrome/browser/autocomplete/zero_suggest_provider.h" | 24 #include "chrome/browser/autocomplete/zero_suggest_provider.h" |
25 #include "chrome/browser/chrome_notification_types.h" | 25 #include "chrome/browser/chrome_notification_types.h" |
26 #include "chrome/browser/omnibox/omnibox_field_trial.h" | 26 #include "chrome/browser/omnibox/omnibox_field_trial.h" |
27 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/search_engines/template_url_service.h" |
28 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" | |
29 #include "components/search_engines/template_url.h" | 28 #include "components/search_engines/template_url.h" |
30 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
31 #include "grit/generated_resources.h" | 30 #include "grit/generated_resources.h" |
32 #include "grit/theme_resources.h" | 31 #include "grit/theme_resources.h" |
33 #include "ui/base/l10n/l10n_util.h" | 32 #include "ui/base/l10n/l10n_util.h" |
34 | 33 |
35 namespace { | 34 namespace { |
36 | 35 |
37 // Converts the given match to a type (and possibly subtype) based on the AQS | 36 // Converts the given match to a type (and possibly subtype) based on the AQS |
38 // specification. For more details, see | 37 // specification. For more details, see |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 // Whether this autocomplete match type supports custom descriptions. | 162 // Whether this autocomplete match type supports custom descriptions. |
164 bool AutocompleteMatchHasCustomDescription(const AutocompleteMatch& match) { | 163 bool AutocompleteMatchHasCustomDescription(const AutocompleteMatch& match) { |
165 return match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY || | 164 return match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY || |
166 match.type == AutocompleteMatchType::SEARCH_SUGGEST_PROFILE; | 165 match.type == AutocompleteMatchType::SEARCH_SUGGEST_PROFILE; |
167 } | 166 } |
168 | 167 |
169 } // namespace | 168 } // namespace |
170 | 169 |
171 AutocompleteController::AutocompleteController( | 170 AutocompleteController::AutocompleteController( |
172 Profile* profile, | 171 Profile* profile, |
| 172 TemplateURLService* template_url_service, |
173 AutocompleteControllerDelegate* delegate, | 173 AutocompleteControllerDelegate* delegate, |
174 int provider_types) | 174 int provider_types) |
175 : delegate_(delegate), | 175 : delegate_(delegate), |
176 history_url_provider_(NULL), | 176 history_url_provider_(NULL), |
177 keyword_provider_(NULL), | 177 keyword_provider_(NULL), |
178 search_provider_(NULL), | 178 search_provider_(NULL), |
179 zero_suggest_provider_(NULL), | 179 zero_suggest_provider_(NULL), |
180 stop_timer_duration_(OmniboxFieldTrial::StopTimerFieldTrialDuration()), | 180 stop_timer_duration_(OmniboxFieldTrial::StopTimerFieldTrialDuration()), |
181 done_(true), | 181 done_(true), |
182 in_start_(false), | 182 in_start_(false), |
183 profile_(profile) { | 183 template_url_service_(template_url_service) { |
184 provider_types &= ~OmniboxFieldTrial::GetDisabledProviderTypes(); | 184 provider_types &= ~OmniboxFieldTrial::GetDisabledProviderTypes(); |
185 if (provider_types & AutocompleteProvider::TYPE_BOOKMARK) | 185 if (provider_types & AutocompleteProvider::TYPE_BOOKMARK) |
186 providers_.push_back(new BookmarkProvider(this, profile)); | 186 providers_.push_back(new BookmarkProvider(this, profile)); |
187 if (provider_types & AutocompleteProvider::TYPE_BUILTIN) | 187 if (provider_types & AutocompleteProvider::TYPE_BUILTIN) |
188 providers_.push_back(new BuiltinProvider(this, profile)); | 188 providers_.push_back(new BuiltinProvider(this, profile)); |
189 if (provider_types & AutocompleteProvider::TYPE_HISTORY_QUICK) | 189 if (provider_types & AutocompleteProvider::TYPE_HISTORY_QUICK) |
190 providers_.push_back(new HistoryQuickProvider(this, profile)); | 190 providers_.push_back(new HistoryQuickProvider(this, profile)); |
191 if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) { | 191 if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) { |
192 history_url_provider_ = new HistoryURLProvider(this, profile); | 192 history_url_provider_ = new HistoryURLProvider(this, profile); |
193 providers_.push_back(history_url_provider_); | 193 providers_.push_back(history_url_provider_); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 395 |
396 void AutocompleteController::ResetSession() { | 396 void AutocompleteController::ResetSession() { |
397 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end(); | 397 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end(); |
398 ++i) | 398 ++i) |
399 (*i)->ResetSession(); | 399 (*i)->ResetSession(); |
400 } | 400 } |
401 | 401 |
402 void AutocompleteController::UpdateMatchDestinationURL( | 402 void AutocompleteController::UpdateMatchDestinationURL( |
403 base::TimeDelta query_formulation_time, | 403 base::TimeDelta query_formulation_time, |
404 AutocompleteMatch* match) const { | 404 AutocompleteMatch* match) const { |
405 TemplateURL* template_url = match->GetTemplateURL(profile_, false); | 405 TemplateURL* template_url = match->GetTemplateURL( |
| 406 template_url_service_, false); |
406 if (!template_url || !match->search_terms_args.get() || | 407 if (!template_url || !match->search_terms_args.get() || |
407 match->search_terms_args->assisted_query_stats.empty()) | 408 match->search_terms_args->assisted_query_stats.empty()) |
408 return; | 409 return; |
409 | 410 |
410 // Append the query formulation time (time from when the user first typed a | 411 // Append the query formulation time (time from when the user first typed a |
411 // character into the omnibox to when the user selected a query) and whether | 412 // character into the omnibox to when the user selected a query) and whether |
412 // a field trial has triggered to the AQS parameter. | 413 // a field trial has triggered to the AQS parameter. |
413 TemplateURLRef::SearchTermsArgs search_terms_args(*match->search_terms_args); | 414 TemplateURLRef::SearchTermsArgs search_terms_args(*match->search_terms_args); |
414 search_terms_args.assisted_query_stats += base::StringPrintf( | 415 search_terms_args.assisted_query_stats += base::StringPrintf( |
415 ".%" PRId64 "j%dj%d", | 416 ".%" PRId64 "j%dj%d", |
416 query_formulation_time.InMilliseconds(), | 417 query_formulation_time.InMilliseconds(), |
417 (search_provider_ && | 418 (search_provider_ && |
418 search_provider_->field_trial_triggered_in_session()) || | 419 search_provider_->field_trial_triggered_in_session()) || |
419 (zero_suggest_provider_ && | 420 (zero_suggest_provider_ && |
420 zero_suggest_provider_->field_trial_triggered_in_session()), | 421 zero_suggest_provider_->field_trial_triggered_in_session()), |
421 input_.current_page_classification()); | 422 input_.current_page_classification()); |
422 match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( | 423 match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( |
423 search_terms_args, UIThreadSearchTermsData(profile_))); | 424 search_terms_args, template_url_service_->search_terms_data())); |
424 } | 425 } |
425 | 426 |
426 void AutocompleteController::UpdateResult( | 427 void AutocompleteController::UpdateResult( |
427 bool regenerate_result, | 428 bool regenerate_result, |
428 bool force_notify_default_match_changed) { | 429 bool force_notify_default_match_changed) { |
429 const bool last_default_was_valid = result_.default_match() != result_.end(); | 430 const bool last_default_was_valid = result_.default_match() != result_.end(); |
430 // The following three variables are only set and used if | 431 // The following three variables are only set and used if |
431 // |last_default_was_valid|. | 432 // |last_default_was_valid|. |
432 base::string16 last_default_fill_into_edit, last_default_keyword, | 433 base::string16 last_default_fill_into_edit, last_default_keyword, |
433 last_default_associated_keyword; | 434 last_default_associated_keyword; |
434 if (last_default_was_valid) { | 435 if (last_default_was_valid) { |
435 last_default_fill_into_edit = result_.default_match()->fill_into_edit; | 436 last_default_fill_into_edit = result_.default_match()->fill_into_edit; |
436 last_default_keyword = result_.default_match()->keyword; | 437 last_default_keyword = result_.default_match()->keyword; |
437 if (result_.default_match()->associated_keyword != NULL) | 438 if (result_.default_match()->associated_keyword != NULL) |
438 last_default_associated_keyword = | 439 last_default_associated_keyword = |
439 result_.default_match()->associated_keyword->keyword; | 440 result_.default_match()->associated_keyword->keyword; |
440 } | 441 } |
441 | 442 |
442 if (regenerate_result) | 443 if (regenerate_result) |
443 result_.Reset(); | 444 result_.Reset(); |
444 | 445 |
445 AutocompleteResult last_result; | 446 AutocompleteResult last_result; |
446 last_result.Swap(&result_); | 447 last_result.Swap(&result_); |
447 | 448 |
448 for (ACProviders::const_iterator i(providers_.begin()); | 449 for (ACProviders::const_iterator i(providers_.begin()); |
449 i != providers_.end(); ++i) | 450 i != providers_.end(); ++i) |
450 result_.AppendMatches((*i)->matches()); | 451 result_.AppendMatches((*i)->matches()); |
451 | 452 |
452 // Sort the matches and trim to a small number of "best" matches. | 453 // Sort the matches and trim to a small number of "best" matches. |
453 result_.SortAndCull(input_, profile_); | 454 result_.SortAndCull(input_, template_url_service_); |
454 | 455 |
455 // Need to validate before invoking CopyOldMatches as the old matches are not | 456 // Need to validate before invoking CopyOldMatches as the old matches are not |
456 // valid against the current input. | 457 // valid against the current input. |
457 #ifndef NDEBUG | 458 #ifndef NDEBUG |
458 result_.Validate(); | 459 result_.Validate(); |
459 #endif | 460 #endif |
460 | 461 |
461 if (!done_) { | 462 if (!done_) { |
462 // This conditional needs to match the conditional in Start that invokes | 463 // This conditional needs to match the conditional in Start that invokes |
463 // StartExpireTimer. | 464 // StartExpireTimer. |
464 result_.CopyOldMatches(input_, last_result, profile_); | 465 result_.CopyOldMatches(input_, last_result, template_url_service_); |
465 } | 466 } |
466 | 467 |
467 UpdateKeywordDescriptions(&result_); | 468 UpdateKeywordDescriptions(&result_); |
468 UpdateAssociatedKeywords(&result_); | 469 UpdateAssociatedKeywords(&result_); |
469 UpdateAssistedQueryStats(&result_); | 470 UpdateAssistedQueryStats(&result_); |
470 | 471 |
471 const bool default_is_valid = result_.default_match() != result_.end(); | 472 const bool default_is_valid = result_.default_match() != result_.end(); |
472 base::string16 default_associated_keyword; | 473 base::string16 default_associated_keyword; |
473 if (default_is_valid && | 474 if (default_is_valid && |
474 (result_.default_match()->associated_keyword != NULL)) { | 475 (result_.default_match()->associated_keyword != NULL)) { |
(...skipping 24 matching lines...) Expand all Loading... |
499 | 500 |
500 void AutocompleteController::UpdateAssociatedKeywords( | 501 void AutocompleteController::UpdateAssociatedKeywords( |
501 AutocompleteResult* result) { | 502 AutocompleteResult* result) { |
502 if (!keyword_provider_) | 503 if (!keyword_provider_) |
503 return; | 504 return; |
504 | 505 |
505 std::set<base::string16> keywords; | 506 std::set<base::string16> keywords; |
506 for (ACMatches::iterator match(result->begin()); match != result->end(); | 507 for (ACMatches::iterator match(result->begin()); match != result->end(); |
507 ++match) { | 508 ++match) { |
508 base::string16 keyword( | 509 base::string16 keyword( |
509 match->GetSubstitutingExplicitlyInvokedKeyword(profile_)); | 510 match->GetSubstitutingExplicitlyInvokedKeyword(template_url_service_)); |
510 if (!keyword.empty()) { | 511 if (!keyword.empty()) { |
511 keywords.insert(keyword); | 512 keywords.insert(keyword); |
512 continue; | 513 continue; |
513 } | 514 } |
514 | 515 |
515 // Only add the keyword if the match does not have a duplicate keyword with | 516 // Only add the keyword if the match does not have a duplicate keyword with |
516 // a more relevant match. | 517 // a more relevant match. |
517 keyword = match->associated_keyword.get() ? | 518 keyword = match->associated_keyword.get() ? |
518 match->associated_keyword->keyword : | 519 match->associated_keyword->keyword : |
519 keyword_provider_->GetKeywordForText(match->fill_into_edit); | 520 keyword_provider_->GetKeywordForText(match->fill_into_edit); |
(...skipping 15 matching lines...) Expand all Loading... |
535 base::string16 last_keyword; | 536 base::string16 last_keyword; |
536 for (AutocompleteResult::iterator i(result->begin()); i != result->end(); | 537 for (AutocompleteResult::iterator i(result->begin()); i != result->end(); |
537 ++i) { | 538 ++i) { |
538 if (AutocompleteMatch::IsSearchType(i->type)) { | 539 if (AutocompleteMatch::IsSearchType(i->type)) { |
539 if (AutocompleteMatchHasCustomDescription(*i)) | 540 if (AutocompleteMatchHasCustomDescription(*i)) |
540 continue; | 541 continue; |
541 i->description.clear(); | 542 i->description.clear(); |
542 i->description_class.clear(); | 543 i->description_class.clear(); |
543 DCHECK(!i->keyword.empty()); | 544 DCHECK(!i->keyword.empty()); |
544 if (i->keyword != last_keyword) { | 545 if (i->keyword != last_keyword) { |
545 const TemplateURL* template_url = i->GetTemplateURL(profile_, false); | 546 const TemplateURL* template_url = |
| 547 i->GetTemplateURL(template_url_service_, false); |
546 if (template_url) { | 548 if (template_url) { |
547 // For extension keywords, just make the description the extension | 549 // For extension keywords, just make the description the extension |
548 // name -- don't assume that the normal search keyword description is | 550 // name -- don't assume that the normal search keyword description is |
549 // applicable. | 551 // applicable. |
550 i->description = template_url->AdjustedShortNameForLocaleDirection(); | 552 i->description = template_url->AdjustedShortNameForLocaleDirection(); |
551 if (template_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION) { | 553 if (template_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION) { |
552 i->description = l10n_util::GetStringFUTF16( | 554 i->description = l10n_util::GetStringFUTF16( |
553 IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION, i->description); | 555 IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION, i->description); |
554 } | 556 } |
555 i->description_class.push_back( | 557 i->description_class.push_back( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 count++; | 590 count++; |
589 } | 591 } |
590 last_type = type; | 592 last_type = type; |
591 last_subtype = subtype; | 593 last_subtype = subtype; |
592 } | 594 } |
593 AppendAvailableAutocompletion( | 595 AppendAvailableAutocompletion( |
594 last_type, last_subtype, count, &autocompletions); | 596 last_type, last_subtype, count, &autocompletions); |
595 // Go over all matches and set AQS if the match supports it. | 597 // Go over all matches and set AQS if the match supports it. |
596 for (size_t index = 0; index < result->size(); ++index) { | 598 for (size_t index = 0; index < result->size(); ++index) { |
597 AutocompleteMatch* match = result->match_at(index); | 599 AutocompleteMatch* match = result->match_at(index); |
598 const TemplateURL* template_url = match->GetTemplateURL(profile_, false); | 600 const TemplateURL* template_url = |
| 601 match->GetTemplateURL(template_url_service_, false); |
599 if (!template_url || !match->search_terms_args.get()) | 602 if (!template_url || !match->search_terms_args.get()) |
600 continue; | 603 continue; |
601 std::string selected_index; | 604 std::string selected_index; |
602 // Prevent trivial suggestions from getting credit for being selected. | 605 // Prevent trivial suggestions from getting credit for being selected. |
603 if (!IsTrivialAutocompletion(*match)) | 606 if (!IsTrivialAutocompletion(*match)) |
604 selected_index = base::StringPrintf("%" PRIuS, index); | 607 selected_index = base::StringPrintf("%" PRIuS, index); |
605 match->search_terms_args->assisted_query_stats = | 608 match->search_terms_args->assisted_query_stats = |
606 base::StringPrintf("chrome.%s.%s", | 609 base::StringPrintf("chrome.%s.%s", |
607 selected_index.c_str(), | 610 selected_index.c_str(), |
608 autocompletions.c_str()); | 611 autocompletions.c_str()); |
609 match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( | 612 match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( |
610 *match->search_terms_args, UIThreadSearchTermsData(profile_))); | 613 *match->search_terms_args, template_url_service_->search_terms_data())); |
611 } | 614 } |
612 } | 615 } |
613 | 616 |
614 void AutocompleteController::NotifyChanged(bool notify_default_match) { | 617 void AutocompleteController::NotifyChanged(bool notify_default_match) { |
615 if (delegate_) | 618 if (delegate_) |
616 delegate_->OnResultChanged(notify_default_match); | 619 delegate_->OnResultChanged(notify_default_match); |
617 if (done_) { | 620 if (done_) { |
618 content::NotificationService::current()->Notify( | 621 content::NotificationService::current()->Notify( |
619 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, | 622 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, |
620 content::Source<AutocompleteController>(this), | 623 content::Source<AutocompleteController>(this), |
(...skipping 25 matching lines...) Expand all Loading... |
646 this, &AutocompleteController::ExpireCopiedEntries); | 649 this, &AutocompleteController::ExpireCopiedEntries); |
647 } | 650 } |
648 | 651 |
649 void AutocompleteController::StartStopTimer() { | 652 void AutocompleteController::StartStopTimer() { |
650 stop_timer_.Start(FROM_HERE, | 653 stop_timer_.Start(FROM_HERE, |
651 stop_timer_duration_, | 654 stop_timer_duration_, |
652 base::Bind(&AutocompleteController::Stop, | 655 base::Bind(&AutocompleteController::Stop, |
653 base::Unretained(this), | 656 base::Unretained(this), |
654 false)); | 657 false)); |
655 } | 658 } |
OLD | NEW |