OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/history_url_provider.h" | 5 #include "chrome/browser/autocomplete/history_url_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/metrics/field_trial.h" | |
14 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
15 #include "base/string_util.h" | 14 #include "base/string_util.h" |
16 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
17 #include "chrome/browser/autocomplete/autocomplete_field_trial.h" | |
18 #include "chrome/browser/autocomplete/autocomplete_match.h" | 16 #include "chrome/browser/autocomplete/autocomplete_match.h" |
19 #include "chrome/browser/history/history.h" | 17 #include "chrome/browser/history/history.h" |
20 #include "chrome/browser/history/history_backend.h" | 18 #include "chrome/browser/history/history_backend.h" |
21 #include "chrome/browser/history/history_database.h" | 19 #include "chrome/browser/history/history_database.h" |
22 #include "chrome/browser/history/history_types.h" | 20 #include "chrome/browser/history/history_types.h" |
23 #include "chrome/browser/net/url_fixer_upper.h" | 21 #include "chrome/browser/net/url_fixer_upper.h" |
24 #include "chrome/browser/prefs/pref_service.h" | 22 #include "chrome/browser/prefs/pref_service.h" |
25 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
26 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
27 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 dont_suggest_exact_input(false) { | 307 dont_suggest_exact_input(false) { |
310 } | 308 } |
311 | 309 |
312 HistoryURLProviderParams::~HistoryURLProviderParams() { | 310 HistoryURLProviderParams::~HistoryURLProviderParams() { |
313 } | 311 } |
314 | 312 |
315 HistoryURLProvider::HistoryURLProvider(ACProviderListener* listener, | 313 HistoryURLProvider::HistoryURLProvider(ACProviderListener* listener, |
316 Profile* profile) | 314 Profile* profile) |
317 : HistoryProvider(listener, profile, "HistoryURL"), | 315 : HistoryProvider(listener, profile, "HistoryURL"), |
318 prefixes_(GetPrefixes()), | 316 prefixes_(GetPrefixes()), |
319 params_(NULL), | 317 params_(NULL) { |
320 enable_aggressive_scoring_(false) { | |
321 enum AggressivenessOption { | |
322 AGGRESSIVENESS_DISABLED = 0, | |
323 AGGRESSIVENESS_ENABLED = 1, | |
324 AGGRESSIVENESS_AUTO_BUT_NOT_IN_FIELD_TRIAL = 2, | |
325 AGGRESSIVENESS_FIELD_TRIAL_DEFAULT_GROUP = 3, | |
326 AGGRESSIVENESS_FIELD_TRIAL_EXPERIMENT_GROUP = 4, | |
327 NUM_OPTIONS = 5 | |
328 }; | |
329 // should always be overwritten | |
330 AggressivenessOption aggressiveness_option = NUM_OPTIONS; | |
331 | |
332 const std::string switch_value = CommandLine::ForCurrentProcess()-> | |
333 GetSwitchValueASCII(switches::kOmniboxAggressiveHistoryURL); | |
334 if (switch_value == switches::kOmniboxAggressiveHistoryURLEnabled) { | |
335 aggressiveness_option = AGGRESSIVENESS_ENABLED; | |
336 enable_aggressive_scoring_ = true; | |
337 } else if (switch_value == switches::kOmniboxAggressiveHistoryURLDisabled) { | |
338 aggressiveness_option = AGGRESSIVENESS_DISABLED; | |
339 enable_aggressive_scoring_ = false; | |
340 } else { | |
341 // Either: switch_value == switches::kOmniboxAggressiveHistoryURLAuto | |
342 // or someone passed an invalid command line flag. We'll default | |
343 // the latter case to automatic but report an error. | |
344 if (!switch_value.empty() && | |
345 (switch_value != switches::kOmniboxAggressiveHistoryURLAuto)) { | |
346 LOG(ERROR) << "Invalid --omnibox-aggressive-with-history-url option " | |
347 << "received on command line: " << switch_value; | |
348 LOG(ERROR) << "Making automatic."; | |
349 } | |
350 // Automatic means eligible for the field trial. | |
351 // For the field trial stuff to work correctly, we must be running | |
352 // on the same thread as the thread that created the field trial, | |
353 // which happens via a call to AutocompleteFieldTrial::Active in | |
354 // chrome_browser_main.cc on the main thread. Let's check this to | |
355 // be sure. We check "if we've heard of the UI thread then we'd better | |
356 // be on it." The first part is necessary so unit tests pass. (Many | |
357 // unit tests don't set up the threading naming system; hence | |
358 // CurrentlyOn(UI thread) will fail.) | |
359 DCHECK(!content::BrowserThread::IsWellKnownThread( | |
360 content::BrowserThread::UI) || | |
361 content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
362 if (AutocompleteFieldTrial::InAggressiveHUPFieldTrial()) { | |
363 if (AutocompleteFieldTrial::InAggressiveHUPFieldTrialExperimentGroup()) { | |
364 enable_aggressive_scoring_ = true; | |
365 aggressiveness_option = AGGRESSIVENESS_FIELD_TRIAL_EXPERIMENT_GROUP; | |
366 } else { | |
367 enable_aggressive_scoring_ = false; | |
368 aggressiveness_option = AGGRESSIVENESS_FIELD_TRIAL_DEFAULT_GROUP; | |
369 } | |
370 } else { | |
371 enable_aggressive_scoring_ = false; | |
372 aggressiveness_option = AGGRESSIVENESS_AUTO_BUT_NOT_IN_FIELD_TRIAL; | |
373 } | |
374 } | |
375 | |
376 // Add a beacon to the logs that'll allow us to identify later what | |
377 // aggressiveness state a user is in. Do this by incrementing a | |
378 // bucket in a histogram, where the bucket represents the user's | |
379 // aggressiveness state. | |
380 UMA_HISTOGRAM_ENUMERATION( | |
381 "Omnibox.AggressiveHistoryURLProviderFieldTrialBeacon", | |
382 aggressiveness_option, NUM_OPTIONS); | |
383 } | 318 } |
384 | 319 |
385 void HistoryURLProvider::Start(const AutocompleteInput& input, | 320 void HistoryURLProvider::Start(const AutocompleteInput& input, |
386 bool minimal_changes) { | 321 bool minimal_changes) { |
387 // NOTE: We could try hard to do less work in the |minimal_changes| case | 322 // NOTE: We could try hard to do less work in the |minimal_changes| case |
388 // here; some clever caching would let us reuse the raw matches from the | 323 // here; some clever caching would let us reuse the raw matches from the |
389 // history DB without re-querying. However, we'd still have to go back to | 324 // history DB without re-querying. However, we'd still have to go back to |
390 // the history thread to mark these up properly, and if pass 2 is currently | 325 // the history thread to mark these up properly, and if pass 2 is currently |
391 // running, we'd need to wait for it to return to the main thread before | 326 // running, we'd need to wait for it to return to the main thread before |
392 // doing this (we can't just write new data for it to read due to thread | 327 // doing this (we can't just write new data for it to read due to thread |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 // kMaxMatches results plus the What You Typed result, if it was added to | 461 // kMaxMatches results plus the What You Typed result, if it was added to |
527 // |history_matches| above. | 462 // |history_matches| above. |
528 CullRedirects(backend, &history_matches, kMaxMatches + exact_suggestion); | 463 CullRedirects(backend, &history_matches, kMaxMatches + exact_suggestion); |
529 | 464 |
530 // Convert the history matches to autocomplete matches. | 465 // Convert the history matches to autocomplete matches. |
531 for (size_t i = first_match; i < history_matches.size(); ++i) { | 466 for (size_t i = first_match; i < history_matches.size(); ++i) { |
532 const history::HistoryMatch& match = history_matches[i]; | 467 const history::HistoryMatch& match = history_matches[i]; |
533 DCHECK(!have_what_you_typed_match || | 468 DCHECK(!have_what_you_typed_match || |
534 (match.url_info.url() != | 469 (match.url_info.url() != |
535 GURL(params->matches.front().destination_url))); | 470 GURL(params->matches.front().destination_url))); |
536 // With aggressive scoring, we assume that the results are all of similar | 471 // If we've assigned a score already, all later matches score one |
537 // quality, so we give them consecutively decreasing scores. | 472 // less than the previous match. |
538 relevance = (enable_aggressive_scoring_ && (relevance > 0)) ? | 473 relevance = (relevance > 0) ? (relevance - 1) : |
539 (relevance - 1) : | |
540 CalculateRelevance(NORMAL, history_matches.size() - 1 - i); | 474 CalculateRelevance(NORMAL, history_matches.size() - 1 - i); |
541 AutocompleteMatch ac_match = HistoryMatchToACMatch(params, match, | 475 AutocompleteMatch ac_match = HistoryMatchToACMatch(params, match, |
542 NORMAL, relevance); | 476 NORMAL, relevance); |
543 params->matches.push_back(ac_match); | 477 params->matches.push_back(ac_match); |
544 } | 478 } |
545 } | 479 } |
546 | 480 |
547 // Called on the main thread when the query is complete. | 481 // Called on the main thread when the query is complete. |
548 void HistoryURLProvider::QueryComplete( | 482 void HistoryURLProvider::QueryComplete( |
549 HistoryURLProviderParams* params_gets_deleted) { | 483 HistoryURLProviderParams* params_gets_deleted) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 prefixes.push_back(history::Prefix(ASCIIToUTF16("https://"), 1)); | 526 prefixes.push_back(history::Prefix(ASCIIToUTF16("https://"), 1)); |
593 prefixes.push_back(history::Prefix(ASCIIToUTF16("http://"), 1)); | 527 prefixes.push_back(history::Prefix(ASCIIToUTF16("http://"), 1)); |
594 prefixes.push_back(history::Prefix(ASCIIToUTF16("ftp://"), 1)); | 528 prefixes.push_back(history::Prefix(ASCIIToUTF16("ftp://"), 1)); |
595 // Empty string catches within-scheme matches as well. | 529 // Empty string catches within-scheme matches as well. |
596 prefixes.push_back(history::Prefix(string16(), 0)); | 530 prefixes.push_back(history::Prefix(string16(), 0)); |
597 return prefixes; | 531 return prefixes; |
598 } | 532 } |
599 | 533 |
600 int HistoryURLProvider::CalculateRelevance(MatchType match_type, | 534 int HistoryURLProvider::CalculateRelevance(MatchType match_type, |
601 size_t match_number) const { | 535 size_t match_number) const { |
602 int shift = enable_aggressive_scoring_ ? kMaxMatches : 0; | |
603 | |
604 switch (match_type) { | 536 switch (match_type) { |
605 case INLINE_AUTOCOMPLETE: | 537 case INLINE_AUTOCOMPLETE: |
606 return 1410 + shift; | 538 return 1410 + kMaxMatches; |
607 | 539 |
608 case UNVISITED_INTRANET: | 540 case UNVISITED_INTRANET: |
609 return 1400 + shift; | 541 return 1400 + kMaxMatches; |
610 | 542 |
611 case WHAT_YOU_TYPED: | 543 case WHAT_YOU_TYPED: |
612 return 1200 + shift; | 544 return 1200 + kMaxMatches; |
613 | 545 |
614 default: // NORMAL | 546 default: // NORMAL |
615 return 900 + static_cast<int>(match_number); | 547 return 900 + static_cast<int>(match_number); |
616 } | 548 } |
617 } | 549 } |
618 | 550 |
619 void HistoryURLProvider::RunAutocompletePasses( | 551 void HistoryURLProvider::RunAutocompletePasses( |
620 const AutocompleteInput& input, | 552 const AutocompleteInput& input, |
621 bool fixup_input_and_run_pass_1) { | 553 bool fixup_input_and_run_pass_1) { |
622 matches_.clear(); | 554 matches_.clear(); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 &match.contents_class); | 940 &match.contents_class); |
1009 } | 941 } |
1010 match.description = info.title(); | 942 match.description = info.title(); |
1011 AutocompleteMatch::ClassifyMatchInString(params->input.text(), | 943 AutocompleteMatch::ClassifyMatchInString(params->input.text(), |
1012 info.title(), | 944 info.title(), |
1013 ACMatchClassification::NONE, | 945 ACMatchClassification::NONE, |
1014 &match.description_class); | 946 &match.description_class); |
1015 | 947 |
1016 return match; | 948 return match; |
1017 } | 949 } |
OLD | NEW |