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/history_url_provider.h" | 5 #include "chrome/browser/autocomplete/history_url_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 // url_db can be NULL if it hasn't finished initializing (or failed to | 560 // url_db can be NULL if it hasn't finished initializing (or failed to |
561 // initialize). In this case all we can do is fall back on the second | 561 // initialize). In this case all we can do is fall back on the second |
562 // pass. | 562 // pass. |
563 // | 563 // |
564 // TODO(pkasting): We should just block here until this loads. Any time | 564 // TODO(pkasting): We should just block here until this loads. Any time |
565 // someone unloads the history backend, we'll get inconsistent inline | 565 // someone unloads the history backend, we'll get inconsistent inline |
566 // autocomplete behavior here. | 566 // autocomplete behavior here. |
567 if (url_db) { | 567 if (url_db) { |
568 DoAutocomplete(NULL, url_db, params.get()); | 568 DoAutocomplete(NULL, url_db, params.get()); |
569 matches_.clear(); | 569 matches_.clear(); |
570 PromoteMatchesIfNecessary(*params); | 570 PromoteMatchIfNecessary(*params); |
571 // NOTE: We don't reset |params| here since at least the |promote_type| | 571 // NOTE: We don't reset |params| here since at least the |promote_type| |
572 // field on it will be read by the second pass -- see comments in | 572 // field on it will be read by the second pass -- see comments in |
573 // DoAutocomplete(). | 573 // DoAutocomplete(). |
574 } | 574 } |
575 | 575 |
576 // Pass 2: Ask the history service to call us back on the history thread, | 576 // Pass 2: Ask the history service to call us back on the history thread, |
577 // where we can read the full on-disk DB. | 577 // where we can read the full on-disk DB. |
578 if (input.want_asynchronous_matches()) { | 578 if (input.want_asynchronous_matches()) { |
579 done_ = false; | 579 done_ = false; |
580 params_ = params.release(); // This object will be destroyed in | 580 params_ = params.release(); // This object will be destroyed in |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 SortAndDedupMatches(¶ms->matches); | 758 SortAndDedupMatches(¶ms->matches); |
759 | 759 |
760 // Try to create a shorter suggestion from the best match. | 760 // Try to create a shorter suggestion from the best match. |
761 // We consider the what you typed match eligible for display when it's | 761 // We consider the what you typed match eligible for display when it's |
762 // navigable and there's a reasonable chance the user intended to do | 762 // navigable and there's a reasonable chance the user intended to do |
763 // something other than search. We use a variety of heuristics to determine | 763 // something other than search. We use a variety of heuristics to determine |
764 // this, e.g. whether the user explicitly typed a scheme, or if omnibox | 764 // this, e.g. whether the user explicitly typed a scheme, or if omnibox |
765 // searching has been disabled by policy. In the cases where we've parsed as | 765 // searching has been disabled by policy. In the cases where we've parsed as |
766 // UNKNOWN, we'll still show an accidental search infobar if need be. | 766 // UNKNOWN, we'll still show an accidental search infobar if need be. |
767 VisitClassifier classifier(this, params->input, db); | 767 VisitClassifier classifier(this, params->input, db); |
768 params->have_what_you_typed_match = | 768 bool have_what_you_typed_match = |
769 (params->input.type() != metrics::OmniboxInputType::QUERY) && | 769 (params->input.type() != metrics::OmniboxInputType::QUERY) && |
770 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || | 770 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || |
771 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || | 771 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || |
772 !params->trim_http || | 772 !params->trim_http || |
773 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0) || | 773 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0) || |
774 !params->default_search_provider); | 774 !params->default_search_provider); |
775 const bool have_shorter_suggestion_suitable_for_inline_autocomplete = | 775 const bool have_shorter_suggestion_suitable_for_inline_autocomplete = |
776 PromoteOrCreateShorterSuggestion( | 776 PromoteOrCreateShorterSuggestion(db, have_what_you_typed_match, params); |
777 db, params->have_what_you_typed_match, params); | |
778 | 777 |
779 // Check whether what the user typed appears in history. | 778 // Check whether what the user typed appears in history. |
780 const bool can_check_history_for_exact_match = | 779 const bool can_check_history_for_exact_match = |
781 // Checking what_you_typed_match.is_history_what_you_typed_match tells us | 780 // Checking what_you_typed_match.is_history_what_you_typed_match tells us |
782 // whether SuggestExactInput() succeeded in constructing a valid match. | 781 // whether SuggestExactInput() succeeded in constructing a valid match. |
783 params->what_you_typed_match.is_history_what_you_typed_match && | 782 params->what_you_typed_match.is_history_what_you_typed_match && |
784 // Additionally, in the case where the user has typed "foo.com" and | 783 // Additionally, in the case where the user has typed "foo.com" and |
785 // visited (but not typed) "foo/", and the input is "foo", the first pass | 784 // visited (but not typed) "foo/", and the input is "foo", the first pass |
786 // will fall into the FRONT_HISTORY_MATCH case for "foo.com" but the | 785 // will fall into the FRONT_HISTORY_MATCH case for "foo.com" but the |
787 // second pass can suggest the exact input as a better URL. Since we need | 786 // second pass can suggest the exact input as a better URL. Since we need |
(...skipping 13 matching lines...) Expand all Loading... |
801 // then we check whether there's an inline autocompletion we can create from | 800 // then we check whether there's an inline autocompletion we can create from |
802 // this input, so we can promote that as the best match. | 801 // this input, so we can promote that as the best match. |
803 if (params->exact_suggestion_is_in_history) { | 802 if (params->exact_suggestion_is_in_history) { |
804 params->promote_type = HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH; | 803 params->promote_type = HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH; |
805 } else if (!params->prevent_inline_autocomplete && !params->matches.empty() && | 804 } else if (!params->prevent_inline_autocomplete && !params->matches.empty() && |
806 (have_shorter_suggestion_suitable_for_inline_autocomplete || | 805 (have_shorter_suggestion_suitable_for_inline_autocomplete || |
807 CanPromoteMatchForInlineAutocomplete(params->matches[0]))) { | 806 CanPromoteMatchForInlineAutocomplete(params->matches[0]))) { |
808 params->promote_type = HistoryURLProviderParams::FRONT_HISTORY_MATCH; | 807 params->promote_type = HistoryURLProviderParams::FRONT_HISTORY_MATCH; |
809 } else { | 808 } else { |
810 // Failed to promote any URLs. Use the What You Typed match, if we have it. | 809 // Failed to promote any URLs. Use the What You Typed match, if we have it. |
811 params->promote_type = params->have_what_you_typed_match ? | 810 params->promote_type = have_what_you_typed_match ? |
812 HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH : | 811 HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH : |
813 HistoryURLProviderParams::NEITHER; | 812 HistoryURLProviderParams::NEITHER; |
814 } | 813 } |
815 | 814 |
816 const size_t max_results = | 815 const size_t max_results = |
817 kMaxMatches + (params->exact_suggestion_is_in_history ? 1 : 0); | 816 kMaxMatches + (params->exact_suggestion_is_in_history ? 1 : 0); |
818 if (backend) { | 817 if (backend) { |
819 // Remove redirects and trim list to size. We want to provide up to | 818 // Remove redirects and trim list to size. We want to provide up to |
820 // kMaxMatches results plus the What You Typed result, if it was added to | 819 // kMaxMatches results plus the What You Typed result, if it was added to |
821 // params->matches above. | 820 // params->matches above. |
822 CullRedirects(backend, ¶ms->matches, max_results); | 821 CullRedirects(backend, ¶ms->matches, max_results); |
823 } else if (params->matches.size() > max_results) { | 822 } else if (params->matches.size() > max_results) { |
824 // Simply trim the list to size. | 823 // Simply trim the list to size. |
825 params->matches.resize(max_results); | 824 params->matches.resize(max_results); |
826 } | 825 } |
827 } | 826 } |
828 | 827 |
829 void HistoryURLProvider::PromoteMatchesIfNecessary( | 828 void HistoryURLProvider::PromoteMatchIfNecessary( |
830 const HistoryURLProviderParams& params) { | 829 const HistoryURLProviderParams& params) { |
831 if (params.promote_type == HistoryURLProviderParams::FRONT_HISTORY_MATCH) { | 830 if (params.promote_type == HistoryURLProviderParams::NEITHER) |
832 matches_.push_back(HistoryMatchToACMatch(params, 0, INLINE_AUTOCOMPLETE, | 831 return; |
833 CalculateRelevance(INLINE_AUTOCOMPLETE, 0))); | 832 matches_.push_back( |
834 if (OmniboxFieldTrial::AddUWYTMatchEvenIfPromotedURLs() && | 833 (params.promote_type == HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH) ? |
835 params.have_what_you_typed_match) { | 834 params.what_you_typed_match : |
836 matches_.push_back(params.what_you_typed_match); | 835 HistoryMatchToACMatch(params, 0, INLINE_AUTOCOMPLETE, |
837 } | 836 CalculateRelevance(INLINE_AUTOCOMPLETE, 0))); |
838 } else if (params.promote_type == | |
839 HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH) { | |
840 matches_.push_back(params.what_you_typed_match); | |
841 } | |
842 } | 837 } |
843 | 838 |
844 void HistoryURLProvider::QueryComplete( | 839 void HistoryURLProvider::QueryComplete( |
845 HistoryURLProviderParams* params_gets_deleted) { | 840 HistoryURLProviderParams* params_gets_deleted) { |
846 // Ensure |params_gets_deleted| gets deleted on exit. | 841 // Ensure |params_gets_deleted| gets deleted on exit. |
847 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); | 842 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); |
848 | 843 |
849 // If the user hasn't already started another query, clear our member pointer | 844 // If the user hasn't already started another query, clear our member pointer |
850 // so we can't write into deleted memory. | 845 // so we can't write into deleted memory. |
851 if (params_ == params_gets_deleted) | 846 if (params_ == params_gets_deleted) |
852 params_ = NULL; | 847 params_ = NULL; |
853 | 848 |
854 // Don't send responses for queries that have been canceled. | 849 // Don't send responses for queries that have been canceled. |
855 if (params->cancel_flag.IsSet()) | 850 if (params->cancel_flag.IsSet()) |
856 return; // Already set done_ when we canceled, no need to set it again. | 851 return; // Already set done_ when we canceled, no need to set it again. |
857 | 852 |
858 // Don't modify |matches_| if the query failed, since it might have a default | 853 // Don't modify |matches_| if the query failed, since it might have a default |
859 // match in it, whereas |params->matches| will be empty. | 854 // match in it, whereas |params->matches| will be empty. |
860 if (!params->failed) { | 855 if (!params->failed) { |
861 matches_.clear(); | 856 matches_.clear(); |
862 PromoteMatchesIfNecessary(*params); | 857 PromoteMatchIfNecessary(*params); |
863 | 858 |
864 // Determine relevance of highest scoring match, if any. | 859 // Determine relevance of highest scoring match, if any. |
865 int relevance = matches_.empty() ? | 860 int relevance = matches_.empty() ? |
866 CalculateRelevance(NORMAL, | 861 CalculateRelevance(NORMAL, |
867 static_cast<int>(params->matches.size() - 1)) : | 862 static_cast<int>(params->matches.size() - 1)) : |
868 matches_[0].relevance; | 863 matches_[0].relevance; |
869 | 864 |
870 // Convert the history matches to autocomplete matches. If we promoted the | 865 // Convert the history matches to autocomplete matches. If we promoted the |
871 // first match, skip over it. | 866 // first match, skip over it. |
872 const size_t first_match = | 867 const size_t first_match = |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, | 1152 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, |
1158 match.contents.length(), ACMatchClassification::URL, | 1153 match.contents.length(), ACMatchClassification::URL, |
1159 &match.contents_class); | 1154 &match.contents_class); |
1160 } | 1155 } |
1161 match.description = info.title(); | 1156 match.description = info.title(); |
1162 match.description_class = | 1157 match.description_class = |
1163 ClassifyDescription(params.input.text(), match.description); | 1158 ClassifyDescription(params.input.text(), match.description); |
1164 RecordAdditionalInfoFromUrlRow(info, &match); | 1159 RecordAdditionalInfoFromUrlRow(info, &match); |
1165 return match; | 1160 return match; |
1166 } | 1161 } |
OLD | NEW |