Chromium Code Reviews| 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 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 // url_db can be NULL if it hasn't finished initializing (or failed to | 561 // url_db can be NULL if it hasn't finished initializing (or failed to |
| 562 // initialize). In this case all we can do is fall back on the second | 562 // initialize). In this case all we can do is fall back on the second |
| 563 // pass. | 563 // pass. |
| 564 // | 564 // |
| 565 // TODO(pkasting): We should just block here until this loads. Any time | 565 // TODO(pkasting): We should just block here until this loads. Any time |
| 566 // someone unloads the history backend, we'll get inconsistent inline | 566 // someone unloads the history backend, we'll get inconsistent inline |
| 567 // autocomplete behavior here. | 567 // autocomplete behavior here. |
| 568 if (url_db) { | 568 if (url_db) { |
| 569 DoAutocomplete(NULL, url_db, params.get()); | 569 DoAutocomplete(NULL, url_db, params.get()); |
| 570 matches_.clear(); | 570 matches_.clear(); |
| 571 PromoteMatchIfNecessary(*params); | 571 PromoteMatchesIfNecessary(*params); |
| 572 // NOTE: We don't reset |params| here since at least the |promote_type| | 572 // NOTE: We don't reset |params| here since at least the |promote_type| |
| 573 // field on it will be read by the second pass -- see comments in | 573 // field on it will be read by the second pass -- see comments in |
| 574 // DoAutocomplete(). | 574 // DoAutocomplete(). |
| 575 } | 575 } |
| 576 | 576 |
| 577 // Pass 2: Ask the history service to call us back on the history thread, | 577 // Pass 2: Ask the history service to call us back on the history thread, |
| 578 // where we can read the full on-disk DB. | 578 // where we can read the full on-disk DB. |
| 579 if (input.want_asynchronous_matches()) { | 579 if (input.want_asynchronous_matches()) { |
| 580 done_ = false; | 580 done_ = false; |
| 581 params_ = params.release(); // This object will be destroyed in | 581 params_ = params.release(); // This object will be destroyed in |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 SortAndDedupMatches(¶ms->matches); | 759 SortAndDedupMatches(¶ms->matches); |
| 760 | 760 |
| 761 // Try to create a shorter suggestion from the best match. | 761 // Try to create a shorter suggestion from the best match. |
| 762 // We consider the what you typed match eligible for display when it's | 762 // We consider the what you typed match eligible for display when it's |
| 763 // navigable and there's a reasonable chance the user intended to do | 763 // navigable and there's a reasonable chance the user intended to do |
| 764 // something other than search. We use a variety of heuristics to determine | 764 // something other than search. We use a variety of heuristics to determine |
| 765 // this, e.g. whether the user explicitly typed a scheme, or if omnibox | 765 // this, e.g. whether the user explicitly typed a scheme, or if omnibox |
| 766 // searching has been disabled by policy. In the cases where we've parsed as | 766 // searching has been disabled by policy. In the cases where we've parsed as |
| 767 // UNKNOWN, we'll still show an accidental search infobar if need be. | 767 // UNKNOWN, we'll still show an accidental search infobar if need be. |
| 768 VisitClassifier classifier(this, params->input, db); | 768 VisitClassifier classifier(this, params->input, db); |
| 769 bool have_what_you_typed_match = | 769 params->have_what_you_typed_match = |
| 770 (params->input.type() != metrics::OmniboxInputType::QUERY) && | 770 (params->input.type() != metrics::OmniboxInputType::QUERY) && |
| 771 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || | 771 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || |
| 772 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || | 772 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || |
| 773 !params->trim_http || | 773 !params->trim_http || |
| 774 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0) || | 774 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0) || |
| 775 !params->default_search_provider); | 775 !params->default_search_provider); |
| 776 const bool have_shorter_suggestion_suitable_for_inline_autocomplete = | 776 const bool have_shorter_suggestion_suitable_for_inline_autocomplete = |
| 777 PromoteOrCreateShorterSuggestion(db, have_what_you_typed_match, params); | 777 PromoteOrCreateShorterSuggestion( |
| 778 db, params->have_what_you_typed_match, params); | |
|
Peter Kasting
2015/03/20 23:30:19
Just have this function read |have_what_you_typed_
Mark P
2015/03/24 18:23:26
Silly me for overlooking this. Done.
| |
| 778 | 779 |
| 779 // Check whether what the user typed appears in history. | 780 // Check whether what the user typed appears in history. |
| 780 const bool can_check_history_for_exact_match = | 781 const bool can_check_history_for_exact_match = |
| 781 // Checking what_you_typed_match.is_history_what_you_typed_match tells us | 782 // Checking what_you_typed_match.is_history_what_you_typed_match tells us |
| 782 // whether SuggestExactInput() succeeded in constructing a valid match. | 783 // whether SuggestExactInput() succeeded in constructing a valid match. |
| 783 params->what_you_typed_match.is_history_what_you_typed_match && | 784 params->what_you_typed_match.is_history_what_you_typed_match && |
| 784 // Additionally, in the case where the user has typed "foo.com" and | 785 // 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 | 786 // 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 | 787 // 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 | 788 // second pass can suggest the exact input as a better URL. Since we need |
| 788 // both passes to agree, and since during the first pass there's no way to | 789 // both passes to agree, and since during the first pass there's no way to |
| 789 // know about "foo/", ensure that if the promote type was set to | 790 // know about "foo/", ensure that if the promote type was set to |
| 790 // FRONT_HISTORY_MATCH during the first pass, the second pass will not | 791 // FRONT_HISTORY_MATCH during the first pass, the second pass will not |
| 791 // consider the exact suggestion to be in history and therefore will not | 792 // consider the exact suggestion to be in history and therefore will not |
| 792 // suggest the exact input as a better match. (Note that during the first | 793 // suggest the exact input as a better match. (Note that during the first |
| 793 // pass, this conditional will always succeed since |promote_type| is | 794 // pass, this conditional will always succeed since |promote_type| is |
| 794 // initialized to NEITHER.) | 795 // initialized to NEITHER.) |
| 795 (params->promote_type != HistoryURLProviderParams::FRONT_HISTORY_MATCH); | 796 (params->promote_type != HistoryURLProviderParams::FRONT_HISTORY_MATCH); |
| 796 params->exact_suggestion_is_in_history = can_check_history_for_exact_match && | 797 params->exact_suggestion_is_in_history = can_check_history_for_exact_match && |
| 797 FixupExactSuggestion(db, classifier, params); | 798 FixupExactSuggestion(db, classifier, params); |
| 798 | 799 |
| 799 // If we succeeded in fixing up the exact match based on the user's history, | 800 // If we succeeded in fixing up the exact match based on the user's history, |
| 800 // we should treat it as the best match regardless of input type. If not, | 801 // we should treat it as the best match regardless of input type. If not, |
| 801 // then we check whether there's an inline autocompletion we can create from | 802 // 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. | 803 // this input, so we can promote that as the best match. |
| 803 if (params->exact_suggestion_is_in_history) { | 804 if (params->exact_suggestion_is_in_history) { |
| 804 params->promote_type = HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH; | 805 params->promote_type = HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH; |
| 805 } else if (!params->prevent_inline_autocomplete && !params->matches.empty() && | 806 } else if (!params->matches.empty() && |
| 806 (have_shorter_suggestion_suitable_for_inline_autocomplete || | 807 (have_shorter_suggestion_suitable_for_inline_autocomplete || |
| 807 CanPromoteMatchForInlineAutocomplete(params->matches[0]))) { | 808 CanPromoteMatchForInlineAutocomplete(params->matches[0]))) { |
| 808 params->promote_type = HistoryURLProviderParams::FRONT_HISTORY_MATCH; | 809 params->promote_type = HistoryURLProviderParams::FRONT_HISTORY_MATCH; |
| 809 } else { | 810 } else { |
| 810 // Failed to promote any URLs. Use the What You Typed match, if we have it. | 811 // Failed to promote any URLs. Use the What You Typed match, if we have it. |
| 811 params->promote_type = have_what_you_typed_match ? | 812 params->promote_type = params->have_what_you_typed_match ? |
| 812 HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH : | 813 HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH : |
| 813 HistoryURLProviderParams::NEITHER; | 814 HistoryURLProviderParams::NEITHER; |
| 814 } | 815 } |
| 815 | 816 |
| 816 const size_t max_results = | 817 const size_t max_results = |
| 817 kMaxMatches + (params->exact_suggestion_is_in_history ? 1 : 0); | 818 kMaxMatches + (params->exact_suggestion_is_in_history ? 1 : 0); |
| 818 if (backend) { | 819 if (backend) { |
| 819 // Remove redirects and trim list to size. We want to provide up to | 820 // 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 | 821 // kMaxMatches results plus the What You Typed result, if it was added to |
| 821 // params->matches above. | 822 // params->matches above. |
| 822 CullRedirects(backend, ¶ms->matches, max_results); | 823 CullRedirects(backend, ¶ms->matches, max_results); |
| 823 } else if (params->matches.size() > max_results) { | 824 } else if (params->matches.size() > max_results) { |
| 824 // Simply trim the list to size. | 825 // Simply trim the list to size. |
| 825 params->matches.resize(max_results); | 826 params->matches.resize(max_results); |
| 826 } | 827 } |
| 827 } | 828 } |
| 828 | 829 |
| 829 void HistoryURLProvider::PromoteMatchIfNecessary( | 830 void HistoryURLProvider::PromoteMatchesIfNecessary( |
| 830 const HistoryURLProviderParams& params) { | 831 const HistoryURLProviderParams& params) { |
| 831 if (params.promote_type == HistoryURLProviderParams::NEITHER) | 832 if (params.promote_type == HistoryURLProviderParams::NEITHER) |
| 832 return; | 833 return; |
| 833 matches_.push_back( | 834 if (params.promote_type == HistoryURLProviderParams::FRONT_HISTORY_MATCH) { |
| 834 (params.promote_type == HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH) ? | 835 matches_.push_back( |
| 835 params.what_you_typed_match : | 836 HistoryMatchToACMatch(params, 0, INLINE_AUTOCOMPLETE, |
| 836 HistoryMatchToACMatch(params, 0, INLINE_AUTOCOMPLETE, | 837 CalculateRelevance(INLINE_AUTOCOMPLETE, 0))); |
| 837 CalculateRelevance(INLINE_AUTOCOMPLETE, 0))); | 838 } |
| 839 // Add the what-you-typed match if you we're explicitly told to or if we need | |
|
Peter Kasting
2015/03/20 23:30:19
Nit: "you"?
Mark P
2015/03/24 18:23:26
Fixed.
| |
| 840 // it because we added an inline-autocomplete match yet inline autocompletion | |
| 841 // is disabled (so it will not be allowed to be the default match). Hence, | |
| 842 // we need to add the what-you-typed match as a legal default match. | |
| 843 if ((params.promote_type == HistoryURLProviderParams::WHAT_YOU_TYPED_MATCH) || | |
| 844 (params.prevent_inline_autocomplete && | |
| 845 params.have_what_you_typed_match)) { | |
|
Peter Kasting
2015/03/20 23:30:19
Won't this always add the WYT match for |prevent_i
Mark P
2015/03/24 18:23:26
Yes, it'll always add a WYT match for |prevent_inl
Peter Kasting
2015/03/24 21:05:39
Huh. I'm wondering if that's a potential quality
Mark P
2015/03/24 21:40:50
Are you suggesting adding an && !matches.empty() t
| |
| 846 matches_.push_back(params.what_you_typed_match); | |
| 847 } | |
| 838 } | 848 } |
| 839 | 849 |
| 840 void HistoryURLProvider::QueryComplete( | 850 void HistoryURLProvider::QueryComplete( |
| 841 HistoryURLProviderParams* params_gets_deleted) { | 851 HistoryURLProviderParams* params_gets_deleted) { |
| 842 // Ensure |params_gets_deleted| gets deleted on exit. | 852 // Ensure |params_gets_deleted| gets deleted on exit. |
| 843 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); | 853 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); |
| 844 | 854 |
| 845 // If the user hasn't already started another query, clear our member pointer | 855 // If the user hasn't already started another query, clear our member pointer |
| 846 // so we can't write into deleted memory. | 856 // so we can't write into deleted memory. |
| 847 if (params_ == params_gets_deleted) | 857 if (params_ == params_gets_deleted) |
| 848 params_ = NULL; | 858 params_ = NULL; |
| 849 | 859 |
| 850 // Don't send responses for queries that have been canceled. | 860 // Don't send responses for queries that have been canceled. |
| 851 if (params->cancel_flag.IsSet()) | 861 if (params->cancel_flag.IsSet()) |
| 852 return; // Already set done_ when we canceled, no need to set it again. | 862 return; // Already set done_ when we canceled, no need to set it again. |
| 853 | 863 |
| 854 // Don't modify |matches_| if the query failed, since it might have a default | 864 // Don't modify |matches_| if the query failed, since it might have a default |
| 855 // match in it, whereas |params->matches| will be empty. | 865 // match in it, whereas |params->matches| will be empty. |
| 856 if (!params->failed) { | 866 if (!params->failed) { |
| 857 matches_.clear(); | 867 matches_.clear(); |
| 858 PromoteMatchIfNecessary(*params); | 868 PromoteMatchesIfNecessary(*params); |
| 859 | 869 |
| 860 // Determine relevance of highest scoring match, if any. | 870 // Determine relevance of highest scoring match, if any. |
| 861 int relevance = matches_.empty() ? | 871 int relevance = matches_.empty() ? |
| 862 CalculateRelevance(NORMAL, | 872 CalculateRelevance(NORMAL, |
| 863 static_cast<int>(params->matches.size() - 1)) : | 873 static_cast<int>(params->matches.size() - 1)) : |
| 864 matches_[0].relevance; | 874 matches_[0].relevance; |
| 865 | 875 |
| 866 // Convert the history matches to autocomplete matches. If we promoted the | 876 // Convert the history matches to autocomplete matches. If we promoted the |
| 867 // first match, skip over it. | 877 // first match, skip over it. |
| 868 const size_t first_match = | 878 const size_t first_match = |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1153 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, | 1163 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, |
| 1154 match.contents.length(), ACMatchClassification::URL, | 1164 match.contents.length(), ACMatchClassification::URL, |
| 1155 &match.contents_class); | 1165 &match.contents_class); |
| 1156 } | 1166 } |
| 1157 match.description = info.title(); | 1167 match.description = info.title(); |
| 1158 match.description_class = | 1168 match.description_class = |
| 1159 ClassifyDescription(params.input.text(), match.description); | 1169 ClassifyDescription(params.input.text(), match.description); |
| 1160 RecordAdditionalInfoFromUrlRow(info, &match); | 1170 RecordAdditionalInfoFromUrlRow(info, &match); |
| 1161 return match; | 1171 return match; |
| 1162 } | 1172 } |
| OLD | NEW |