OLD | NEW |
---|---|
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/physical_web_node.h" |
19 #include "components/omnibox/browser/url_prefix.h" | |
13 #include "components/omnibox/browser/verbatim_match.h" | 20 #include "components/omnibox/browser/verbatim_match.h" |
14 #include "components/physical_web/data_source/physical_web_data_source.h" | 21 #include "components/physical_web/data_source/physical_web_data_source.h" |
15 #include "components/url_formatter/url_formatter.h" | 22 #include "components/url_formatter/url_formatter.h" |
16 #include "grit/components_strings.h" | 23 #include "grit/components_strings.h" |
17 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
18 #include "ui/gfx/text_elider.h" | 25 #include "ui/gfx/text_elider.h" |
19 #include "url/gurl.h" | 26 #include "url/gurl.h" |
20 | 27 |
21 namespace { | 28 namespace { |
22 | 29 |
23 // Relevance score of the first Physical Web URL autocomplete match. This score | 30 // Relevance score of the first Physical Web URL autocomplete match. This score |
24 // is intended to be between ClipboardURLProvider and ZeroSuggestProvider. | 31 // is intended to be between ClipboardURLProvider and ZeroSuggestProvider. |
25 // Subsequent matches should decrease in relevance to preserve the ordering | 32 // Subsequent matches should decrease in relevance to preserve the ordering |
26 // in the metadata list. | 33 // in the metadata list. |
27 static const int kPhysicalWebUrlBaseRelevance = 700; | 34 static const int kPhysicalWebUrlBaseRelevance = 700; |
28 | 35 |
29 // The maximum length of the page title's part of the overflow item's | 36 // 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 | 37 // 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 | 38 // Physical Web match item (non-overflow item) we allow the omnibox display to |
32 // truncate the title instead. | 39 // truncate the title instead. |
33 static const size_t kMaxTitleLengthInOverflow = 15; | 40 static const size_t kMaxTitleLengthInOverflow = 15; |
41 | |
42 // The maximum number of Physical Web URLs to retrieve from the index. | |
43 static const size_t kPhysicalWebIndexMaxMatches = 50; | |
34 } | 44 } |
Mark P
2016/12/21 18:57:50
style nit (I think): blank line before closing nam
mattreynolds
2016/12/21 22:25:58
Done.
| |
35 | 45 |
36 // static | 46 // static |
37 const size_t PhysicalWebProvider::kPhysicalWebMaxMatches = 1; | 47 const size_t PhysicalWebProvider::kPhysicalWebMaxMatches = 1; |
38 | 48 |
39 // static | 49 // static |
40 PhysicalWebProvider* PhysicalWebProvider::Create( | 50 PhysicalWebProvider* PhysicalWebProvider::Create( |
41 AutocompleteProviderClient* client, | 51 AutocompleteProviderClient* client, |
42 HistoryURLProvider* history_url_provider) { | 52 HistoryURLProvider* history_url_provider) { |
43 return new PhysicalWebProvider(client, history_url_provider); | 53 return new PhysicalWebProvider(client, history_url_provider); |
44 } | 54 } |
45 | 55 |
46 void PhysicalWebProvider::Start(const AutocompleteInput& input, | 56 void PhysicalWebProvider::Start(const AutocompleteInput& input, |
47 bool minimal_changes) { | 57 bool minimal_changes) { |
48 DCHECK(kPhysicalWebMaxMatches < kMaxMatches); | 58 DCHECK(kPhysicalWebMaxMatches < kMaxMatches); |
49 | 59 |
50 Stop(false, false); | 60 Stop(false, false); |
51 | 61 |
52 done_ = false; | 62 done_ = false; |
53 matches_.clear(); | 63 matches_.clear(); |
54 | 64 |
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. | 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 // 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 | 84 // 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 | 85 // 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 | 86 // the omnibox causes the current page to reload. If the input field is |
82 // required. | 87 // empty, no default match is required. |
83 if (!matches_.empty() && !input.text().empty()) { | 88 if (!matches_.empty() && !input.text().empty()) { |
84 matches_.push_back(VerbatimMatchForURL(client_, input, input.current_url(), | 89 matches_.push_back( |
85 history_url_provider_, -1)); | 90 VerbatimMatchForURL(client_, input, input.current_url(), |
91 history_url_provider_, -1)); | |
92 } | |
93 } else { | |
94 ConstructQuerySuggestMatches(data_source->GetMetadata(), input); | |
86 } | 95 } |
87 | 96 |
88 done_ = true; | 97 done_ = true; |
89 } | 98 } |
90 | 99 |
91 void PhysicalWebProvider::Stop(bool clear_cached_results, | 100 void PhysicalWebProvider::Stop(bool clear_cached_results, |
92 bool due_to_user_inactivity) { | 101 bool due_to_user_inactivity) { |
93 done_ = true; | 102 done_ = true; |
94 } | 103 } |
95 | 104 |
(...skipping 13 matching lines...) Expand all Loading... | |
109 PhysicalWebProvider::PhysicalWebProvider( | 118 PhysicalWebProvider::PhysicalWebProvider( |
110 AutocompleteProviderClient* client, | 119 AutocompleteProviderClient* client, |
111 HistoryURLProvider* history_url_provider) | 120 HistoryURLProvider* history_url_provider) |
112 : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB), | 121 : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB), |
113 client_(client), | 122 client_(client), |
114 history_url_provider_(history_url_provider) {} | 123 history_url_provider_(history_url_provider) {} |
115 | 124 |
116 PhysicalWebProvider::~PhysicalWebProvider() { | 125 PhysicalWebProvider::~PhysicalWebProvider() { |
117 } | 126 } |
118 | 127 |
119 void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) { | 128 void PhysicalWebProvider::ConstructZeroSuggestMatches( |
129 std::unique_ptr<base::ListValue> metadata_list) { | |
120 nearby_url_count_ = metadata_list->GetSize(); | 130 nearby_url_count_ = metadata_list->GetSize(); |
121 size_t used_slots = 0; | 131 size_t used_slots = 0; |
122 | 132 |
123 for (size_t i = 0; i < nearby_url_count_; ++i) { | 133 for (size_t i = 0; i < nearby_url_count_; ++i) { |
124 base::DictionaryValue* metadata_item = NULL; | 134 base::DictionaryValue* metadata_item = NULL; |
125 if (!metadata_list->GetDictionary(i, &metadata_item)) { | 135 if (!metadata_list->GetDictionary(i, &metadata_item)) { |
126 continue; | 136 continue; |
127 } | 137 } |
128 | 138 |
129 std::string url_string; | 139 std::string url_string; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 ACMatchClassification(0, ACMatchClassification::NONE)); | 181 ACMatchClassification(0, ACMatchClassification::NONE)); |
172 | 182 |
173 matches_.push_back(match); | 183 matches_.push_back(match); |
174 ++used_slots; | 184 ++used_slots; |
175 } | 185 } |
176 | 186 |
177 UMA_HISTOGRAM_EXACT_LINEAR( | 187 UMA_HISTOGRAM_EXACT_LINEAR( |
178 "Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches); | 188 "Omnibox.PhysicalWebProviderMatches", matches_.size(), kMaxMatches); |
179 } | 189 } |
180 | 190 |
191 void PhysicalWebProvider::ConstructQuerySuggestMatches( | |
192 std::unique_ptr<base::ListValue> metadata_list, | |
193 const AutocompleteInput& input) { | |
194 bookmarks::TitledUrlIndex index(NULL); | |
Mark P
2016/12/21 18:57:50
Please either add a comment (in this changelist or
mattreynolds
2016/12/21 22:25:58
I'll add the comment here and comment the TitledUr
Mark P
2016/12/21 23:21:40
Acknowledged.
| |
195 std::vector<std::unique_ptr<PhysicalWebNode> > nodes; | |
196 size_t metadata_count = metadata_list->GetSize(); | |
Mark P
2016/12/21 18:57:50
nit: const
mattreynolds
2016/12/21 22:25:58
Done.
| |
197 for (size_t i = 0; i < metadata_count; ++i) { | |
198 base::DictionaryValue* metadata_item = NULL; | |
199 if (metadata_list->GetDictionary(i, &metadata_item)) { | |
200 nodes.push_back(base::MakeUnique<PhysicalWebNode>(*metadata_item)); | |
Mark P
2016/12/21 18:57:50
This seems roundabout to me. Why not call index.A
mattreynolds
2016/12/21 22:25:58
TitledUrlIndex doesn't take ownership of the Physi
Mark P
2016/12/21 23:21:40
Acknowledged.
| |
201 index.Add(nodes.back().get()); | |
202 } | |
203 } | |
204 | |
205 std::vector<bookmarks::TitledUrlMatch> titled_url_matches; | |
206 index.GetResultsMatching(input.text(), kPhysicalWebIndexMaxMatches, | |
207 query_parser::MatchingAlgorithm::DEFAULT, | |
208 &titled_url_matches); | |
209 | |
210 size_t used_slots = 0; | |
211 const base::string16 fixed_up_input(FixupUserInput(input).second); | |
212 for (auto titled_url_match : titled_url_matches) { | |
213 const int relevance = kPhysicalWebUrlBaseRelevance - used_slots; | |
214 matches_.push_back( | |
215 TitledUrlMatchToAutocompleteMatch( | |
216 this, client_->GetSchemeClassifier(), input, fixed_up_input, | |
217 titled_url_match, AutocompleteMatchType::PHYSICAL_WEB, relevance)); | |
218 ++used_slots; | |
219 if (matches_.size() >= kPhysicalWebMaxMatches) { | |
220 break; | |
221 } | |
222 } | |
223 } | |
224 | |
181 void PhysicalWebProvider::AppendOverflowItem(int additional_url_count, | 225 void PhysicalWebProvider::AppendOverflowItem(int additional_url_count, |
182 int relevance, | 226 int relevance, |
183 const base::string16& title) { | 227 const base::string16& title) { |
184 std::string url_string = "chrome://physical-web"; | 228 std::string url_string = "chrome://physical-web"; |
185 GURL url(url_string); | 229 GURL url(url_string); |
186 | 230 |
187 AutocompleteMatch match(this, relevance, false, | 231 AutocompleteMatch match(this, relevance, false, |
188 AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW); | 232 AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW); |
189 match.destination_url = url; | 233 match.destination_url = url; |
190 | 234 |
(...skipping 14 matching lines...) Expand all Loading... | |
205 AutocompleteInput::FormattedStringWithEquivalentMeaning( | 249 AutocompleteInput::FormattedStringWithEquivalentMeaning( |
206 url, match.contents, client_->GetSchemeClassifier()); | 250 url, match.contents, client_->GetSchemeClassifier()); |
207 | 251 |
208 match.description = | 252 match.description = |
209 l10n_util::GetStringUTF16(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION); | 253 l10n_util::GetStringUTF16(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION); |
210 match.description_class.push_back( | 254 match.description_class.push_back( |
211 ACMatchClassification(0, ACMatchClassification::NONE)); | 255 ACMatchClassification(0, ACMatchClassification::NONE)); |
212 | 256 |
213 matches_.push_back(match); | 257 matches_.push_back(match); |
214 } | 258 } |
OLD | NEW |