Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "chrome/browser/autocomplete/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1300 ACMatches::const_iterator SearchProvider::FindTopMatch( | 1300 ACMatches::const_iterator SearchProvider::FindTopMatch( |
| 1301 bool autocomplete_result_will_reorder_for_default_match) const { | 1301 bool autocomplete_result_will_reorder_for_default_match) const { |
| 1302 if (!autocomplete_result_will_reorder_for_default_match) | 1302 if (!autocomplete_result_will_reorder_for_default_match) |
| 1303 return matches_.begin(); | 1303 return matches_.begin(); |
| 1304 ACMatches::const_iterator it = matches_.begin(); | 1304 ACMatches::const_iterator it = matches_.begin(); |
| 1305 while ((it != matches_.end()) && !it->allowed_to_be_default_match) | 1305 while ((it != matches_.end()) && !it->allowed_to_be_default_match) |
| 1306 ++it; | 1306 ++it; |
| 1307 return it; | 1307 return it; |
| 1308 } | 1308 } |
| 1309 | 1309 |
| 1310 bool SearchProvider::IsTopMatchNavigationInKeywordMode( | 1310 bool SearchProvider::IsTopMatchNavigation( |
| 1311 bool autocomplete_result_will_reorder_for_default_match) const { | 1311 bool autocomplete_result_will_reorder_for_default_match) const { |
| 1312 ACMatches::const_iterator first_match = | 1312 ACMatches::const_iterator first_match = |
| 1313 FindTopMatch(autocomplete_result_will_reorder_for_default_match); | 1313 FindTopMatch(autocomplete_result_will_reorder_for_default_match); |
| 1314 return !providers_.keyword_provider().empty() && | 1314 return (first_match != matches_.end()) && |
| 1315 (first_match != matches_.end()) && | |
| 1316 (first_match->type == AutocompleteMatchType::NAVSUGGEST); | 1315 (first_match->type == AutocompleteMatchType::NAVSUGGEST); |
| 1317 } | 1316 } |
| 1318 | 1317 |
| 1318 bool SearchProvider::HasKeywordMatchThatCanBeDefault( | |
| 1319 bool autocomplete_result_will_reorder_for_default_match) const { | |
| 1320 // In regular (non-reorder) mode we don't care about the | |
| 1321 // |allowed_to_be_default_match| state, so return true saying | |
| 1322 // everything is fine. | |
| 1323 if (!autocomplete_result_will_reorder_for_default_match) | |
| 1324 return true; | |
|
Peter Kasting
2013/11/19 02:58:24
It seems kinda wrong to do this here, because it e
Mark P
2013/11/20 19:05:52
Good point. It does seem wrong. Fixed.
| |
| 1325 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | |
| 1326 if (keyword_url == NULL) // not in keyword mode -> say everything's okay | |
| 1327 return true; | |
| 1328 for (ACMatches::const_iterator it = matches_.begin(); it != matches_.end(); | |
| 1329 ++it) { | |
| 1330 if ((it->keyword == keyword_url->keyword()) && | |
| 1331 it->allowed_to_be_default_match) | |
| 1332 return true; | |
| 1333 } | |
| 1334 return false; | |
| 1335 } | |
| 1336 | |
| 1319 bool SearchProvider::IsTopMatchScoreTooLow( | 1337 bool SearchProvider::IsTopMatchScoreTooLow( |
| 1320 bool autocomplete_result_will_reorder_for_default_match) const { | 1338 bool autocomplete_result_will_reorder_for_default_match) const { |
| 1321 // In reorder mode, there's no such thing as a score that's too low. | 1339 // In reorder mode, there's no such thing as a score that's too low. |
| 1322 if (autocomplete_result_will_reorder_for_default_match) | 1340 if (autocomplete_result_will_reorder_for_default_match) |
| 1323 return false; | 1341 return false; |
| 1324 | 1342 |
| 1325 // Here we use CalculateRelevanceForVerbatimIgnoringKeywordModeState() | 1343 // Here we use CalculateRelevanceForVerbatimIgnoringKeywordModeState() |
| 1326 // rather than CalculateRelevanceForVerbatim() because the latter returns | 1344 // rather than CalculateRelevanceForVerbatim() because the latter returns |
| 1327 // a very low score (250) if keyword mode is active. This is because | 1345 // a very low score (250) if keyword mode is active. This is because |
| 1328 // when keyword mode is active the user probably wants the keyword matches, | 1346 // when keyword mode is active the user probably wants the keyword matches, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1357 if (it->allowed_to_be_default_match) | 1375 if (it->allowed_to_be_default_match) |
| 1358 return true; | 1376 return true; |
| 1359 if (!autocomplete_result_will_reorder_for_default_match) | 1377 if (!autocomplete_result_will_reorder_for_default_match) |
| 1360 return false; | 1378 return false; |
| 1361 } | 1379 } |
| 1362 return false; | 1380 return false; |
| 1363 } | 1381 } |
| 1364 | 1382 |
| 1365 void SearchProvider::UpdateMatches() { | 1383 void SearchProvider::UpdateMatches() { |
| 1366 base::TimeTicks update_matches_start_time(base::TimeTicks::Now()); | 1384 base::TimeTicks update_matches_start_time(base::TimeTicks::Now()); |
| 1385 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | |
| 1367 ConvertResultsToAutocompleteMatches(); | 1386 ConvertResultsToAutocompleteMatches(); |
| 1368 | 1387 |
| 1388 // True if the omnibox will reorder matches as necessary to make the first | |
| 1389 // one something that is allowed to be the default match. | |
| 1390 const bool omnibox_will_reorder_for_legal_default_match = | |
| 1391 OmniboxFieldTrial::ReorderForLegalDefaultMatch( | |
| 1392 input_.current_page_classification()); | |
| 1393 | |
| 1369 // Check constraints that may be violated by suggested relevances. | 1394 // Check constraints that may be violated by suggested relevances. |
| 1370 if (!matches_.empty() && | 1395 if (!matches_.empty() && |
| 1371 (default_results_.HasServerProvidedScores() || | 1396 (default_results_.HasServerProvidedScores() || |
| 1372 keyword_results_.HasServerProvidedScores())) { | 1397 keyword_results_.HasServerProvidedScores())) { |
| 1373 // These blocks attempt to repair undesirable behavior by suggested | 1398 // These blocks attempt to repair undesirable behavior by suggested |
| 1374 // relevances with minimal impact, preserving other suggested relevances. | 1399 // relevances with minimal impact, preserving other suggested relevances. |
| 1375 | 1400 |
| 1376 // True if the omnibox will reorder matches as necessary to make the first | 1401 if ((keyword_url != NULL) && |
| 1377 // one something that is allowed to be the default match. | 1402 IsTopMatchNavigation(omnibox_will_reorder_for_legal_default_match)) { |
| 1378 const bool omnibox_will_reorder_for_legal_default_match = | |
| 1379 OmniboxFieldTrial::ReorderForLegalDefaultMatch( | |
| 1380 input_.current_page_classification()); | |
| 1381 if (IsTopMatchNavigationInKeywordMode( | |
| 1382 omnibox_will_reorder_for_legal_default_match)) { | |
| 1383 // Correct the suggested relevance scores if the top match is a | 1403 // Correct the suggested relevance scores if the top match is a |
| 1384 // navigation in keyword mode, since inlining a navigation match | 1404 // navigation in keyword mode, since inlining a navigation match |
| 1385 // would break the user out of keyword mode. By the way, if the top | 1405 // would break the user out of keyword mode. We only need to do this |
| 1386 // match is a non-keyword match (query or navsuggestion) in keyword | 1406 // correction in regular (non-reorder) mode; in reorder mode, we rely |
| 1387 // mode, the user would also break out of keyword mode. However, | 1407 // on the fact that navigation matches are marked as not allowed to be |
| 1388 // that situation is impossible given the current scoring paradigm | 1408 // the default match. |
|
Peter Kasting
2013/11/19 02:58:24
This comment doesn't seem to match the code? It l
Mark P
2013/11/20 19:05:52
Clarified comment and added DCHECK.
| |
| 1389 // and the fact that only one search engine (Google) provides suggested | |
| 1390 // relevance scores at this time. | |
| 1391 DemoteKeywordNavigationMatchesPastTopQuery(); | 1409 DemoteKeywordNavigationMatchesPastTopQuery(); |
| 1392 ConvertResultsToAutocompleteMatches(); | 1410 ConvertResultsToAutocompleteMatches(); |
| 1393 DCHECK(!IsTopMatchNavigationInKeywordMode( | 1411 DCHECK(!IsTopMatchNavigation( |
| 1394 omnibox_will_reorder_for_legal_default_match)); | 1412 omnibox_will_reorder_for_legal_default_match)); |
| 1395 } | 1413 } |
| 1414 if ((keyword_url != NULL) && !HasKeywordMatchThatCanBeDefault( | |
| 1415 omnibox_will_reorder_for_legal_default_match)) { | |
| 1416 // In keyword mode, disregard the keyword verbatim suggested relevance | |
| 1417 // if necessary so there at least one keyword match that's allowed to | |
| 1418 // be the default match. | |
| 1419 keyword_results_.verbatim_relevance = -1; | |
| 1420 ConvertResultsToAutocompleteMatches(); | |
| 1421 } | |
| 1396 if (IsTopMatchScoreTooLow(omnibox_will_reorder_for_legal_default_match)) { | 1422 if (IsTopMatchScoreTooLow(omnibox_will_reorder_for_legal_default_match)) { |
| 1397 // Disregard the suggested verbatim relevance if the top score is below | 1423 // Disregard the suggested verbatim relevance if the top score is below |
| 1398 // the usual verbatim value. For example, a BarProvider may rely on | 1424 // the usual verbatim value. For example, a BarProvider may rely on |
| 1399 // SearchProvider's verbatim or inlineable matches for input "foo" (all | 1425 // SearchProvider's verbatim or inlineable matches for input "foo" (all |
| 1400 // allowed to be default match) to always outrank its own lowly-ranked | 1426 // allowed to be default match) to always outrank its own lowly-ranked |
| 1401 // "bar" matches that shouldn't be the default match. | 1427 // "bar" matches that shouldn't be the default match. |
| 1402 default_results_.verbatim_relevance = -1; | 1428 default_results_.verbatim_relevance = -1; |
| 1403 keyword_results_.verbatim_relevance = -1; | 1429 keyword_results_.verbatim_relevance = -1; |
| 1404 ConvertResultsToAutocompleteMatches(); | 1430 ConvertResultsToAutocompleteMatches(); |
| 1405 } | 1431 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1422 // match or inlinable). For example, input "foo" should not invoke a | 1448 // match or inlinable). For example, input "foo" should not invoke a |
| 1423 // search for "bar", which would happen if the "bar" search match | 1449 // search for "bar", which would happen if the "bar" search match |
| 1424 // outranked all other matches. On the other hand, if the omnibox will | 1450 // outranked all other matches. On the other hand, if the omnibox will |
| 1425 // reorder matches as necessary to put a legal default match at the top, | 1451 // reorder matches as necessary to put a legal default match at the top, |
| 1426 // all we need to guarantee is that SearchProvider returns a legal | 1452 // all we need to guarantee is that SearchProvider returns a legal |
| 1427 // default match. (The omnibox always needs at least one legal default | 1453 // default match. (The omnibox always needs at least one legal default |
| 1428 // match, and it relies on SearchProvider to always return one.) | 1454 // match, and it relies on SearchProvider to always return one.) |
| 1429 ApplyCalculatedRelevance(); | 1455 ApplyCalculatedRelevance(); |
| 1430 ConvertResultsToAutocompleteMatches(); | 1456 ConvertResultsToAutocompleteMatches(); |
| 1431 } | 1457 } |
| 1432 DCHECK(!IsTopMatchNavigationInKeywordMode( | 1458 DCHECK((keyword_url == NULL) || |
| 1459 !IsTopMatchNavigation(omnibox_will_reorder_for_legal_default_match)); | |
| 1460 DCHECK((keyword_url == NULL) || HasKeywordMatchThatCanBeDefault( | |
| 1433 omnibox_will_reorder_for_legal_default_match)); | 1461 omnibox_will_reorder_for_legal_default_match)); |
| 1434 DCHECK(!IsTopMatchScoreTooLow( | 1462 DCHECK(!IsTopMatchScoreTooLow( |
| 1435 omnibox_will_reorder_for_legal_default_match)); | 1463 omnibox_will_reorder_for_legal_default_match)); |
| 1436 DCHECK(!IsTopMatchSearchWithURLInput( | 1464 DCHECK(!IsTopMatchSearchWithURLInput( |
| 1437 omnibox_will_reorder_for_legal_default_match)); | 1465 omnibox_will_reorder_for_legal_default_match)); |
| 1438 DCHECK(HasValidDefaultMatch(omnibox_will_reorder_for_legal_default_match)); | 1466 DCHECK(HasValidDefaultMatch(omnibox_will_reorder_for_legal_default_match)); |
| 1439 } | 1467 } |
| 1440 | 1468 |
| 1469 if ((keyword_url != NULL) && HasKeywordMatchThatCanBeDefault( | |
| 1470 omnibox_will_reorder_for_legal_default_match)) { | |
| 1471 // If there is a keyword match that is allowed to be the default match, | |
| 1472 // then prohibit default provider matches from being the defaul match lest | |
| 1473 // such matches cause the user to break out of keyword mode. | |
| 1474 for (ACMatches::const_iterator keyword_match_it = matches_.begin(); | |
| 1475 keyword_match_it != matches_.end(); ++keyword_match_it) { | |
| 1476 if (keyword_match_it->allowed_to_be_default_match && | |
| 1477 (keyword_match_it->keyword == keyword_url->keyword())) { | |
|
Peter Kasting
2013/11/19 02:58:24
Nit: You know, if we had a functor that could comp
Mark P
2013/11/20 19:05:52
I realized part of this block is redundant with Ha
| |
| 1478 // Found one such match. | |
| 1479 for (ACMatches::iterator it = matches_.begin(); it != matches_.end(); | |
| 1480 ++it) { | |
| 1481 if (it->keyword != keyword_url->keyword()) | |
| 1482 it->allowed_to_be_default_match = false; | |
| 1483 } | |
| 1484 break; | |
| 1485 } | |
| 1486 } | |
| 1487 } | |
| 1488 | |
| 1441 base::TimeTicks update_starred_start_time(base::TimeTicks::Now()); | 1489 base::TimeTicks update_starred_start_time(base::TimeTicks::Now()); |
| 1442 UpdateStarredStateOfMatches(); | 1490 UpdateStarredStateOfMatches(); |
| 1443 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.UpdateStarredTime", | 1491 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.UpdateStarredTime", |
| 1444 base::TimeTicks::Now() - update_starred_start_time); | 1492 base::TimeTicks::Now() - update_starred_start_time); |
| 1445 UpdateDone(); | 1493 UpdateDone(); |
| 1446 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.UpdateMatchesTime", | 1494 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.UpdateMatchesTime", |
| 1447 base::TimeTicks::Now() - update_matches_start_time); | 1495 base::TimeTicks::Now() - update_matches_start_time); |
| 1448 } | 1496 } |
| 1449 | 1497 |
| 1450 void SearchProvider::AddNavigationResultsToMatches( | 1498 void SearchProvider::AddNavigationResultsToMatches( |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1832 // Preserve the forced query '?' prefix in |match.fill_into_edit|. | 1880 // Preserve the forced query '?' prefix in |match.fill_into_edit|. |
| 1833 // Otherwise, user edits to a suggestion would show non-Search results. | 1881 // Otherwise, user edits to a suggestion would show non-Search results. |
| 1834 if (input_.type() == AutocompleteInput::FORCED_QUERY) { | 1882 if (input_.type() == AutocompleteInput::FORCED_QUERY) { |
| 1835 match.fill_into_edit.insert(0, ASCIIToUTF16("?")); | 1883 match.fill_into_edit.insert(0, ASCIIToUTF16("?")); |
| 1836 if (inline_autocomplete_offset != string16::npos) | 1884 if (inline_autocomplete_offset != string16::npos) |
| 1837 ++inline_autocomplete_offset; | 1885 ++inline_autocomplete_offset; |
| 1838 } | 1886 } |
| 1839 if (!input_.prevent_inline_autocomplete() && | 1887 if (!input_.prevent_inline_autocomplete() && |
| 1840 (inline_autocomplete_offset != string16::npos)) { | 1888 (inline_autocomplete_offset != string16::npos)) { |
| 1841 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); | 1889 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); |
| 1842 match.allowed_to_be_default_match = true; | 1890 // A navsuggestion can only be the default match when there is no |
| 1891 // keyword provider active lest it appear first and breaks the user | |
|
Peter Kasting
2013/11/19 02:58:24
Nit: breaks -> break
Also probably add a comma af
Mark P
2013/11/20 19:05:52
Agree with both. Done.
| |
| 1892 // out of keyword mode. | |
| 1893 match.allowed_to_be_default_match = | |
| 1894 (providers_.GetKeywordProviderURL() == NULL); | |
| 1843 match.inline_autocompletion = | 1895 match.inline_autocompletion = |
| 1844 match.fill_into_edit.substr(inline_autocomplete_offset); | 1896 match.fill_into_edit.substr(inline_autocomplete_offset); |
| 1845 } | 1897 } |
| 1846 | 1898 |
| 1847 match.contents = net::FormatUrl(navigation.url(), languages, | 1899 match.contents = net::FormatUrl(navigation.url(), languages, |
| 1848 format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start); | 1900 format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start); |
| 1849 // If the first match in the untrimmed string was inside a scheme that we | 1901 // If the first match in the untrimmed string was inside a scheme that we |
| 1850 // trimmed, look for a subsequent match. | 1902 // trimmed, look for a subsequent match. |
| 1851 if (match_start == string16::npos) | 1903 if (match_start == string16::npos) |
| 1852 match_start = match.contents.find(input); | 1904 match_start = match.contents.find(input); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1907 it->set_relevance(max_query_relevance); | 1959 it->set_relevance(max_query_relevance); |
| 1908 it->set_relevance_from_server(relevance_from_server); | 1960 it->set_relevance_from_server(relevance_from_server); |
| 1909 } | 1961 } |
| 1910 } | 1962 } |
| 1911 | 1963 |
| 1912 void SearchProvider::UpdateDone() { | 1964 void SearchProvider::UpdateDone() { |
| 1913 // We're done when the timer isn't running, there are no suggest queries | 1965 // We're done when the timer isn't running, there are no suggest queries |
| 1914 // pending, and we're not waiting on Instant. | 1966 // pending, and we're not waiting on Instant. |
| 1915 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); | 1967 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); |
| 1916 } | 1968 } |
| OLD | NEW |