Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: components/omnibox/browser/physical_web_provider.cc

Issue 2591053002: Show PhysicalWebProvider suggestions with omnibox input (Closed)
Patch Set: add field trials Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 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 "components/omnibox/browser/physical_web_provider.h"
6
5 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
6 #include "base/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/strings/string_util.h"
7 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
8 #include "base/values.h" 11 #include "base/values.h"
12 #include "components/bookmarks/browser/titled_url_index.h"
13 #include "components/bookmarks/browser/titled_url_node_sorter.h"
9 #include "components/omnibox/browser/autocomplete_provider_client.h" 14 #include "components/omnibox/browser/autocomplete_provider_client.h"
10 #include "components/omnibox/browser/autocomplete_provider_listener.h" 15 #include "components/omnibox/browser/autocomplete_provider_listener.h"
16 #include "components/omnibox/browser/autocomplete_provider_utils.h"
11 #include "components/omnibox/browser/history_url_provider.h" 17 #include "components/omnibox/browser/history_url_provider.h"
12 #include "components/omnibox/browser/physical_web_provider.h" 18 #include "components/omnibox/browser/omnibox_field_trial.h"
19 #include "components/omnibox/browser/physical_web_node.h"
20 #include "components/omnibox/browser/url_prefix.h"
13 #include "components/omnibox/browser/verbatim_match.h" 21 #include "components/omnibox/browser/verbatim_match.h"
14 #include "components/physical_web/data_source/physical_web_data_source.h" 22 #include "components/physical_web/data_source/physical_web_data_source.h"
15 #include "components/url_formatter/url_formatter.h" 23 #include "components/url_formatter/url_formatter.h"
16 #include "grit/components_strings.h" 24 #include "grit/components_strings.h"
17 #include "ui/base/l10n/l10n_util.h" 25 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/gfx/text_elider.h" 26 #include "ui/gfx/text_elider.h"
19 #include "url/gurl.h" 27 #include "url/gurl.h"
20 28
21 namespace { 29 namespace {
22 30
23 // Relevance score of the first Physical Web URL autocomplete match. This score 31 // Relevance score of the first Physical Web URL autocomplete match. This score
24 // is intended to be between ClipboardURLProvider and ZeroSuggestProvider. 32 // is intended to be between ClipboardURLProvider and ZeroSuggestProvider.
25 // Subsequent matches should decrease in relevance to preserve the ordering 33 // Subsequent matches should decrease in relevance to preserve the ordering
26 // in the metadata list. 34 // in the metadata list.
27 static const int kPhysicalWebUrlBaseRelevance = 700; 35 static const int kPhysicalWebUrlBaseRelevance = 700;
28 36
29 // The maximum length of the page title's part of the overflow item's 37 // The maximum length of the page title's part of the overflow item's
30 // description. Longer titles will be truncated to this length. In a normal 38 // description. Longer titles will be truncated to this length. In a normal
31 // Physical Web match item (non-overflow item) we allow the omnibox display to 39 // Physical Web match item (non-overflow item) we allow the omnibox display to
32 // truncate the title instead. 40 // truncate the title instead.
33 static const size_t kMaxTitleLengthInOverflow = 15; 41 static const size_t kMaxTitleLengthInOverflow = 15;
42
43 // The maximum number of Physical Web URLs to retrieve from the index.
44 static const size_t kPhysicalWebIndexMaxMatches = 50;
45
34 } 46 }
35 47
36 // static 48 // static
37 const size_t PhysicalWebProvider::kPhysicalWebMaxMatches = 1; 49 const size_t PhysicalWebProvider::kPhysicalWebMaxMatches = 1;
38 50
39 // static 51 // static
40 PhysicalWebProvider* PhysicalWebProvider::Create( 52 PhysicalWebProvider* PhysicalWebProvider::Create(
41 AutocompleteProviderClient* client, 53 AutocompleteProviderClient* client,
42 HistoryURLProvider* history_url_provider) { 54 HistoryURLProvider* history_url_provider) {
43 return new PhysicalWebProvider(client, history_url_provider); 55 return new PhysicalWebProvider(client, history_url_provider);
44 } 56 }
45 57
46 void PhysicalWebProvider::Start(const AutocompleteInput& input, 58 void PhysicalWebProvider::Start(const AutocompleteInput& input,
47 bool minimal_changes) { 59 bool minimal_changes) {
48 DCHECK(kPhysicalWebMaxMatches < kMaxMatches); 60 DCHECK(kPhysicalWebMaxMatches < kMaxMatches);
49 61
50 Stop(false, false); 62 Stop(false, false);
51 63
52 done_ = false; 64 done_ = false;
53 matches_.clear(); 65 matches_.clear();
54 66
55 // Stop providing suggestions when the user enters text into the omnibox.
56 if (!input.from_omnibox_focus()) {
57 done_ = true;
58 return;
59 }
60
61 // Don't provide suggestions in incognito mode. 67 // Don't provide suggestions in incognito mode.
62 if (client_->IsOffTheRecord()) { 68 if (client_->IsOffTheRecord()) {
63 done_ = true; 69 done_ = true;
64 nearby_url_count_ = 0; 70 nearby_url_count_ = 0;
65 return; 71 return;
66 } 72 }
67 73
68 physical_web::PhysicalWebDataSource* data_source = 74 physical_web::PhysicalWebDataSource* data_source =
69 client_->GetPhysicalWebDataSource(); 75 client_->GetPhysicalWebDataSource();
70 if (!data_source) { 76 if (!data_source) {
71 done_ = true; 77 done_ = true;
72 nearby_url_count_ = 0; 78 nearby_url_count_ = 0;
73 return; 79 return;
74 } 80 }
75 81
76 ConstructMatches(data_source->GetMetadata().get()); 82 if (zero_suggest_enabled_ && input.from_omnibox_focus()) {
83 ConstructZeroSuggestMatches(data_source->GetMetadata());
77 84
78 // Physical Web matches should never be default. If the omnibox input is 85 // In zero-suggest, Physical Web matches should never be default. If the
79 // non-empty and we have at least one Physical Web match, add the current URL 86 // omnibox input is non-empty and we have at least one Physical Web match,
80 // as the default so that hitting enter after focusing the omnibox causes the 87 // add the current URL as the default so that hitting enter after focusing
81 // current page to reload. If the input field is empty, no default match is 88 // the omnibox causes the current page to reload. If the input field is
82 // required. 89 // empty, no default match is required.
83 if (!matches_.empty() && !input.text().empty()) { 90 if (!matches_.empty() && !input.text().empty()) {
84 matches_.push_back(VerbatimMatchForURL(client_, input, input.current_url(), 91 matches_.push_back(
85 history_url_provider_, -1)); 92 VerbatimMatchForURL(client_, input, input.current_url(),
93 history_url_provider_, -1));
94 }
95 } else if (after_typing_enabled_) {
96 ConstructQuerySuggestMatches(data_source->GetMetadata(), input);
86 } 97 }
87 98
88 done_ = true; 99 done_ = true;
89 } 100 }
90 101
91 void PhysicalWebProvider::Stop(bool clear_cached_results, 102 void PhysicalWebProvider::Stop(bool clear_cached_results,
92 bool due_to_user_inactivity) { 103 bool due_to_user_inactivity) {
93 done_ = true; 104 done_ = true;
94 } 105 }
95 106
96 void PhysicalWebProvider::AddProviderInfo(ProvidersInfo* provider_info) const { 107 void PhysicalWebProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
97 // AddProviderInfo is called for each autocomplete provider to allow 108 // AddProviderInfo is called for each autocomplete provider to allow
98 // provider-specific diagnostic info to be added to the omnibox log entry. 109 // provider-specific diagnostic info to be added to the omnibox log entry.
99 // In this case we do not append any diagnostic info and are taking advantage 110 // In this case we do not append any diagnostic info and are taking advantage
100 // of the fact that this method is only called when the user has accepted an 111 // of the fact that this method is only called when the user has accepted an
101 // autocomplete suggestion. 112 // autocomplete suggestion.
102 113
103 // When the user accepts an autocomplete suggestion, record the number of 114 // When the user accepts an autocomplete suggestion, record the number of
104 // nearby Physical Web URLs at the time the provider last constructed matches. 115 // nearby Physical Web URLs at the time the provider last constructed matches.
105 UMA_HISTOGRAM_EXACT_LINEAR("Omnibox.SuggestionUsed.NearbyURLCount", 116 UMA_HISTOGRAM_EXACT_LINEAR("Omnibox.SuggestionUsed.NearbyURLCount",
106 nearby_url_count_, 50); 117 nearby_url_count_, 50);
107 } 118 }
108 119
109 PhysicalWebProvider::PhysicalWebProvider( 120 PhysicalWebProvider::PhysicalWebProvider(
110 AutocompleteProviderClient* client, 121 AutocompleteProviderClient* client,
111 HistoryURLProvider* history_url_provider) 122 HistoryURLProvider* history_url_provider)
112 : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB), 123 : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB),
113 client_(client), 124 client_(client),
114 history_url_provider_(history_url_provider) {} 125 history_url_provider_(history_url_provider),
126 zero_suggest_base_relevance_(kPhysicalWebUrlBaseRelevance),
127 after_typing_base_relevance_(kPhysicalWebUrlBaseRelevance) {
128 zero_suggest_enabled_ =
129 OmniboxFieldTrial::InPhysicalWebZeroSuggestFieldTrial();
130 after_typing_enabled_ =
131 OmniboxFieldTrial::InPhysicalWebAfterTypingFieldTrial();
132 PhysicalWebScoringParams scoring_params;
133 OmniboxFieldTrial::GetExperimentalPhysicalWebScoringParams(&scoring_params);
134 if (scoring_params.experimental_scoring_enabled) {
135 zero_suggest_base_relevance_ = scoring_params.zero_suggest_base_relevance;
136 after_typing_base_relevance_ = scoring_params.after_typing_base_relevance;
137 }
138 }
115 139
116 PhysicalWebProvider::~PhysicalWebProvider() { 140 PhysicalWebProvider::~PhysicalWebProvider() {
117 } 141 }
118 142
119 void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) { 143 void PhysicalWebProvider::ConstructZeroSuggestMatches(
144 std::unique_ptr<base::ListValue> metadata_list) {
120 nearby_url_count_ = metadata_list->GetSize(); 145 nearby_url_count_ = metadata_list->GetSize();
121 size_t used_slots = 0; 146 size_t used_slots = 0;
122 147
123 for (size_t i = 0; i < nearby_url_count_; ++i) { 148 for (size_t i = 0; i < nearby_url_count_; ++i) {
124 base::DictionaryValue* metadata_item = NULL; 149 base::DictionaryValue* metadata_item = NULL;
125 if (!metadata_list->GetDictionary(i, &metadata_item)) { 150 if (!metadata_list->GetDictionary(i, &metadata_item)) {
126 continue; 151 continue;
127 } 152 }
128 153
129 std::string url_string; 154 std::string url_string;
130 std::string title_string; 155 std::string title_string;
131 if (!metadata_item->GetString(physical_web::kResolvedUrlKey, &url_string) || 156 if (!metadata_item->GetString(physical_web::kResolvedUrlKey, &url_string) ||
132 !metadata_item->GetString(physical_web::kTitleKey, &title_string)) { 157 !metadata_item->GetString(physical_web::kTitleKey, &title_string)) {
133 continue; 158 continue;
134 } 159 }
135 base::string16 title = 160 base::string16 title =
136 AutocompleteMatch::SanitizeString(base::UTF8ToUTF16(title_string)); 161 AutocompleteMatch::SanitizeString(base::UTF8ToUTF16(title_string));
137 162
138 // Add match items with decreasing relevance to preserve the ordering in 163 // Add match items with decreasing relevance to preserve the ordering in
139 // the metadata list. 164 // the metadata list.
140 int relevance = kPhysicalWebUrlBaseRelevance - used_slots; 165 int relevance = zero_suggest_base_relevance_ - used_slots;
141 166
142 // Append an overflow item if creating a match for each metadata item would 167 // Append an overflow item if creating a match for each metadata item would
143 // exceed the match limit. 168 // exceed the match limit.
144 const size_t remaining_slots = kPhysicalWebMaxMatches - used_slots; 169 const size_t remaining_slots = kPhysicalWebMaxMatches - used_slots;
145 const size_t remaining_metadata = nearby_url_count_ - i; 170 const size_t remaining_metadata = nearby_url_count_ - i;
146 if ((remaining_slots == 1) && (remaining_metadata > remaining_slots)) { 171 if ((remaining_slots == 1) && (remaining_metadata > remaining_slots)) {
147 AppendOverflowItem(remaining_metadata, relevance, title); 172 AppendOverflowItem(remaining_metadata, relevance, title);
148 break; 173 break;
149 } 174 }
150 175
(...skipping 20 matching lines...) Expand all
171 ACMatchClassification(0, ACMatchClassification::NONE)); 196 ACMatchClassification(0, ACMatchClassification::NONE));
172 197
173 matches_.push_back(match); 198 matches_.push_back(match);
174 ++used_slots; 199 ++used_slots;
175 } 200 }
176 201
177 UMA_HISTOGRAM_EXACT_LINEAR( 202 UMA_HISTOGRAM_EXACT_LINEAR(
178 "Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches); 203 "Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches);
179 } 204 }
180 205
206 void PhysicalWebProvider::ConstructQuerySuggestMatches(
207 std::unique_ptr<base::ListValue> metadata_list,
208 const AutocompleteInput& input) {
209 // Passing nullptr for the TitledUrlNodeSorter will cause the returned match
210 // list to be unsorted.
211 bookmarks::TitledUrlIndex index(nullptr);
212 std::vector<std::unique_ptr<PhysicalWebNode> > nodes;
213 const size_t metadata_count = metadata_list->GetSize();
214 for (size_t i = 0; i < metadata_count; ++i) {
215 base::DictionaryValue* metadata_item = NULL;
216 if (metadata_list->GetDictionary(i, &metadata_item)) {
217 nodes.push_back(base::MakeUnique<PhysicalWebNode>(*metadata_item));
218 index.Add(nodes.back().get());
219 }
220 }
221
222 std::vector<bookmarks::TitledUrlMatch> titled_url_matches;
223 index.GetResultsMatching(input.text(), kPhysicalWebIndexMaxMatches,
224 query_parser::MatchingAlgorithm::DEFAULT,
225 &titled_url_matches);
226
227 size_t used_slots = 0;
228 const base::string16 fixed_up_input(FixupUserInput(input).second);
229 for (auto titled_url_match : titled_url_matches) {
230 const int relevance = after_typing_base_relevance_ - used_slots;
231 matches_.push_back(
232 TitledUrlMatchToAutocompleteMatch(
233 this, client_->GetSchemeClassifier(), input, fixed_up_input,
234 titled_url_match, AutocompleteMatchType::PHYSICAL_WEB, relevance));
235 ++used_slots;
236 if (matches_.size() >= kPhysicalWebMaxMatches) {
237 break;
238 }
239 }
240 }
241
181 void PhysicalWebProvider::AppendOverflowItem(int additional_url_count, 242 void PhysicalWebProvider::AppendOverflowItem(int additional_url_count,
182 int relevance, 243 int relevance,
183 const base::string16& title) { 244 const base::string16& title) {
184 std::string url_string = "chrome://physical-web"; 245 std::string url_string = "chrome://physical-web";
185 GURL url(url_string); 246 GURL url(url_string);
186 247
187 AutocompleteMatch match(this, relevance, false, 248 AutocompleteMatch match(this, relevance, false,
188 AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW); 249 AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW);
189 match.destination_url = url; 250 match.destination_url = url;
190 251
(...skipping 14 matching lines...) Expand all
205 AutocompleteInput::FormattedStringWithEquivalentMeaning( 266 AutocompleteInput::FormattedStringWithEquivalentMeaning(
206 url, match.contents, client_->GetSchemeClassifier()); 267 url, match.contents, client_->GetSchemeClassifier());
207 268
208 match.description = 269 match.description =
209 l10n_util::GetStringUTF16(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION); 270 l10n_util::GetStringUTF16(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION);
210 match.description_class.push_back( 271 match.description_class.push_back(
211 ACMatchClassification(0, ACMatchClassification::NONE)); 272 ACMatchClassification(0, ACMatchClassification::NONE));
212 273
213 matches_.push_back(match); 274 matches_.push_back(match);
214 } 275 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698