OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 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" | 5 #include "components/omnibox/browser/physical_web_provider.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "components/metrics/proto/omnibox_event.pb.h" | 14 #include "components/metrics/proto/omnibox_event.pb.h" |
15 #include "components/omnibox/browser/mock_autocomplete_provider_client.h" | 15 #include "components/omnibox/browser/mock_autocomplete_provider_client.h" |
16 #include "components/omnibox/browser/test_scheme_classifier.h" | 16 #include "components/omnibox/browser/test_scheme_classifier.h" |
17 #include "components/physical_web/data_source/physical_web_data_source.h" | 17 #include "components/physical_web/data_source/physical_web_data_source.h" |
18 #include "components/physical_web/data_source/physical_web_listener.h" | 18 #include "components/physical_web/data_source/physical_web_listener.h" |
19 #include "grit/components_strings.h" | 19 #include "grit/components_strings.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
| 23 #include "ui/gfx/text_elider.h" |
23 #include "url/gurl.h" | 24 #include "url/gurl.h" |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
27 // A mock implementation of the Physical Web data source that allows setting | 28 // A mock implementation of the Physical Web data source that allows setting |
28 // metadata for nearby URLs directly. | 29 // metadata for nearby URLs directly. |
29 class MockPhysicalWebDataSource : public PhysicalWebDataSource { | 30 class MockPhysicalWebDataSource : public PhysicalWebDataSource { |
30 public: | 31 public: |
31 MockPhysicalWebDataSource() : metadata_(new base::ListValue()) {} | 32 MockPhysicalWebDataSource() : metadata_(new base::ListValue()) {} |
32 ~MockPhysicalWebDataSource() override {} | 33 ~MockPhysicalWebDataSource() override {} |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 // Convenience method to avoid downcasts when accessing the mock data source. | 78 // Convenience method to avoid downcasts when accessing the mock data source. |
78 MockPhysicalWebDataSource* GetMockPhysicalWebDataSource() { | 79 MockPhysicalWebDataSource* GetMockPhysicalWebDataSource() { |
79 return physical_web_data_source_.get(); | 80 return physical_web_data_source_.get(); |
80 } | 81 } |
81 | 82 |
82 private: | 83 private: |
83 std::unique_ptr<MockPhysicalWebDataSource> physical_web_data_source_; | 84 std::unique_ptr<MockPhysicalWebDataSource> physical_web_data_source_; |
84 TestSchemeClassifier scheme_classifier_; | 85 TestSchemeClassifier scheme_classifier_; |
85 }; | 86 }; |
86 | 87 |
| 88 } // namespace |
| 89 |
87 class PhysicalWebProviderTest : public testing::Test { | 90 class PhysicalWebProviderTest : public testing::Test { |
88 protected: | 91 protected: |
89 PhysicalWebProviderTest() : provider_(NULL) {} | 92 PhysicalWebProviderTest() : provider_(NULL) {} |
90 ~PhysicalWebProviderTest() override {} | 93 ~PhysicalWebProviderTest() override {} |
91 | 94 |
92 void SetUp() override { | 95 void SetUp() override { |
93 client_.reset(new FakeAutocompleteProviderClient()); | 96 client_.reset(new FakeAutocompleteProviderClient()); |
94 provider_ = PhysicalWebProvider::Create(client_.get(), nullptr); | 97 provider_ = PhysicalWebProvider::Create(client_.get(), nullptr); |
95 } | 98 } |
96 | 99 |
(...skipping 25 matching lines...) Expand all Loading... |
122 static AutocompleteInput CreateInputForNTP() { | 125 static AutocompleteInput CreateInputForNTP() { |
123 return AutocompleteInput( | 126 return AutocompleteInput( |
124 base::string16(), base::string16::npos, std::string(), GURL(), | 127 base::string16(), base::string16::npos, std::string(), GURL(), |
125 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, | 128 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, |
126 false, false, true, true, true, TestSchemeClassifier()); | 129 false, false, true, true, true, TestSchemeClassifier()); |
127 } | 130 } |
128 | 131 |
129 // Construct an AutocompleteInput to represent tapping the omnibox with |url| | 132 // Construct an AutocompleteInput to represent tapping the omnibox with |url| |
130 // as the current web page. | 133 // as the current web page. |
131 static AutocompleteInput CreateInputWithCurrentUrl(const std::string& url) { | 134 static AutocompleteInput CreateInputWithCurrentUrl(const std::string& url) { |
132 return AutocompleteInput(base::ASCIIToUTF16(url), base::string16::npos, | 135 return AutocompleteInput(base::UTF8ToUTF16(url), base::string16::npos, |
133 std::string(), GURL(url), | 136 std::string(), GURL(url), |
134 metrics::OmniboxEventProto::OTHER, false, false, | 137 metrics::OmniboxEventProto::OTHER, false, false, |
135 true, true, true, TestSchemeClassifier()); | 138 true, true, true, TestSchemeClassifier()); |
136 } | 139 } |
137 | 140 |
| 141 // For a given |match|, check that the destination URL, contents string, |
| 142 // description string, and default match state agree with the values specified |
| 143 // in |url|, |contents|, |description|, and |allowed_to_be_default_match|. |
| 144 static void ValidateMatch(const AutocompleteMatch& match, |
| 145 const std::string& url, |
| 146 const std::string& contents, |
| 147 const std::string& description, |
| 148 bool allowed_to_be_default_match) { |
| 149 EXPECT_EQ(url, match.destination_url.spec()); |
| 150 EXPECT_EQ(contents, base::UTF16ToUTF8(match.contents)); |
| 151 EXPECT_EQ(description, base::UTF16ToUTF8(match.description)); |
| 152 EXPECT_EQ(allowed_to_be_default_match, match.allowed_to_be_default_match); |
| 153 } |
| 154 |
| 155 // Returns the contents string for an overflow item. Use |truncated_title| |
| 156 // as the title of the first match, |match_count_without_default| as the |
| 157 // total number of matches (not counting the default match), and |
| 158 // |metadata_count| as the number of nearby Physical Web URLs for which we |
| 159 // have metadata. |
| 160 static std::string ConstructOverflowItemContents( |
| 161 const std::string& truncated_title, |
| 162 size_t match_count_without_default, |
| 163 size_t metadata_count) { |
| 164 // Don't treat the overflow item as a metadata match. |
| 165 const size_t metadata_match_count = match_count_without_default - 1; |
| 166 // Determine how many URLs we didn't create match items for. |
| 167 const size_t additional_url_count = metadata_count - metadata_match_count; |
| 168 |
| 169 // Build the contents string. |
| 170 if (truncated_title.empty()) { |
| 171 return l10n_util::GetPluralStringFUTF8( |
| 172 IDS_PHYSICAL_WEB_OVERFLOW_EMPTY_TITLE, additional_url_count); |
| 173 } else { |
| 174 // Subtract one from the additional URL count because the first item is |
| 175 // represented by its title. |
| 176 std::string contents_suffix = l10n_util::GetPluralStringFUTF8( |
| 177 IDS_PHYSICAL_WEB_OVERFLOW, additional_url_count - 1); |
| 178 return truncated_title + " " + contents_suffix; |
| 179 } |
| 180 } |
| 181 |
| 182 // Run a test case using |input| as the simulated state of the omnibox input |
| 183 // field, |metadata_list| as the list of simulated Physical Web metadata, |
| 184 // and |title_truncated| as the truncated title of the first match. In |
| 185 // addition to checking the fields of the overflow item, this will also check |
| 186 // that the total number of matches is equal to |expected_match_count| and |
| 187 // that a default match and overflow item are only present when |
| 188 // |should_expect_default_match| or |should_expect_overflow_item| are true. |
| 189 // Metadata matches are not checked. |
| 190 void OverflowItemTestCase(const AutocompleteInput& input, |
| 191 std::unique_ptr<base::ListValue> metadata_list, |
| 192 const std::string& title_truncated, |
| 193 size_t expected_match_count, |
| 194 bool should_expect_default_match, |
| 195 bool should_expect_overflow_item) { |
| 196 const size_t metadata_count = metadata_list->GetSize(); |
| 197 |
| 198 MockPhysicalWebDataSource* data_source = |
| 199 client_->GetMockPhysicalWebDataSource(); |
| 200 EXPECT_TRUE(data_source); |
| 201 |
| 202 data_source->SetMetadata(std::move(metadata_list)); |
| 203 |
| 204 provider_->Start(input, false); |
| 205 |
| 206 const size_t match_count = provider_->matches().size(); |
| 207 EXPECT_EQ(expected_match_count, match_count); |
| 208 |
| 209 const size_t match_count_without_default = |
| 210 should_expect_default_match ? match_count - 1 : match_count; |
| 211 |
| 212 if (should_expect_overflow_item) { |
| 213 EXPECT_LT(match_count_without_default, metadata_count); |
| 214 } else { |
| 215 EXPECT_EQ(match_count_without_default, metadata_count); |
| 216 } |
| 217 |
| 218 size_t overflow_match_count = 0; |
| 219 size_t default_match_count = 0; |
| 220 for (const auto& match : provider_->matches()) { |
| 221 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) { |
| 222 std::string contents = ConstructOverflowItemContents( |
| 223 title_truncated, match_count_without_default, metadata_count); |
| 224 ValidateMatch( |
| 225 match, "chrome://physical-web/", contents, |
| 226 l10n_util::GetStringUTF8(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION), |
| 227 false); |
| 228 ++overflow_match_count; |
| 229 } else if (match.allowed_to_be_default_match) { |
| 230 ++default_match_count; |
| 231 } |
| 232 } |
| 233 EXPECT_EQ(should_expect_overflow_item ? 1U : 0U, overflow_match_count); |
| 234 EXPECT_EQ(should_expect_default_match ? 1U : 0U, default_match_count); |
| 235 } |
| 236 |
138 std::unique_ptr<FakeAutocompleteProviderClient> client_; | 237 std::unique_ptr<FakeAutocompleteProviderClient> client_; |
139 scoped_refptr<PhysicalWebProvider> provider_; | 238 scoped_refptr<PhysicalWebProvider> provider_; |
140 | 239 |
141 private: | 240 private: |
142 DISALLOW_COPY_AND_ASSIGN(PhysicalWebProviderTest); | 241 DISALLOW_COPY_AND_ASSIGN(PhysicalWebProviderTest); |
143 }; | 242 }; |
144 | 243 |
145 TEST_F(PhysicalWebProviderTest, TestEmptyMetadataListCreatesNoMatches) { | 244 TEST_F(PhysicalWebProviderTest, TestEmptyMetadataListCreatesNoMatches) { |
146 MockPhysicalWebDataSource* data_source = | 245 MockPhysicalWebDataSource* data_source = |
147 client_->GetMockPhysicalWebDataSource(); | 246 client_->GetMockPhysicalWebDataSource(); |
(...skipping 27 matching lines...) Expand all Loading... |
175 | 274 |
176 data_source->SetMetadata(std::move(metadata_list)); | 275 data_source->SetMetadata(std::move(metadata_list)); |
177 | 276 |
178 // Run the test with no text in the omnibox input to simulate NTP. | 277 // Run the test with no text in the omnibox input to simulate NTP. |
179 provider_->Start(CreateInputForNTP(), false); | 278 provider_->Start(CreateInputForNTP(), false); |
180 | 279 |
181 // Check that there is only one match item and its fields are correct. | 280 // Check that there is only one match item and its fields are correct. |
182 EXPECT_EQ(1U, provider_->matches().size()); | 281 EXPECT_EQ(1U, provider_->matches().size()); |
183 const AutocompleteMatch& metadata_match = provider_->matches().front(); | 282 const AutocompleteMatch& metadata_match = provider_->matches().front(); |
184 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, metadata_match.type); | 283 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, metadata_match.type); |
185 EXPECT_EQ(resolved_url, metadata_match.destination_url.spec()); | 284 ValidateMatch(metadata_match, resolved_url, resolved_url, title, false); |
186 EXPECT_EQ(resolved_url, base::UTF16ToASCII(metadata_match.contents)); | |
187 EXPECT_EQ(title, base::UTF16ToASCII(metadata_match.description)); | |
188 EXPECT_FALSE(metadata_match.allowed_to_be_default_match); | |
189 | 285 |
190 // Run the test again with a URL in the omnibox input. An additional match | 286 // Run the test again with a URL in the omnibox input. An additional match |
191 // should be added as a default match. | 287 // should be added as a default match. |
192 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); | 288 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); |
193 | 289 |
194 size_t metadata_match_count = 0; | 290 size_t metadata_match_count = 0; |
195 size_t default_match_count = 0; | 291 size_t default_match_count = 0; |
196 for (const auto& match : provider_->matches()) { | 292 for (const auto& match : provider_->matches()) { |
197 if (match.type == AutocompleteMatchType::PHYSICAL_WEB) { | 293 if (match.type == AutocompleteMatchType::PHYSICAL_WEB) { |
198 EXPECT_EQ(resolved_url, match.destination_url.spec()); | 294 ValidateMatch(match, resolved_url, resolved_url, title, false); |
199 EXPECT_EQ(resolved_url, base::UTF16ToASCII(match.contents)); | |
200 EXPECT_EQ(title, base::UTF16ToASCII(match.description)); | |
201 EXPECT_FALSE(match.allowed_to_be_default_match); | |
202 ++metadata_match_count; | 295 ++metadata_match_count; |
203 } else { | 296 } else { |
204 EXPECT_TRUE(match.allowed_to_be_default_match); | 297 EXPECT_TRUE(match.allowed_to_be_default_match); |
205 ++default_match_count; | 298 ++default_match_count; |
206 } | 299 } |
207 } | 300 } |
208 EXPECT_EQ(2U, provider_->matches().size()); | 301 EXPECT_EQ(2U, provider_->matches().size()); |
209 EXPECT_EQ(1U, metadata_match_count); | 302 EXPECT_EQ(1U, metadata_match_count); |
210 EXPECT_EQ(1U, default_match_count); | 303 EXPECT_EQ(1U, default_match_count); |
211 } | 304 } |
212 | 305 |
213 TEST_F(PhysicalWebProviderTest, TestManyMetadataItemsCreatesOverflowItem) { | |
214 // This test is intended to verify that an overflow item is created when the | |
215 // number of nearby Physical Web URLs exceeds the maximum allowable matches | |
216 // for this provider. The actual limit for the PhysicalWebProvider may be | |
217 // changed in the future, so create enough metadata to exceed the | |
218 // AutocompleteProvider's limit. | |
219 const size_t metadata_count = AutocompleteProvider::kMaxMatches + 1; | |
220 | |
221 MockPhysicalWebDataSource* data_source = | |
222 client_->GetMockPhysicalWebDataSource(); | |
223 EXPECT_TRUE(data_source); | |
224 | |
225 data_source->SetMetadata(CreateMetadata(metadata_count)); | |
226 | |
227 { | |
228 // Run the test with no text in the omnibox input to simulate NTP. | |
229 provider_->Start(CreateInputForNTP(), false); | |
230 | |
231 const size_t match_count = provider_->matches().size(); | |
232 EXPECT_LT(match_count, metadata_count); | |
233 | |
234 // Check that the overflow item is present and its fields are correct. There | |
235 // may be additional match items, but none should be marked as default. | |
236 size_t overflow_match_count = 0; | |
237 for (const auto& match : provider_->matches()) { | |
238 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) { | |
239 EXPECT_EQ("chrome://physical-web/", match.destination_url.spec()); | |
240 EXPECT_EQ("chrome://physical-web/", base::UTF16ToASCII(match.contents)); | |
241 const size_t metadata_matches = match_count - 1; | |
242 std::string description = l10n_util::GetPluralStringFUTF8( | |
243 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - metadata_matches); | |
244 EXPECT_EQ(description, base::UTF16ToASCII(match.description)); | |
245 ++overflow_match_count; | |
246 } | |
247 EXPECT_FALSE(match.allowed_to_be_default_match); | |
248 } | |
249 EXPECT_EQ(1U, overflow_match_count); | |
250 } | |
251 | |
252 { | |
253 // Run the test again with a URL in the omnibox input. An additional match | |
254 // should be added as a default match. | |
255 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); | |
256 | |
257 const size_t match_count = provider_->matches().size(); | |
258 EXPECT_LT(match_count - 1, metadata_count); | |
259 | |
260 // Check that the overflow item and default match are present and their | |
261 // fields are correct. | |
262 size_t overflow_match_count = 0; | |
263 size_t default_match_count = 0; | |
264 for (const auto& match : provider_->matches()) { | |
265 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) { | |
266 EXPECT_EQ("chrome://physical-web/", match.destination_url.spec()); | |
267 EXPECT_EQ("chrome://physical-web/", base::UTF16ToASCII(match.contents)); | |
268 const size_t metadata_matches = match_count - 2; | |
269 std::string description = l10n_util::GetPluralStringFUTF8( | |
270 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - metadata_matches); | |
271 EXPECT_EQ(description, base::UTF16ToASCII(match.description)); | |
272 EXPECT_FALSE(match.allowed_to_be_default_match); | |
273 ++overflow_match_count; | |
274 } else if (match.allowed_to_be_default_match) { | |
275 ++default_match_count; | |
276 } | |
277 } | |
278 EXPECT_EQ(1U, overflow_match_count); | |
279 EXPECT_EQ(1U, default_match_count); | |
280 } | |
281 } | |
282 | |
283 TEST_F(PhysicalWebProviderTest, TestNoMatchesWithUserInput) { | 306 TEST_F(PhysicalWebProviderTest, TestNoMatchesWithUserInput) { |
284 MockPhysicalWebDataSource* data_source = | 307 MockPhysicalWebDataSource* data_source = |
285 client_->GetMockPhysicalWebDataSource(); | 308 client_->GetMockPhysicalWebDataSource(); |
286 EXPECT_TRUE(data_source); | 309 EXPECT_TRUE(data_source); |
287 | 310 |
288 data_source->SetMetadata(CreateMetadata(1)); | 311 data_source->SetMetadata(CreateMetadata(1)); |
289 | 312 |
290 // Construct an AutocompleteInput to simulate user input in the omnibox input | 313 // Construct an AutocompleteInput to simulate user input in the omnibox input |
291 // field. The provider should not generate any matches. | 314 // field. The provider should not generate any matches. |
292 std::string text("user input"); | 315 std::string text("user input"); |
293 const AutocompleteInput input(base::ASCIIToUTF16(text), text.length(), | 316 const AutocompleteInput input( |
294 std::string(), GURL(), | 317 base::UTF8ToUTF16(text), text.length(), std::string(), GURL(), |
295 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, | 318 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, |
296 true, false, true, true, false, TestSchemeClassifier()); | 319 true, false, true, true, false, TestSchemeClassifier()); |
297 provider_->Start(input, false); | 320 provider_->Start(input, false); |
298 | 321 |
299 EXPECT_TRUE(provider_->matches().empty()); | 322 EXPECT_TRUE(provider_->matches().empty()); |
300 } | 323 } |
301 | 324 |
| 325 TEST_F(PhysicalWebProviderTest, TestManyMetadataItemsCreatesOverflowItem) { |
| 326 // Create enough metadata to guarantee an overflow item will be created. |
| 327 const size_t metadata_count = AutocompleteProvider::kMaxMatches + 1; |
| 328 |
| 329 // Run the test with no text in the omnibox input to simulate NTP. |
| 330 OverflowItemTestCase( |
| 331 CreateInputForNTP(), CreateMetadata(metadata_count), "Example title 0", |
| 332 PhysicalWebProvider::kPhysicalWebMaxMatches, false, true); |
| 333 |
| 334 // Run the test again with a URL in the omnibox input. An additional match |
| 335 // should be added as a default match. |
| 336 OverflowItemTestCase(CreateInputWithCurrentUrl("http://www.cnn.com"), |
| 337 CreateMetadata(metadata_count), "Example title 0", |
| 338 PhysicalWebProvider::kPhysicalWebMaxMatches + 1, true, |
| 339 true); |
302 } | 340 } |
| 341 |
| 342 TEST_F(PhysicalWebProviderTest, TestLongPageTitleIsTruncatedInOverflowItem) { |
| 343 // Set a long title for the first item. The page title for this item will |
| 344 // appear in the overflow item's content string. |
| 345 auto metadata_list = CreateMetadata(AutocompleteProvider::kMaxMatches + 1); |
| 346 base::DictionaryValue* metadata_item; |
| 347 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item)); |
| 348 metadata_item->SetString("title", "Extra long example title 0"); |
| 349 |
| 350 OverflowItemTestCase(CreateInputForNTP(), std::move(metadata_list), |
| 351 "Extra long exa" + std::string(gfx::kEllipsis), |
| 352 PhysicalWebProvider::kPhysicalWebMaxMatches, false, |
| 353 true); |
| 354 } |
| 355 |
| 356 TEST_F(PhysicalWebProviderTest, TestEmptyPageTitleInOverflowItem) { |
| 357 // Set an empty title for the first item. Because the title is empty, we will |
| 358 // display an alternate string in the overflow item's contents. |
| 359 auto metadata_list = CreateMetadata(AutocompleteProvider::kMaxMatches + 1); |
| 360 base::DictionaryValue* metadata_item; |
| 361 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item)); |
| 362 metadata_item->SetString("title", ""); |
| 363 |
| 364 OverflowItemTestCase(CreateInputForNTP(), std::move(metadata_list), "", |
| 365 PhysicalWebProvider::kPhysicalWebMaxMatches, false, |
| 366 true); |
| 367 } |
| 368 |
| 369 TEST_F(PhysicalWebProviderTest, TestRTLPageTitleInOverflowItem) { |
| 370 // Set a Hebrew title for the first item. |
| 371 auto metadata_list = CreateMetadata(AutocompleteProvider::kMaxMatches + 1); |
| 372 base::DictionaryValue* metadata_item; |
| 373 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item)); |
| 374 metadata_item->SetString("title", "ויקיפדיה"); |
| 375 |
| 376 OverflowItemTestCase(CreateInputForNTP(), std::move(metadata_list), |
| 377 "ויקיפדיה", PhysicalWebProvider::kPhysicalWebMaxMatches, |
| 378 false, true); |
| 379 } |
OLD | NEW |