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

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

Issue 2591053002: Show PhysicalWebProvider suggestions with omnibox input (Closed)
Patch Set: fix nits Created 3 years, 11 months 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
« no previous file with comments | « components/omnibox/browser/physical_web_provider.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
24 // is intended to be between ClipboardURLProvider and ZeroSuggestProvider.
25 // Subsequent matches should decrease in relevance to preserve the ordering
26 // in the metadata list.
27 static const int kPhysicalWebUrlBaseRelevance = 700;
28
29 // The maximum length of the page title's part of the overflow item's 31 // 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 32 // 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 33 // Physical Web match item (non-overflow item) we allow the omnibox display to
32 // truncate the title instead. 34 // truncate the title instead.
33 static const size_t kMaxTitleLengthInOverflow = 15; 35 static const size_t kMaxTitleLengthInOverflow = 15;
36
37 // The maximum number of Physical Web URLs to retrieve from the index.
38 static const size_t kPhysicalWebIndexMaxMatches = 50;
39
34 } 40 }
35 41
36 // static 42 // static
37 const size_t PhysicalWebProvider::kPhysicalWebMaxMatches = 1; 43 const size_t PhysicalWebProvider::kPhysicalWebMaxMatches = 1;
38 44
39 // static 45 // static
40 PhysicalWebProvider* PhysicalWebProvider::Create( 46 PhysicalWebProvider* PhysicalWebProvider::Create(
41 AutocompleteProviderClient* client, 47 AutocompleteProviderClient* client,
42 HistoryURLProvider* history_url_provider) { 48 HistoryURLProvider* history_url_provider) {
43 return new PhysicalWebProvider(client, history_url_provider); 49 return new PhysicalWebProvider(client, history_url_provider);
44 } 50 }
45 51
46 void PhysicalWebProvider::Start(const AutocompleteInput& input, 52 void PhysicalWebProvider::Start(const AutocompleteInput& input,
47 bool minimal_changes) { 53 bool minimal_changes) {
48 DCHECK(kPhysicalWebMaxMatches < kMaxMatches); 54 DCHECK(kPhysicalWebMaxMatches < kMaxMatches);
49 55
50 Stop(false, false); 56 Stop(false, false);
51 57
52 done_ = false; 58 done_ = false;
53 matches_.clear(); 59 matches_.clear();
54 60
55 // Stop providing suggestions when the user enters text into the omnibox. 61 had_physical_web_suggestions_ = false;
56 if (!input.from_omnibox_focus()) { 62 if (input.from_omnibox_focus())
57 done_ = true; 63 had_physical_web_suggestions_at_focus_or_later_ = false;
58 return;
59 }
60 64
61 // Don't provide suggestions in incognito mode. 65 // Don't provide suggestions in incognito mode.
62 if (client_->IsOffTheRecord()) { 66 if (client_->IsOffTheRecord()) {
63 done_ = true; 67 done_ = true;
64 nearby_url_count_ = 0; 68 nearby_url_count_ = 0;
65 return; 69 return;
66 } 70 }
67 71
68 physical_web::PhysicalWebDataSource* data_source = 72 physical_web::PhysicalWebDataSource* data_source =
69 client_->GetPhysicalWebDataSource(); 73 client_->GetPhysicalWebDataSource();
70 if (!data_source) { 74 if (!data_source) {
71 done_ = true; 75 done_ = true;
72 nearby_url_count_ = 0; 76 nearby_url_count_ = 0;
73 return; 77 return;
74 } 78 }
75 79
76 ConstructMatches(data_source->GetMetadata().get()); 80 if (input.from_omnibox_focus()) {
81 ConstructZeroSuggestMatches(data_source->GetMetadata());
77 82
78 // Physical Web matches should never be default. If the omnibox input is 83 if (!matches_.empty()) {
79 // non-empty and we have at least one Physical Web match, add the current URL 84 had_physical_web_suggestions_ = true;
80 // as the default so that hitting enter after focusing the omnibox causes the 85 had_physical_web_suggestions_at_focus_or_later_ = true;
81 // current page to reload. If the input field is empty, no default match is 86 }
82 // required. 87
83 if (!matches_.empty() && !input.text().empty()) { 88 if (!zero_suggest_enabled_) {
84 matches_.push_back(VerbatimMatchForURL(client_, input, input.current_url(), 89 matches_.clear();
85 history_url_provider_, -1)); 90 }
91
92 // In zero-suggest, Physical Web matches should never be default. If the
93 // omnibox input is non-empty and we have at least one Physical Web match,
94 // add the current URL as the default so that hitting enter after focusing
95 // the omnibox causes the current page to reload. If the input field is
96 // empty, no default match is required.
97 if (!matches_.empty() && !input.text().empty()) {
98 matches_.push_back(
99 VerbatimMatchForURL(client_, input, input.current_url(),
100 history_url_provider_, -1));
101 }
102 } else {
103 ConstructQuerySuggestMatches(data_source->GetMetadata(), input);
104
105 if (!matches_.empty()) {
106 had_physical_web_suggestions_ = true;
107 had_physical_web_suggestions_at_focus_or_later_ = true;
108 }
109
110 if (!after_typing_enabled_) {
111 matches_.clear();
112 }
86 } 113 }
87 114
88 done_ = true; 115 done_ = true;
89 } 116 }
90 117
91 void PhysicalWebProvider::Stop(bool clear_cached_results, 118 void PhysicalWebProvider::Stop(bool clear_cached_results,
92 bool due_to_user_inactivity) { 119 bool due_to_user_inactivity) {
93 done_ = true; 120 done_ = true;
94 } 121 }
95 122
96 void PhysicalWebProvider::AddProviderInfo(ProvidersInfo* provider_info) const { 123 void PhysicalWebProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
97 // AddProviderInfo is called for each autocomplete provider to allow 124 // Record whether the provider could have provided a Physical Web suggestion,
98 // provider-specific diagnostic info to be added to the omnibox log entry. 125 // even if the suggestion could not be displayed due to the current field
99 // In this case we do not append any diagnostic info and are taking advantage 126 // trial.
100 // of the fact that this method is only called when the user has accepted an 127 provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo());
101 // autocomplete suggestion. 128 metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back();
129 new_entry.set_provider(AsOmniboxEventProviderType());
130 new_entry.set_provider_done(done_);
131 std::vector<uint32_t> field_trial_hashes;
132 OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes(&field_trial_hashes);
133 for (size_t i = 0; i < field_trial_hashes.size(); ++i) {
134 if (had_physical_web_suggestions_)
135 new_entry.mutable_field_trial_triggered()->Add(field_trial_hashes[i]);
136 if (had_physical_web_suggestions_at_focus_or_later_) {
137 new_entry.mutable_field_trial_triggered_in_session()->Add(
138 field_trial_hashes[i]);
139 }
140 }
102 141
103 // When the user accepts an autocomplete suggestion, record the number of 142 // When the user accepts an autocomplete suggestion, record the number of
104 // nearby Physical Web URLs at the time the provider last constructed matches. 143 // nearby Physical Web URLs at the time the provider last constructed matches.
105 UMA_HISTOGRAM_EXACT_LINEAR("Omnibox.SuggestionUsed.NearbyURLCount", 144 UMA_HISTOGRAM_EXACT_LINEAR("Omnibox.SuggestionUsed.NearbyURLCount",
106 nearby_url_count_, 50); 145 nearby_url_count_, 50);
107 } 146 }
108 147
109 PhysicalWebProvider::PhysicalWebProvider( 148 PhysicalWebProvider::PhysicalWebProvider(
110 AutocompleteProviderClient* client, 149 AutocompleteProviderClient* client,
111 HistoryURLProvider* history_url_provider) 150 HistoryURLProvider* history_url_provider)
112 : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB), 151 : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB),
113 client_(client), 152 client_(client),
114 history_url_provider_(history_url_provider) {} 153 history_url_provider_(history_url_provider),
154 zero_suggest_enabled_(
155 OmniboxFieldTrial::InPhysicalWebZeroSuggestFieldTrial()),
156 after_typing_enabled_(
157 OmniboxFieldTrial::InPhysicalWebAfterTypingFieldTrial()),
158 zero_suggest_base_relevance_(
159 OmniboxFieldTrial::GetPhysicalWebZeroSuggestBaseRelevance()),
160 after_typing_base_relevance_(
161 OmniboxFieldTrial::GetPhysicalWebAfterTypingBaseRelevance()) {}
115 162
116 PhysicalWebProvider::~PhysicalWebProvider() { 163 PhysicalWebProvider::~PhysicalWebProvider() {
117 } 164 }
118 165
119 void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) { 166 void PhysicalWebProvider::ConstructZeroSuggestMatches(
167 std::unique_ptr<base::ListValue> metadata_list) {
120 nearby_url_count_ = metadata_list->GetSize(); 168 nearby_url_count_ = metadata_list->GetSize();
121 size_t used_slots = 0; 169 size_t used_slots = 0;
122 170
123 for (size_t i = 0; i < nearby_url_count_; ++i) { 171 for (size_t i = 0; i < nearby_url_count_; ++i) {
124 base::DictionaryValue* metadata_item = NULL; 172 base::DictionaryValue* metadata_item = NULL;
125 if (!metadata_list->GetDictionary(i, &metadata_item)) { 173 if (!metadata_list->GetDictionary(i, &metadata_item)) {
126 continue; 174 continue;
127 } 175 }
128 176
129 std::string url_string; 177 std::string url_string;
130 std::string title_string; 178 std::string title_string;
131 if (!metadata_item->GetString(physical_web::kResolvedUrlKey, &url_string) || 179 if (!metadata_item->GetString(physical_web::kResolvedUrlKey, &url_string) ||
132 !metadata_item->GetString(physical_web::kTitleKey, &title_string)) { 180 !metadata_item->GetString(physical_web::kTitleKey, &title_string)) {
133 continue; 181 continue;
134 } 182 }
135 base::string16 title = 183 base::string16 title =
136 AutocompleteMatch::SanitizeString(base::UTF8ToUTF16(title_string)); 184 AutocompleteMatch::SanitizeString(base::UTF8ToUTF16(title_string));
137 185
138 // Add match items with decreasing relevance to preserve the ordering in 186 // Add match items with decreasing relevance to preserve the ordering in
139 // the metadata list. 187 // the metadata list.
140 int relevance = kPhysicalWebUrlBaseRelevance - used_slots; 188 int relevance = zero_suggest_base_relevance_ - used_slots;
141 189
142 // Append an overflow item if creating a match for each metadata item would 190 // Append an overflow item if creating a match for each metadata item would
143 // exceed the match limit. 191 // exceed the match limit.
144 const size_t remaining_slots = kPhysicalWebMaxMatches - used_slots; 192 const size_t remaining_slots = kPhysicalWebMaxMatches - used_slots;
145 const size_t remaining_metadata = nearby_url_count_ - i; 193 const size_t remaining_metadata = nearby_url_count_ - i;
146 if ((remaining_slots == 1) && (remaining_metadata > remaining_slots)) { 194 if ((remaining_slots == 1) && (remaining_metadata > remaining_slots)) {
147 AppendOverflowItem(remaining_metadata, relevance, title); 195 AppendOverflowItem(remaining_metadata, relevance, title);
148 break; 196 break;
149 } 197 }
150 198
(...skipping 20 matching lines...) Expand all
171 ACMatchClassification(0, ACMatchClassification::NONE)); 219 ACMatchClassification(0, ACMatchClassification::NONE));
172 220
173 matches_.push_back(match); 221 matches_.push_back(match);
174 ++used_slots; 222 ++used_slots;
175 } 223 }
176 224
177 UMA_HISTOGRAM_EXACT_LINEAR( 225 UMA_HISTOGRAM_EXACT_LINEAR(
178 "Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches); 226 "Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches);
179 } 227 }
180 228
229 void PhysicalWebProvider::ConstructQuerySuggestMatches(
230 std::unique_ptr<base::ListValue> metadata_list,
231 const AutocompleteInput& input) {
232 // Passing nullptr for the TitledUrlNodeSorter will cause the returned match
233 // list to be unsorted.
234 bookmarks::TitledUrlIndex index(nullptr);
235 std::vector<std::unique_ptr<PhysicalWebNode> > nodes;
236 const size_t metadata_count = metadata_list->GetSize();
237 for (size_t i = 0; i < metadata_count; ++i) {
238 base::DictionaryValue* metadata_item = NULL;
239 if (metadata_list->GetDictionary(i, &metadata_item)) {
240 nodes.push_back(base::MakeUnique<PhysicalWebNode>(*metadata_item));
241 index.Add(nodes.back().get());
242 }
243 }
244
245 std::vector<bookmarks::TitledUrlMatch> titled_url_matches;
246 index.GetResultsMatching(input.text(), kPhysicalWebIndexMaxMatches,
247 query_parser::MatchingAlgorithm::DEFAULT,
248 &titled_url_matches);
249
250 size_t used_slots = 0;
251 const base::string16 fixed_up_input(FixupUserInput(input).second);
252 for (auto titled_url_match : titled_url_matches) {
253 const int relevance = after_typing_base_relevance_ - used_slots;
254 matches_.push_back(
255 TitledUrlMatchToAutocompleteMatch(
256 this, client_->GetSchemeClassifier(), input, fixed_up_input,
257 titled_url_match, AutocompleteMatchType::PHYSICAL_WEB, relevance));
258 ++used_slots;
259 if (matches_.size() >= kPhysicalWebMaxMatches) {
260 break;
261 }
262 }
263 }
264
181 void PhysicalWebProvider::AppendOverflowItem(int additional_url_count, 265 void PhysicalWebProvider::AppendOverflowItem(int additional_url_count,
182 int relevance, 266 int relevance,
183 const base::string16& title) { 267 const base::string16& title) {
184 std::string url_string = "chrome://physical-web"; 268 std::string url_string = "chrome://physical-web";
185 GURL url(url_string); 269 GURL url(url_string);
186 270
187 AutocompleteMatch match(this, relevance, false, 271 AutocompleteMatch match(this, relevance, false,
188 AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW); 272 AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW);
189 match.destination_url = url; 273 match.destination_url = url;
190 274
(...skipping 14 matching lines...) Expand all
205 AutocompleteInput::FormattedStringWithEquivalentMeaning( 289 AutocompleteInput::FormattedStringWithEquivalentMeaning(
206 url, match.contents, client_->GetSchemeClassifier()); 290 url, match.contents, client_->GetSchemeClassifier());
207 291
208 match.description = 292 match.description =
209 l10n_util::GetStringUTF16(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION); 293 l10n_util::GetStringUTF16(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION);
210 match.description_class.push_back( 294 match.description_class.push_back(
211 ACMatchClassification(0, ACMatchClassification::NONE)); 295 ACMatchClassification(0, ACMatchClassification::NONE));
212 296
213 matches_.push_back(match); 297 matches_.push_back(match);
214 } 298 }
OLDNEW
« no previous file with comments | « components/omnibox/browser/physical_web_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698