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/autocomplete_controller.h" | 5 #include "chrome/browser/autocomplete/autocomplete_controller.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 namespace { | 43 namespace { |
44 | 44 |
45 // Converts the given match to a type (and possibly subtype) based on the AQS | 45 // Converts the given match to a type (and possibly subtype) based on the AQS |
46 // specification. For more details, see | 46 // specification. For more details, see |
47 // http://goto.google.com/binary-clients-logging. | 47 // http://goto.google.com/binary-clients-logging. |
48 void AutocompleteMatchToAssistedQuery( | 48 void AutocompleteMatchToAssistedQuery( |
49 const AutocompleteMatch::Type& match, size_t* type, size_t* subtype) { | 49 const AutocompleteMatch::Type& match, size_t* type, size_t* subtype) { |
50 // This type indicates a native chrome suggestion. | 50 // This type indicates a native chrome suggestion. |
51 *type = 69; | 51 *type = 69; |
52 // Default value, indicating no subtype. | 52 // Default value, indicating no subtype. |
53 *subtype = string16::npos; | 53 *subtype = base::string16::npos; |
54 | 54 |
55 switch (match) { | 55 switch (match) { |
56 case AutocompleteMatchType::SEARCH_SUGGEST: { | 56 case AutocompleteMatchType::SEARCH_SUGGEST: { |
57 *type = 0; | 57 *type = 0; |
58 return; | 58 return; |
59 } | 59 } |
60 case AutocompleteMatchType::NAVSUGGEST: { | 60 case AutocompleteMatchType::NAVSUGGEST: { |
61 *type = 5; | 61 *type = 5; |
62 return; | 62 return; |
63 } | 63 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 // the existing available autocompletions string, encoding according to the | 105 // the existing available autocompletions string, encoding according to the |
106 // spec. | 106 // spec. |
107 void AppendAvailableAutocompletion(size_t type, | 107 void AppendAvailableAutocompletion(size_t type, |
108 size_t subtype, | 108 size_t subtype, |
109 int count, | 109 int count, |
110 std::string* autocompletions) { | 110 std::string* autocompletions) { |
111 if (!autocompletions->empty()) | 111 if (!autocompletions->empty()) |
112 autocompletions->append("j"); | 112 autocompletions->append("j"); |
113 base::StringAppendF(autocompletions, "%" PRIuS, type); | 113 base::StringAppendF(autocompletions, "%" PRIuS, type); |
114 // Subtype is optional - string16::npos indicates no subtype. | 114 // Subtype is optional - string16::npos indicates no subtype. |
115 if (subtype != string16::npos) | 115 if (subtype != base::string16::npos) |
116 base::StringAppendF(autocompletions, "i%" PRIuS, subtype); | 116 base::StringAppendF(autocompletions, "i%" PRIuS, subtype); |
117 if (count > 1) | 117 if (count > 1) |
118 base::StringAppendF(autocompletions, "l%d", count); | 118 base::StringAppendF(autocompletions, "l%d", count); |
119 } | 119 } |
120 | 120 |
121 // Returns whether the autocompletion is trivial enough that we consider it | 121 // Returns whether the autocompletion is trivial enough that we consider it |
122 // an autocompletion for which the omnibox autocompletion code did not add | 122 // an autocompletion for which the omnibox autocompletion code did not add |
123 // any value. | 123 // any value. |
124 bool IsTrivialAutocompletion(const AutocompleteMatch& match) { | 124 bool IsTrivialAutocompletion(const AutocompleteMatch& match) { |
125 return match.type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || | 125 return match.type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 result_.Reset(); // Not really necessary. | 208 result_.Reset(); // Not really necessary. |
209 Stop(false); | 209 Stop(false); |
210 | 210 |
211 for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i) | 211 for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i) |
212 (*i)->Release(); | 212 (*i)->Release(); |
213 | 213 |
214 providers_.clear(); // Not really necessary. | 214 providers_.clear(); // Not really necessary. |
215 } | 215 } |
216 | 216 |
217 void AutocompleteController::Start(const AutocompleteInput& input) { | 217 void AutocompleteController::Start(const AutocompleteInput& input) { |
218 const string16 old_input_text(input_.text()); | 218 const base::string16 old_input_text(input_.text()); |
219 const AutocompleteInput::MatchesRequested old_matches_requested = | 219 const AutocompleteInput::MatchesRequested old_matches_requested = |
220 input_.matches_requested(); | 220 input_.matches_requested(); |
221 input_ = input; | 221 input_ = input; |
222 | 222 |
223 // See if we can avoid rerunning autocomplete when the query hasn't changed | 223 // See if we can avoid rerunning autocomplete when the query hasn't changed |
224 // much. When the user presses or releases the ctrl key, the desired_tld | 224 // much. When the user presses or releases the ctrl key, the desired_tld |
225 // changes, and when the user finishes an IME composition, inline autocomplete | 225 // changes, and when the user finishes an IME composition, inline autocomplete |
226 // may no longer be prevented. In both these cases the text itself hasn't | 226 // may no longer be prevented. In both these cases the text itself hasn't |
227 // changed since the last query, and some providers can do much less work (and | 227 // changed since the last query, and some providers can do much less work (and |
228 // get matches back more quickly). Taking advantage of this reduces flicker. | 228 // get matches back more quickly). Taking advantage of this reduces flicker. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 result_.Reset(); | 299 result_.Reset(); |
300 // NOTE: We pass in false since we're trying to only clear the popup, not | 300 // NOTE: We pass in false since we're trying to only clear the popup, not |
301 // touch the edit... this is all a mess and should be cleaned up :( | 301 // touch the edit... this is all a mess and should be cleaned up :( |
302 NotifyChanged(false); | 302 NotifyChanged(false); |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 void AutocompleteController::StartZeroSuggest( | 306 void AutocompleteController::StartZeroSuggest( |
307 const GURL& url, | 307 const GURL& url, |
308 AutocompleteInput::PageClassification page_classification, | 308 AutocompleteInput::PageClassification page_classification, |
309 const string16& permanent_text) { | 309 const base::string16& permanent_text) { |
310 if (zero_suggest_provider_ != NULL) { | 310 if (zero_suggest_provider_ != NULL) { |
311 DCHECK(!in_start_); // We should not be already running a query. | 311 DCHECK(!in_start_); // We should not be already running a query. |
312 in_zero_suggest_ = true; | 312 in_zero_suggest_ = true; |
313 zero_suggest_provider_->StartZeroSuggest( | 313 zero_suggest_provider_->StartZeroSuggest( |
314 url, page_classification, permanent_text); | 314 url, page_classification, permanent_text); |
315 } | 315 } |
316 } | 316 } |
317 | 317 |
318 void AutocompleteController::StopZeroSuggest() { | 318 void AutocompleteController::StopZeroSuggest() { |
319 if (zero_suggest_provider_ != NULL) { | 319 if (zero_suggest_provider_ != NULL) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 match->destination_url = | 400 match->destination_url = |
401 GURL(template_url->url_ref().ReplaceSearchTerms(search_terms_args)); | 401 GURL(template_url->url_ref().ReplaceSearchTerms(search_terms_args)); |
402 } | 402 } |
403 | 403 |
404 void AutocompleteController::UpdateResult( | 404 void AutocompleteController::UpdateResult( |
405 bool regenerate_result, | 405 bool regenerate_result, |
406 bool force_notify_default_match_changed) { | 406 bool force_notify_default_match_changed) { |
407 const bool last_default_was_valid = result_.default_match() != result_.end(); | 407 const bool last_default_was_valid = result_.default_match() != result_.end(); |
408 // The following three variables are only set and used if | 408 // The following three variables are only set and used if |
409 // |last_default_was_valid|. | 409 // |last_default_was_valid|. |
410 string16 last_default_fill_into_edit, last_default_keyword, | 410 base::string16 last_default_fill_into_edit, last_default_keyword, |
411 last_default_associated_keyword; | 411 last_default_associated_keyword; |
412 if (last_default_was_valid) { | 412 if (last_default_was_valid) { |
413 last_default_fill_into_edit = result_.default_match()->fill_into_edit; | 413 last_default_fill_into_edit = result_.default_match()->fill_into_edit; |
414 last_default_keyword = result_.default_match()->keyword; | 414 last_default_keyword = result_.default_match()->keyword; |
415 if (result_.default_match()->associated_keyword != NULL) | 415 if (result_.default_match()->associated_keyword != NULL) |
416 last_default_associated_keyword = | 416 last_default_associated_keyword = |
417 result_.default_match()->associated_keyword->keyword; | 417 result_.default_match()->associated_keyword->keyword; |
418 } | 418 } |
419 | 419 |
420 if (regenerate_result) | 420 if (regenerate_result) |
(...skipping 19 matching lines...) Expand all Loading... |
440 // This conditional needs to match the conditional in Start that invokes | 440 // This conditional needs to match the conditional in Start that invokes |
441 // StartExpireTimer. | 441 // StartExpireTimer. |
442 result_.CopyOldMatches(input_, last_result, profile_); | 442 result_.CopyOldMatches(input_, last_result, profile_); |
443 } | 443 } |
444 | 444 |
445 UpdateKeywordDescriptions(&result_); | 445 UpdateKeywordDescriptions(&result_); |
446 UpdateAssociatedKeywords(&result_); | 446 UpdateAssociatedKeywords(&result_); |
447 UpdateAssistedQueryStats(&result_); | 447 UpdateAssistedQueryStats(&result_); |
448 | 448 |
449 const bool default_is_valid = result_.default_match() != result_.end(); | 449 const bool default_is_valid = result_.default_match() != result_.end(); |
450 string16 default_associated_keyword; | 450 base::string16 default_associated_keyword; |
451 if (default_is_valid && | 451 if (default_is_valid && |
452 (result_.default_match()->associated_keyword != NULL)) { | 452 (result_.default_match()->associated_keyword != NULL)) { |
453 default_associated_keyword = | 453 default_associated_keyword = |
454 result_.default_match()->associated_keyword->keyword; | 454 result_.default_match()->associated_keyword->keyword; |
455 } | 455 } |
456 // We've gotten async results. Send notification that the default match | 456 // We've gotten async results. Send notification that the default match |
457 // updated if fill_into_edit, associated_keyword, or keyword differ. (The | 457 // updated if fill_into_edit, associated_keyword, or keyword differ. (The |
458 // second can change if we've just started Chrome and the keyword database | 458 // second can change if we've just started Chrome and the keyword database |
459 // finishes loading while processing this request. The third can change | 459 // finishes loading while processing this request. The third can change |
460 // if we swapped from interpreting the input as a search--which gets | 460 // if we swapped from interpreting the input as a search--which gets |
(...skipping 12 matching lines...) Expand all Loading... |
473 last_time_default_match_changed_ = base::TimeTicks::Now(); | 473 last_time_default_match_changed_ = base::TimeTicks::Now(); |
474 | 474 |
475 NotifyChanged(force_notify_default_match_changed || notify_default_match); | 475 NotifyChanged(force_notify_default_match_changed || notify_default_match); |
476 } | 476 } |
477 | 477 |
478 void AutocompleteController::UpdateAssociatedKeywords( | 478 void AutocompleteController::UpdateAssociatedKeywords( |
479 AutocompleteResult* result) { | 479 AutocompleteResult* result) { |
480 if (!keyword_provider_) | 480 if (!keyword_provider_) |
481 return; | 481 return; |
482 | 482 |
483 std::set<string16> keywords; | 483 std::set<base::string16> keywords; |
484 for (ACMatches::iterator match(result->begin()); match != result->end(); | 484 for (ACMatches::iterator match(result->begin()); match != result->end(); |
485 ++match) { | 485 ++match) { |
486 string16 keyword(match->GetSubstitutingExplicitlyInvokedKeyword(profile_)); | 486 base::string16 keyword( |
| 487 match->GetSubstitutingExplicitlyInvokedKeyword(profile_)); |
487 if (!keyword.empty()) { | 488 if (!keyword.empty()) { |
488 keywords.insert(keyword); | 489 keywords.insert(keyword); |
489 continue; | 490 continue; |
490 } | 491 } |
491 | 492 |
492 // Only add the keyword if the match does not have a duplicate keyword with | 493 // Only add the keyword if the match does not have a duplicate keyword with |
493 // a more relevant match. | 494 // a more relevant match. |
494 keyword = match->associated_keyword.get() ? | 495 keyword = match->associated_keyword.get() ? |
495 match->associated_keyword->keyword : | 496 match->associated_keyword->keyword : |
496 keyword_provider_->GetKeywordForText(match->fill_into_edit); | 497 keyword_provider_->GetKeywordForText(match->fill_into_edit); |
497 if (!keyword.empty() && !keywords.count(keyword)) { | 498 if (!keyword.empty() && !keywords.count(keyword)) { |
498 keywords.insert(keyword); | 499 keywords.insert(keyword); |
499 | 500 |
500 if (!match->associated_keyword.get()) | 501 if (!match->associated_keyword.get()) |
501 match->associated_keyword.reset(new AutocompleteMatch( | 502 match->associated_keyword.reset(new AutocompleteMatch( |
502 keyword_provider_->CreateVerbatimMatch(match->fill_into_edit, | 503 keyword_provider_->CreateVerbatimMatch(match->fill_into_edit, |
503 keyword, input_))); | 504 keyword, input_))); |
504 } else { | 505 } else { |
505 match->associated_keyword.reset(); | 506 match->associated_keyword.reset(); |
506 } | 507 } |
507 } | 508 } |
508 } | 509 } |
509 | 510 |
510 void AutocompleteController::UpdateKeywordDescriptions( | 511 void AutocompleteController::UpdateKeywordDescriptions( |
511 AutocompleteResult* result) { | 512 AutocompleteResult* result) { |
512 string16 last_keyword; | 513 base::string16 last_keyword; |
513 for (AutocompleteResult::iterator i(result->begin()); i != result->end(); | 514 for (AutocompleteResult::iterator i(result->begin()); i != result->end(); |
514 ++i) { | 515 ++i) { |
515 if ((i->provider->type() == AutocompleteProvider::TYPE_KEYWORD && | 516 if ((i->provider->type() == AutocompleteProvider::TYPE_KEYWORD && |
516 !i->keyword.empty()) || | 517 !i->keyword.empty()) || |
517 (i->provider->type() == AutocompleteProvider::TYPE_SEARCH && | 518 (i->provider->type() == AutocompleteProvider::TYPE_SEARCH && |
518 AutocompleteMatch::IsSearchType(i->type))) { | 519 AutocompleteMatch::IsSearchType(i->type))) { |
519 i->description.clear(); | 520 i->description.clear(); |
520 i->description_class.clear(); | 521 i->description_class.clear(); |
521 DCHECK(!i->keyword.empty()); | 522 DCHECK(!i->keyword.empty()); |
522 if (i->keyword != last_keyword) { | 523 if (i->keyword != last_keyword) { |
(...skipping 19 matching lines...) Expand all Loading... |
542 } | 543 } |
543 | 544 |
544 void AutocompleteController::UpdateAssistedQueryStats( | 545 void AutocompleteController::UpdateAssistedQueryStats( |
545 AutocompleteResult* result) { | 546 AutocompleteResult* result) { |
546 if (result->empty()) | 547 if (result->empty()) |
547 return; | 548 return; |
548 | 549 |
549 // Build the impressions string (the AQS part after "."). | 550 // Build the impressions string (the AQS part after "."). |
550 std::string autocompletions; | 551 std::string autocompletions; |
551 int count = 0; | 552 int count = 0; |
552 size_t last_type = string16::npos; | 553 size_t last_type = base::string16::npos; |
553 size_t last_subtype = string16::npos; | 554 size_t last_subtype = base::string16::npos; |
554 for (ACMatches::iterator match(result->begin()); match != result->end(); | 555 for (ACMatches::iterator match(result->begin()); match != result->end(); |
555 ++match) { | 556 ++match) { |
556 size_t type = string16::npos; | 557 size_t type = base::string16::npos; |
557 size_t subtype = string16::npos; | 558 size_t subtype = base::string16::npos; |
558 AutocompleteMatchToAssistedQuery(match->type, &type, &subtype); | 559 AutocompleteMatchToAssistedQuery(match->type, &type, &subtype); |
559 if (last_type != string16::npos && | 560 if (last_type != base::string16::npos && |
560 (type != last_type || subtype != last_subtype)) { | 561 (type != last_type || subtype != last_subtype)) { |
561 AppendAvailableAutocompletion( | 562 AppendAvailableAutocompletion( |
562 last_type, last_subtype, count, &autocompletions); | 563 last_type, last_subtype, count, &autocompletions); |
563 count = 1; | 564 count = 1; |
564 } else { | 565 } else { |
565 count++; | 566 count++; |
566 } | 567 } |
567 last_type = type; | 568 last_type = type; |
568 last_subtype = subtype; | 569 last_subtype = subtype; |
569 } | 570 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 // the disruptive effect of belated omnibox updates, updates that | 633 // the disruptive effect of belated omnibox updates, updates that |
633 // come after the user has had to time to read the whole dropdown | 634 // come after the user has had to time to read the whole dropdown |
634 // and doesn't expect it to change. | 635 // and doesn't expect it to change. |
635 const int kStopTimeMS = 1500; | 636 const int kStopTimeMS = 1500; |
636 stop_timer_.Start(FROM_HERE, | 637 stop_timer_.Start(FROM_HERE, |
637 base::TimeDelta::FromMilliseconds(kStopTimeMS), | 638 base::TimeDelta::FromMilliseconds(kStopTimeMS), |
638 base::Bind(&AutocompleteController::Stop, | 639 base::Bind(&AutocompleteController::Stop, |
639 base::Unretained(this), | 640 base::Unretained(this), |
640 false)); | 641 false)); |
641 } | 642 } |
OLD | NEW |