Index: components/omnibox/browser/physical_web_provider.cc |
diff --git a/components/omnibox/browser/physical_web_provider.cc b/components/omnibox/browser/physical_web_provider.cc |
index fc65e2e4464f0b0669f89351ffc27dfa25b90593..10c5dd2d9168859298127c834780b21dbcf2651a 100644 |
--- a/components/omnibox/browser/physical_web_provider.cc |
+++ b/components/omnibox/browser/physical_web_provider.cc |
@@ -2,14 +2,22 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "components/omnibox/browser/physical_web_provider.h" |
+ |
#include "base/memory/ptr_util.h" |
#include "base/metrics/histogram_macros.h" |
+#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/values.h" |
+#include "components/bookmarks/browser/titled_url_index.h" |
+#include "components/bookmarks/browser/titled_url_node_sorter.h" |
#include "components/omnibox/browser/autocomplete_provider_client.h" |
#include "components/omnibox/browser/autocomplete_provider_listener.h" |
+#include "components/omnibox/browser/autocomplete_provider_utils.h" |
#include "components/omnibox/browser/history_url_provider.h" |
-#include "components/omnibox/browser/physical_web_provider.h" |
+#include "components/omnibox/browser/omnibox_field_trial.h" |
+#include "components/omnibox/browser/physical_web_node.h" |
+#include "components/omnibox/browser/url_prefix.h" |
#include "components/omnibox/browser/verbatim_match.h" |
#include "components/physical_web/data_source/physical_web_data_source.h" |
#include "components/url_formatter/url_formatter.h" |
@@ -31,6 +39,10 @@ static const int kPhysicalWebUrlBaseRelevance = 700; |
// Physical Web match item (non-overflow item) we allow the omnibox display to |
// truncate the title instead. |
static const size_t kMaxTitleLengthInOverflow = 15; |
+ |
+// The maximum number of Physical Web URLs to retrieve from the index. |
+static const size_t kPhysicalWebIndexMaxMatches = 50; |
+ |
} |
// static |
@@ -52,12 +64,6 @@ void PhysicalWebProvider::Start(const AutocompleteInput& input, |
done_ = false; |
matches_.clear(); |
- // Stop providing suggestions when the user enters text into the omnibox. |
- if (!input.from_omnibox_focus()) { |
- done_ = true; |
- return; |
- } |
- |
// Don't provide suggestions in incognito mode. |
if (client_->IsOffTheRecord()) { |
done_ = true; |
@@ -73,16 +79,21 @@ void PhysicalWebProvider::Start(const AutocompleteInput& input, |
return; |
} |
- ConstructMatches(data_source->GetMetadata().get()); |
- |
- // Physical Web matches should never be default. If the omnibox input is |
- // non-empty and we have at least one Physical Web match, add the current URL |
- // as the default so that hitting enter after focusing the omnibox causes the |
- // current page to reload. If the input field is empty, no default match is |
- // required. |
- if (!matches_.empty() && !input.text().empty()) { |
- matches_.push_back(VerbatimMatchForURL(client_, input, input.current_url(), |
- history_url_provider_, -1)); |
+ if (zero_suggest_enabled_ && input.from_omnibox_focus()) { |
+ ConstructZeroSuggestMatches(data_source->GetMetadata()); |
+ |
+ // In zero-suggest, Physical Web matches should never be default. If the |
+ // omnibox input is non-empty and we have at least one Physical Web match, |
+ // add the current URL as the default so that hitting enter after focusing |
+ // the omnibox causes the current page to reload. If the input field is |
+ // empty, no default match is required. |
+ if (!matches_.empty() && !input.text().empty()) { |
+ matches_.push_back( |
+ VerbatimMatchForURL(client_, input, input.current_url(), |
+ history_url_provider_, -1)); |
+ } |
+ } else if (after_typing_enabled_) { |
+ ConstructQuerySuggestMatches(data_source->GetMetadata(), input); |
} |
done_ = true; |
@@ -111,12 +122,26 @@ PhysicalWebProvider::PhysicalWebProvider( |
HistoryURLProvider* history_url_provider) |
: AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB), |
client_(client), |
- history_url_provider_(history_url_provider) {} |
+ history_url_provider_(history_url_provider), |
+ zero_suggest_base_relevance_(kPhysicalWebUrlBaseRelevance), |
+ after_typing_base_relevance_(kPhysicalWebUrlBaseRelevance) { |
+ zero_suggest_enabled_ = |
+ OmniboxFieldTrial::InPhysicalWebZeroSuggestFieldTrial(); |
+ after_typing_enabled_ = |
+ OmniboxFieldTrial::InPhysicalWebAfterTypingFieldTrial(); |
+ PhysicalWebScoringParams scoring_params; |
+ OmniboxFieldTrial::GetExperimentalPhysicalWebScoringParams(&scoring_params); |
+ if (scoring_params.experimental_scoring_enabled) { |
+ zero_suggest_base_relevance_ = scoring_params.zero_suggest_base_relevance; |
+ after_typing_base_relevance_ = scoring_params.after_typing_base_relevance; |
+ } |
+} |
PhysicalWebProvider::~PhysicalWebProvider() { |
} |
-void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) { |
+void PhysicalWebProvider::ConstructZeroSuggestMatches( |
+ std::unique_ptr<base::ListValue> metadata_list) { |
nearby_url_count_ = metadata_list->GetSize(); |
size_t used_slots = 0; |
@@ -137,7 +162,7 @@ void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) { |
// Add match items with decreasing relevance to preserve the ordering in |
// the metadata list. |
- int relevance = kPhysicalWebUrlBaseRelevance - used_slots; |
+ int relevance = zero_suggest_base_relevance_ - used_slots; |
// Append an overflow item if creating a match for each metadata item would |
// exceed the match limit. |
@@ -178,6 +203,42 @@ void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) { |
"Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches); |
} |
+void PhysicalWebProvider::ConstructQuerySuggestMatches( |
+ std::unique_ptr<base::ListValue> metadata_list, |
+ const AutocompleteInput& input) { |
+ // Passing nullptr for the TitledUrlNodeSorter will cause the returned match |
+ // list to be unsorted. |
+ bookmarks::TitledUrlIndex index(nullptr); |
+ std::vector<std::unique_ptr<PhysicalWebNode> > nodes; |
+ const size_t metadata_count = metadata_list->GetSize(); |
+ for (size_t i = 0; i < metadata_count; ++i) { |
+ base::DictionaryValue* metadata_item = NULL; |
+ if (metadata_list->GetDictionary(i, &metadata_item)) { |
+ nodes.push_back(base::MakeUnique<PhysicalWebNode>(*metadata_item)); |
+ index.Add(nodes.back().get()); |
+ } |
+ } |
+ |
+ std::vector<bookmarks::TitledUrlMatch> titled_url_matches; |
+ index.GetResultsMatching(input.text(), kPhysicalWebIndexMaxMatches, |
+ query_parser::MatchingAlgorithm::DEFAULT, |
+ &titled_url_matches); |
+ |
+ size_t used_slots = 0; |
+ const base::string16 fixed_up_input(FixupUserInput(input).second); |
+ for (auto titled_url_match : titled_url_matches) { |
+ const int relevance = after_typing_base_relevance_ - used_slots; |
+ matches_.push_back( |
+ TitledUrlMatchToAutocompleteMatch( |
+ this, client_->GetSchemeClassifier(), input, fixed_up_input, |
+ titled_url_match, AutocompleteMatchType::PHYSICAL_WEB, relevance)); |
+ ++used_slots; |
+ if (matches_.size() >= kPhysicalWebMaxMatches) { |
+ break; |
+ } |
+ } |
+} |
+ |
void PhysicalWebProvider::AppendOverflowItem(int additional_url_count, |
int relevance, |
const base::string16& title) { |