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