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

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

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