autocomplete.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ 6#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ 7#pragma once 8 9#include <string> 10#include <vector> 11 12#include "base/logging.h" 13#include "base/ref_counted.h" 14#include "base/timer.h" 15#include "chrome/common/page_transition_types.h" 16#include "googleurl/src/gurl.h" 17#include "googleurl/src/url_parse.h" 18 19// The AutocompleteController is the center of the autocomplete system. A 20// class creates an instance of the controller, which in turn creates a set of 21// AutocompleteProviders to serve it. The owning class can ask the controller 22// to Start() a query; the controller in turn passes this call down to the 23// providers, each of which keeps track of its own matches and whether it has 24// finished processing the query. When a provider gets more matches or finishes 25// processing, it notifies the controller, which merges the combined matches 26// together and makes the result available to interested observers. 27// 28// The owner may also cancel the current query by calling Stop(), which the 29// controller will in turn communicate to all the providers. No callbacks will 30// happen after a request has been stopped. 31// 32// IMPORTANT: There is NO THREAD SAFETY built into this portion of the 33// autocomplete system. All calls to and from the AutocompleteController should 34// happen on the same thread. AutocompleteProviders are responsible for doing 35// their own thread management when they need to return matches asynchronously. 36// 37// The AutocompleteProviders each return different kinds of matches, such as 38// history or search matches. These matches are given "relevance" scores. 39// Higher scores are better matches than lower scores. The relevance scores and 40// classes providing the respective matches are as follows: 41// 42// UNKNOWN input type: 43// --------------------------------------------------------------------|----- 44// Keyword (non-substituting or in keyword UI mode, exact match) | 1500 45// HistoryURL (exact or inline autocomplete match) | 1400 46// Search Primary Provider (what you typed) | 1300 47// HistoryURL (what you typed) | 1200 48// Keyword (substituting, exact match) | 1100 49// Search Primary Provider (past query in history) | 1050-- 50// HistoryContents (any match in title of starred page) | 1000++ 51// HistoryURL (inexact match) | 900++ 52// Search Primary Provider (navigational suggestion) | 800++ 53// HistoryContents (any match in title of nonstarred page) | 700++ 54// Search Primary Provider (suggestion) | 600++ 55// HistoryContents (any match in body of starred page) | 550++ 56// HistoryContents (any match in body of nonstarred page) | 500++ 57// Keyword (inexact match) | 450 58// Search Secondary Provider (what you typed) | 250 59// Search Secondary Provider (past query in history) | 200-- 60// Search Secondary Provider (navigational suggestion) | 150++ 61// Search Secondary Provider (suggestion) | 100++ 62// 63// REQUESTED_URL input type: 64// --------------------------------------------------------------------|----- 65// Keyword (non-substituting or in keyword UI mode, exact match) | 1500 66// HistoryURL (exact or inline autocomplete match) | 1400 67// HistoryURL (what you typed) | 1200 68// Search Primary Provider (what you typed) | 1150 69// Keyword (substituting, exact match) | 1100 70// Search Primary Provider (past query in history) | 1050-- 71// HistoryContents (any match in title of starred page) | 1000++ 72// HistoryURL (inexact match) | 900++ 73// Search Primary Provider (navigational suggestion) | 800++ 74// HistoryContents (any match in title of nonstarred page) | 700++ 75// Search Primary Provider (suggestion) | 600++ 76// HistoryContents (any match in body of starred page) | 550++ 77// HistoryContents (any match in body of nonstarred page) | 500++ 78// Keyword (inexact match) | 450 79// Search Secondary Provider (what you typed) | 250 80// Search Secondary Provider (past query in history) | 200-- 81// Search Secondary Provider (navigational suggestion) | 150++ 82// Search Secondary Provider (suggestion) | 100++ 83// 84// URL input type: 85// --------------------------------------------------------------------|----- 86// Keyword (non-substituting or in keyword UI mode, exact match) | 1500 87// HistoryURL (exact or inline autocomplete match) | 1400 88// HistoryURL (what you typed) | 1200 89// Keyword (substituting, exact match) | 1100 90// HistoryURL (inexact match) | 900++ 91// Search Primary Provider (what you typed) | 850 92// Search Primary Provider (navigational suggestion) | 800++ 93// Search Primary Provider (past query in history) | 750-- 94// Keyword (inexact match) | 700 95// Search Primary Provider (suggestion) | 300++ 96// Search Secondary Provider (what you typed) | 250 97// Search Secondary Provider (past query in history) | 200-- 98// Search Secondary Provider (navigational suggestion) | 150++ 99// Search Secondary Provider (suggestion) | 100++ 100// 101// QUERY input type: 102// --------------------------------------------------------------------|----- 103// Keyword (non-substituting or in keyword UI mode, exact match) | 1500 104// Keyword (substituting, exact match) | 1450 105// HistoryURL (exact or inline autocomplete match) | 1400 106// Search Primary Provider (what you typed) | 1300 107// Search Primary Provider (past query in history) | 1050-- 108// HistoryContents (any match in title of starred page) | 1000++ 109// HistoryURL (inexact match) | 900++ 110// Search Primary Provider (navigational suggestion) | 800++ 111// HistoryContents (any match in title of nonstarred page) | 700++ 112// Search Primary Provider (suggestion) | 600++ 113// HistoryContents (any match in body of starred page) | 550++ 114// HistoryContents (any match in body of nonstarred page) | 500++ 115// Keyword (inexact match) | 450 116// Search Secondary Provider (what you typed) | 250 117// Search Secondary Provider (past query in history) | 200-- 118// Search Secondary Provider (navigational suggestion) | 150++ 119// Search Secondary Provider (suggestion) | 100++ 120// 121// FORCED_QUERY input type: 122// --------------------------------------------------------------------|----- 123// Search Primary Provider (what you typed) | 1300 124// Search Primary Provider (past query in history) | 1050-- 125// HistoryContents (any match in title of starred page) | 1000++ 126// Search Primary Provider (navigational suggestion) | 800++ 127// HistoryContents (any match in title of nonstarred page) | 700++ 128// Search Primary Provider (suggestion) | 600++ 129// HistoryContents (any match in body of starred page) | 550++ 130// HistoryContents (any match in body of nonstarred page) | 500++ 131// 132// (A search keyword is a keyword with a replacement string; a bookmark keyword 133// is a keyword with no replacement string, that is, a shortcut for a URL.) 134// 135// There are two possible providers for search suggestions. If the user has 136// typed a keyword, then the primary provider is the keyword provider and the 137// secondary provider is the default provider. If the user has not typed a 138// keyword, then the primary provider corresponds to the default provider. 139// 140// The value column gives the ranking returned from the various providers. 141// ++: a series of matches with relevance from n up to (n + max_matches). 142// --: relevance score falls off over time (discounted 50 points @ 15 minutes, 143// 450 points @ two weeks) 144 145class AutocompleteInput; 146struct AutocompleteMatch; 147class AutocompleteProvider; 148class AutocompleteResult; 149class AutocompleteController; 150class HistoryContentsProvider; 151class Profile; 152class TemplateURL; 153 154typedef std::vector<AutocompleteMatch> ACMatches; 155typedef std::vector<AutocompleteProvider*> ACProviders; 156 157// AutocompleteInput ---------------------------------------------------------- 158 159// The user input for an autocomplete query. Allows copying. 160class AutocompleteInput { 161 public: 162 // Note that the type below may be misleading. For example, "http:/" alone 163 // cannot be opened as a URL, so it is marked as a QUERY; yet the user 164 // probably intends to type more and have it eventually become a URL, so we 165 // need to make sure we still run it through inline autocomplete. 166 enum Type { 167 INVALID, // Empty input 168 UNKNOWN, // Valid input whose type cannot be determined 169 REQUESTED_URL, // Input autodetected as UNKNOWN, which the user wants to 170 // treat as an URL by specifying a desired_tld 171 URL, // Input autodetected as a URL 172 QUERY, // Input autodetected as a query 173 FORCED_QUERY, // Input forced to be a query by an initial '?' 174 }; 175 176 AutocompleteInput(); 177 AutocompleteInput(const std::wstring& text, 178 const std::wstring& desired_tld, 179 bool prevent_inline_autocomplete, 180 bool prefer_keyword, 181 bool synchronous_only); 182 ~AutocompleteInput(); 183 184 // Converts |type| to a string representation. Used in logging. 185 static std::string TypeToString(Type type); 186 187 // Parses |text| and returns the type of input this will be interpreted as. 188 // The components of the input are stored in the output parameter |parts|, if 189 // it is non-NULL. 190 static Type Parse(const std::wstring& text, 191 const std::wstring& desired_tld, 192 url_parse::Parsed* parts, 193 std::wstring* scheme); 194 195 // Parses |text| and fill |scheme| and |host| by the positions of them. 196 // The results are almost as same as the result of Parse(), but if the scheme 197 // is view-source, this function returns the positions of scheme and host 198 // in the URL qualified by "view-source:" prefix. 199 static void ParseForEmphasizeComponents(const std::wstring& text, 200 const std::wstring& desired_tld, 201 url_parse::Component* scheme, 202 url_parse::Component* host); 203 204 // Code that wants to format URLs with a format flag including 205 // net::kFormatUrlOmitTrailingSlashOnBareHostname risk changing the meaning if 206 // the result is then parsed as AutocompleteInput. Such code can call this 207 // function with the URL and its formatted string, and it will return a 208 // formatted string with the same meaning as the original URL (i.e. it will 209 // re-append a slash if necessary). 210 static std::wstring FormattedStringWithEquivalentMeaning( 211 const GURL& url, 212 const std::wstring& formatted_url); 213 214 // User-provided text to be completed. 215 const std::wstring& text() const { return text_; } 216 217 // Use of this setter is risky, since no other internal state is updated 218 // besides |text_|. Only callers who know that they're not changing the 219 // type/scheme/etc. should use this. 220 void set_text(const std::wstring& text) { text_ = text; } 221 222 // User's desired TLD, if one is not already present in the text to 223 // autocomplete. When this is non-empty, it also implies that "www." should 224 // be prepended to the domain where possible. This should not have a leading 225 // '.' (use "com" instead of ".com"). 226 const std::wstring& desired_tld() const { return desired_tld_; } 227 228 // The type of input supplied. 229 Type type() const { return type_; } 230 231 // Returns parsed URL components. 232 const url_parse::Parsed& parts() const { return parts_; } 233 234 // The scheme parsed from the provided text; only meaningful when type_ is 235 // URL. 236 const std::wstring& scheme() const { return scheme_; } 237 238 // The input as an URL to navigate to, if possible. 239 const GURL& canonicalized_url() const { return canonicalized_url_; } 240 241 // Returns whether inline autocompletion should be prevented. 242 bool prevent_inline_autocomplete() const { 243 return prevent_inline_autocomplete_; 244 } 245 246 // Returns whether, given an input string consisting solely of a substituting 247 // keyword, we should score it like a non-substituting keyword. 248 bool prefer_keyword() const { return prefer_keyword_; } 249 250 // Returns whether providers should avoid scheduling asynchronous work. If 251 // this is true, providers should stop after returning all the 252 // synchronously-available matches. This also means any in-progress 253 // asynchronous work should be canceled, so no later callbacks are fired. 254 bool synchronous_only() const { return synchronous_only_; } 255 256 // operator==() by another name. 257 bool Equals(const AutocompleteInput& other) const; 258 259 // Resets all internal variables to the null-constructed state. 260 void Clear(); 261 262 private: 263 std::wstring text_; 264 std::wstring desired_tld_; 265 Type type_; 266 url_parse::Parsed parts_; 267 std::wstring scheme_; 268 GURL canonicalized_url_; 269 bool prevent_inline_autocomplete_; 270 bool prefer_keyword_; 271 bool synchronous_only_; 272}; 273 274// AutocompleteMatch ---------------------------------------------------------- 275 276// A single result line with classified spans. The autocomplete popup displays 277// the 'contents' and the 'description' (the description is optional) in the 278// autocomplete dropdown, and fills in 'fill_into_edit' into the textbox when 279// that line is selected. fill_into_edit may be the same as 'description' for 280// things like URLs, but may be different for searches or other providers. For 281// example, a search result may say "Search for asdf" as the description, but 282// "asdf" should appear in the box. 283struct AutocompleteMatch { 284 // Autocomplete matches contain strings that are classified according to a 285 // separate vector of styles. This vector associates flags with particular 286 // string segments, and must be in sorted order. All text must be associated 287 // with some kind of classification. Even if a match has no distinct 288 // segments, its vector should contain an entry at offset 0 with no flags. 289 // 290 // Example: The user typed "goog" 291 // http://www.google.com/ Google 292 // ^ ^ ^ ^ ^ 293 // 0, | 15, | 4, 294 // 11,match 0,match 295 // 296 // This structure holds the classification information for each span. 297 struct ACMatchClassification { 298 // The values in here are not mutually exclusive -- use them like a 299 // bitfield. This also means we use "int" instead of this enum type when 300 // passing the values around, so the compiler doesn't complain. 301 enum Style { 302 NONE = 0, 303 URL = 1 << 0, // A URL 304 MATCH = 1 << 1, // A match for the user's search term 305 DIM = 1 << 2, // "Helper text" 306 }; 307 308 ACMatchClassification(size_t offset, int style) 309 : offset(offset), 310 style(style) { 311 } 312 313 // Offset within the string that this classification starts 314 size_t offset; 315 316 int style; 317 }; 318 319 typedef std::vector<ACMatchClassification> ACMatchClassifications; 320 321 // The type of this match. 322 enum Type { 323 URL_WHAT_YOU_TYPED = 0, // The input as a URL. 324 HISTORY_URL, // A past page whose URL contains the input. 325 HISTORY_TITLE, // A past page whose title contains the input. 326 HISTORY_BODY, // A past page whose body contains the input. 327 HISTORY_KEYWORD, // A past page whose keyword contains the input. 328 NAVSUGGEST, // A suggested URL. 329 SEARCH_WHAT_YOU_TYPED, // The input as a search query (with the default 330 // engine). 331 SEARCH_HISTORY, // A past search (with the default engine) 332 // containing the input. 333 SEARCH_SUGGEST, // A suggested search (with the default engine). 334 SEARCH_OTHER_ENGINE, // A search with a non-default engine. 335 OPEN_HISTORY_PAGE, // A synthetic result that opens the history page 336 // to search for the input. 337 NUM_TYPES, 338 }; 339 340 AutocompleteMatch(); 341 AutocompleteMatch(AutocompleteProvider* provider, 342 int relevance, 343 bool deletable, 344 Type type); 345 ~AutocompleteMatch(); 346 347 // Converts |type| to a string representation. Used in logging. 348 static std::string TypeToString(Type type); 349 350 // Converts |type| to a resource identifier for the appropriate icon for this 351 // type. 352 static int TypeToIcon(Type type); 353 354 // Comparison function for determining when one match is better than another. 355 static bool MoreRelevant(const AutocompleteMatch& elem1, 356 const AutocompleteMatch& elem2); 357 358 // Comparison functions for removing matches with duplicate destinations. 359 static bool DestinationSortFunc(const AutocompleteMatch& elem1, 360 const AutocompleteMatch& elem2); 361 static bool DestinationsEqual(const AutocompleteMatch& elem1, 362 const AutocompleteMatch& elem2); 363 364 // Helper functions for classes creating matches: 365 // Fills in the classifications for |text|, using |style| as the base style 366 // and marking the first instance of |find_text| as a match. (This match 367 // will also not be dimmed, if |style| has DIM set.) 368 static void ClassifyMatchInString(const std::wstring& find_text, 369 const std::wstring& text, 370 int style, 371 ACMatchClassifications* classifications); 372 373 // Similar to ClassifyMatchInString(), but for cases where the range to mark 374 // as matching is already known (avoids calling find()). This can be helpful 375 // when find() would be misleading (e.g. you want to mark the second match in 376 // a string instead of the first). 377 static void ClassifyLocationInString(size_t match_location, 378 size_t match_length, 379 size_t overall_length, 380 int style, 381 ACMatchClassifications* classifications); 382 383 // The provider of this match, used to remember which provider the user had 384 // selected when the input changes. This may be NULL, in which case there is 385 // no provider (or memory of the user's selection). 386 AutocompleteProvider* provider; 387 388 // The relevance of this match. See table above for scores returned by 389 // various providers. This is used to rank matches among all responding 390 // providers, so different providers must be carefully tuned to supply 391 // matches with appropriate relevance. 392 // 393 // If the relevance is negative, it will only be displayed if there are not 394 // enough non-negative items in all the providers to max out the popup. In 395 // this case, the relevance of the additional items will be inverted so they 396 // can be mixed in with the rest of the relevances. This allows a provider 397 // to group its matches, having the added items appear intermixed with its 398 // other matches. 399 // 400 // TODO(pkasting): http://b/1111299 This should be calculated algorithmically, 401 // rather than being a fairly fixed value defined by the table above. 402 int relevance; 403 404 // True if the user should be able to delete this match. 405 bool deletable; 406 407 // This string is loaded into the location bar when the item is selected 408 // by pressing the arrow keys. This may be different than a URL, for example, 409 // for search suggestions, this would just be the search terms. 410 std::wstring fill_into_edit; 411 412 // The position within fill_into_edit from which we'll display the inline 413 // autocomplete string. This will be std::wstring::npos if this match should 414 // not be inline autocompleted. 415 size_t inline_autocomplete_offset; 416 417 // The URL to actually load when the autocomplete item is selected. This URL 418 // should be canonical so we can compare URLs with strcmp to avoid dupes. 419 // It may be empty if there is no possible navigation. 420 GURL destination_url; 421 422 // The main text displayed in the address bar dropdown. 423 std::wstring contents; 424 ACMatchClassifications contents_class; 425 426 // Additional helper text for each entry, such as a title or description. 427 std::wstring description; 428 ACMatchClassifications description_class; 429 430 // The transition type to use when the user opens this match. By default 431 // this is TYPED. Providers whose matches do not look like URLs should set 432 // it to GENERATED. 433 PageTransition::Type transition; 434 435 // True when this match is the "what you typed" match from the history 436 // system. 437 bool is_history_what_you_typed_match; 438 439 // Type of this match. 440 Type type; 441 442 // If this match corresponds to a keyword, this is the TemplateURL the 443 // keyword was obtained from. 444 const TemplateURL* template_url; 445 446 // True if the user has starred the destination URL. 447 bool starred; 448 449#ifndef NDEBUG 450 // Does a data integrity check on this match. 451 void Validate() const; 452 453 // Checks one text/classifications pair for valid values. 454 void ValidateClassifications( 455 const std::wstring& text, 456 const ACMatchClassifications& classifications) const; 457#endif 458}; 459 460typedef AutocompleteMatch::ACMatchClassification ACMatchClassification; 461typedef std::vector<ACMatchClassification> ACMatchClassifications; 462 463// AutocompleteProvider ------------------------------------------------------- 464 465// A single result provider for the autocomplete system. Given user input, the 466// provider decides what (if any) matches to return, their relevance, and their 467// classifications. 468class AutocompleteProvider 469 : public base::RefCountedThreadSafe<AutocompleteProvider> { 470 public: 471 class ACProviderListener { 472 public: 473 // Called by a provider as a notification that something has changed. 474 // |updated_matches| should be true iff the matches have changed in some 475 // way (they may not have changed if, for example, the provider did an 476 // asynchronous query to get more matches, came up with none, and is now 477 // giving up). 478 // 479 // NOTE: Providers MUST only call this method while processing asynchronous 480 // queries. Do not call this for a synchronous query. 481 // 482 // NOTE: There's no parameter to tell the listener _which_ provider is 483 // calling it. Because the AutocompleteController (the typical listener) 484 // doesn't cache the providers' individual matches locally, it has to get 485 // them all again when this is called anyway, so such a parameter wouldn't 486 // actually be useful. 487 virtual void OnProviderUpdate(bool updated_matches) = 0; 488 489 protected: 490 virtual ~ACProviderListener(); 491 }; 492 493 AutocompleteProvider(ACProviderListener* listener, 494 Profile* profile, 495 const char* name); 496 497 // Invoked when the profile changes. 498 // NOTE: Do not access any previous Profile* at this point as it may have 499 // already been deleted. 500 void SetProfile(Profile* profile); 501 502 // Called to start an autocomplete query. The provider is responsible for 503 // tracking its matches for this query and whether it is done processing the 504 // query. When new matches are available or the provider finishes, it 505 // calls the controller's OnProviderUpdate() method. The controller can then 506 // get the new matches using the provider's accessors. 507 // Exception: Matches available immediately after starting the query (that 508 // is, synchronously) do not cause any notifications to be sent. The 509 // controller is expected to check for these without prompting (since 510 // otherwise, starting each provider running would result in a flurry of 511 // notifications). 512 // 513 // Once Stop() has been called, no more notifications should be sent. 514 // 515 // |minimal_changes| is an optimization that lets the provider do less work 516 // when the |input|'s text hasn't changed. See the body of 517 // AutocompletePopupModel::StartAutocomplete(). 518 virtual void Start(const AutocompleteInput& input, 519 bool minimal_changes) = 0; 520 521 // Called when a provider must not make any more callbacks for the current 522 // query. This will be called regardless of whether the provider is already 523 // done. 524 virtual void Stop(); 525 526 // Returns the set of matches for the current query. 527 const ACMatches& matches() const { return matches_; } 528 529 // Returns whether the provider is done processing the query. 530 bool done() const { return done_; } 531 532 // Returns the name of this provider. 533 const char* name() const { return name_; } 534 535 // Called to delete a match and the backing data that produced it. This 536 // match should not appear again in this or future queries. This can only be 537 // called for matches the provider marks as deletable. This should only be 538 // called when no query is running. 539 // NOTE: Remember to call OnProviderUpdate() if matches_ is updated. 540 virtual void DeleteMatch(const AutocompleteMatch& match); 541 542 // A suggested upper bound for how many matches a provider should return. 543 // TODO(pkasting): http://b/1111299 , http://b/933133 This should go away once 544 // we have good relevance heuristics; the controller should handle all 545 // culling. 546 static const size_t kMaxMatches; 547 548 protected: 549 friend class base::RefCountedThreadSafe<AutocompleteProvider>; 550 551 virtual ~AutocompleteProvider(); 552 553 // Returns whether |input| begins "http:" or "view-source:http:". 554 static bool HasHTTPScheme(const std::wstring& input); 555 556 // Updates the starred state of each of the matches in matches_ from the 557 // profile's bookmark bar model. 558 void UpdateStarredStateOfMatches(); 559 560 // A convenience function to call net::FormatUrl() with the current set of 561 // "Accept Languages" when check_accept_lang is true. Otherwise, it's called 562 // with an empty list. 563 std::wstring StringForURLDisplay(const GURL& url, 564 bool check_accept_lang, 565 bool trim_http) const; 566 567 // The profile associated with the AutocompleteProvider. Reference is not 568 // owned by us. 569 Profile* profile_; 570 571 ACProviderListener* listener_; 572 ACMatches matches_; 573 bool done_; 574 575 // The name of this provider. Used for logging. 576 const char* name_; 577 578 private: 579 DISALLOW_COPY_AND_ASSIGN(AutocompleteProvider); 580}; 581 582typedef AutocompleteProvider::ACProviderListener ACProviderListener; 583 584// AutocompleteResult --------------------------------------------------------- 585 586// All matches from all providers for a particular query. This also tracks 587// what the default match should be if the user doesn't manually select another 588// match. 589class AutocompleteResult { 590 public: 591 typedef ACMatches::const_iterator const_iterator; 592 typedef ACMatches::iterator iterator; 593 594 // The "Selection" struct is the information we need to select the same match 595 // in one result set that was selected in another. 596 struct Selection { 597 Selection() 598 : provider_affinity(NULL), 599 is_history_what_you_typed_match(false) { 600 } 601 602 // Clear the selection entirely. 603 void Clear(); 604 605 // True when the selection is empty. 606 bool empty() const { 607 return destination_url.is_empty() && !provider_affinity && 608 !is_history_what_you_typed_match; 609 } 610 611 // The desired destination URL. 612 GURL destination_url; 613 614 // The desired provider. If we can't find a match with the specified 615 // |destination_url|, we'll use the best match from this provider. 616 const AutocompleteProvider* provider_affinity; 617 618 // True when this is the HistoryURLProvider's "what you typed" match. This 619 // can't be tracked using |destination_url| because its URL changes on every 620 // keystroke, so if this is set, we'll preserve the selection by simply 621 // choosing the new "what you typed" entry and ignoring |destination_url|. 622 bool is_history_what_you_typed_match; 623 }; 624 625 AutocompleteResult(); 626 627 // operator=() by another name. 628 void CopyFrom(const AutocompleteResult& rhs); 629 630 // Adds a single match. The match is inserted at the appropriate position 631 // based on relevancy and display order. This is ONLY for use after 632 // SortAndCull() has been invoked, and preserves default_match_. 633 void AddMatch(const AutocompleteMatch& match); 634 635 // Adds a new set of matches to the result set. Does not re-sort. 636 void AppendMatches(const ACMatches& matches); 637 638 // Removes duplicates, puts the list in sorted order and culls to leave only 639 // the best kMaxMatches matches. Sets the default match to the best match 640 // and updates the alternate nav URL. 641 void SortAndCull(const AutocompleteInput& input); 642 643 // Vector-style accessors/operators. 644 size_t size() const { return matches_.size(); } 645 bool empty() const { return matches_.empty(); } 646 const_iterator begin() const { return matches_.begin(); } 647 iterator begin() { return matches_.begin(); } 648 const_iterator end() const { return matches_.end(); } 649 iterator end() { return matches_.end(); } 650 651 // Returns the match at the given index. 652 const AutocompleteMatch& match_at(size_t index) const { 653 DCHECK(index < matches_.size()); 654 return matches_[index]; 655 } 656 657 // Get the default match for the query (not necessarily the first). Returns 658 // end() if there is no default match. 659 const_iterator default_match() const { return default_match_; } 660 661 GURL alternate_nav_url() const { return alternate_nav_url_; } 662 663 // Clears the matches for this result set. 664 void Reset() { 665 matches_.clear(); 666 default_match_ = end(); 667 } 668 669#ifndef NDEBUG 670 // Does a data integrity check on this result. 671 void Validate() const; 672#endif 673 674 // Max number of matches we'll show from the various providers. We may end 675 // up showing an additional shortcut for Destinations->History, see 676 // AddHistoryContentsShortcut. 677 static const size_t kMaxMatches; 678 679 private: 680 ACMatches matches_; 681 682 const_iterator default_match_; 683 684 // The "alternate navigation URL", if any, for this result set. This is a URL 685 // to try offering as a navigational option in case the user navigated to the 686 // URL of the default match but intended something else. For example, if the 687 // user's local intranet contains site "foo", and the user types "foo", we 688 // default to searching for "foo" when the user may have meant to navigate 689 // there. In cases like this, the default match will point to the "search for 690 // 'foo'" result, and this will contain "http://foo/". 691 GURL alternate_nav_url_; 692 693 DISALLOW_COPY_AND_ASSIGN(AutocompleteResult); 694}; 695 696// AutocompleteController ----------------------------------------------------- 697 698// The coordinator for autocomplete queries, responsible for combining the 699// matches from a series of providers into one AutocompleteResult. 700class AutocompleteController : public ACProviderListener { 701 public: 702 // Used to indicate an index that is not selected in a call to Update(). 703 static const int kNoItemSelected; 704 705 // Normally, you will call the first constructor. Unit tests can use the 706 // second to set the providers to some known testing providers. The default 707 // providers will be overridden and the controller will take ownership of the 708 // providers, Release()ing them on destruction. 709 explicit AutocompleteController(Profile* profile); 710#ifdef UNIT_TEST 711 explicit AutocompleteController(const ACProviders& providers) 712 : providers_(providers), 713 history_contents_provider_(NULL), 714 updated_latest_result_(false), 715 delay_interval_has_passed_(false), 716 have_committed_during_this_query_(false), 717 done_(true) { 718 } 719#endif 720 ~AutocompleteController(); 721 722 // Invoked when the profile changes. This forwards the call down to all 723 // the AutocompleteProviders. 724 void SetProfile(Profile* profile); 725 726 // Starts an autocomplete query, which continues until all providers are 727 // done or the query is Stop()ed. It is safe to Start() a new query without 728 // Stop()ing the previous one. 729 // 730 // See AutocompleteInput::desired_tld() for meaning of |desired_tld|. 731 // 732 // |prevent_inline_autocomplete| is true if the generated result set should 733 // not require inline autocomplete for the default match. This is difficult 734 // to explain in the abstract; the practical use case is that after the user 735 // deletes text in the edit, the HistoryURLProvider should make sure not to 736 // promote a match requiring inline autocomplete too highly. 737 // 738 // |prefer_keyword| should be true when the keyword UI is onscreen; this will 739 // bias the autocomplete result set toward the keyword provider when the input 740 // string is a bare keyword. 741 // 742 // If |synchronous_only| is true, the controller asks the providers to only 743 // return matches which are synchronously available, which should mean that 744 // all providers will be done immediately. 745 // 746 // The controller will fire 747 // AUTOCOMPLETE_CONTROLLER_SYNCHRONOUS_MATCHES_AVAILABLE from inside this 748 // call, and unless the query is stopped, will fire at least one (and perhaps 749 // more) AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED later as more matches come in 750 // (even if the query completes synchronously). Listeners should use the 751 // result set provided in the accompanying Details object to update 752 // themselves. 753 void Start(const std::wstring& text, 754 const std::wstring& desired_tld, 755 bool prevent_inline_autocomplete, 756 bool prefer_keyword, 757 bool synchronous_only); 758 759 // Cancels the current query, ensuring there will be no future notifications 760 // fired. If new matches have come in since the most recent notification was 761 // fired, they will be discarded. 762 // 763 // If |clear_result| is true, the controller will also erase the result set. 764 void Stop(bool clear_result); 765 766 // Asks the relevant provider to delete |match|, and ensures observers are 767 // notified of resulting changes immediately. This should only be called when 768 // no query is running. 769 void DeleteMatch(const AutocompleteMatch& match); 770 771 // Commits the results for the current query if they've never been committed. 772 // This is used by the popup to ensure it's not showing an out-of-date query. 773 void CommitIfQueryHasNeverBeenCommitted(); 774 775 // Getters 776 const AutocompleteInput& input() const { return input_; } 777 const AutocompleteResult& result() const { return result_; } 778 // This next is temporary and should go away when 779 // AutocompletePopup::InfoForCurrentSelection() moves to the controller. 780 const AutocompleteResult& latest_result() const { return latest_result_; } 781 bool done() const { return done_ && !update_delay_timer_.IsRunning(); } 782 783 // From AutocompleteProvider::Listener 784 virtual void OnProviderUpdate(bool updated_matches); 785 786 private: 787 // Updates |latest_result_| and |done_| to reflect the current provider state. 788 // Resets timers and fires notifications as necessary. |is_synchronous_pass| 789 // is true only when Start() is calling this to get the synchronous result. 790 void UpdateLatestResult(bool is_synchronous_pass); 791 792 // Callback for when |max_delay_timer_| fires; this notes that the delay 793 // interval has passed and commits the result, if it's changed. 794 void DelayTimerFired(); 795 796 // Copies |latest_result_| to |result_| and notifies observers of updates. 797 // |notify_default_match| should normally be true; if it's false, we don't 798 // send an AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED notification. This 799 // is a hack to avoid updating the edit with out-of-date data. 800 // TODO(pkasting): Don't hardcode assumptions about who listens to these 801 // notificiations. 802 void CommitResult(bool notify_default_match); 803 804 // Returns the matches from |provider| whose destination urls are not in 805 // |latest_result_|. 806 ACMatches GetMatchesNotInLatestResult( 807 const AutocompleteProvider* provider) const; 808 809 // If the HistoryContentsAutocomplete provider is done and there are more 810 // matches in the database than currently shown, an entry is added to 811 // |latest_result_| to show all history matches. 812 void AddHistoryContentsShortcut(); 813 814 // Updates |done_| to be accurate with respect to current providers' statuses. 815 void CheckIfDone(); 816 817 // A list of all providers. 818 ACProviders providers_; 819 820 HistoryContentsProvider* history_contents_provider_; 821 822 // Input passed to Start. 823 AutocompleteInput input_; 824 825 // Data from the autocomplete query. 826 AutocompleteResult result_; 827 828 // The latest result available from the autocomplete providers. This may be 829 // different than |result_| if we've gotten matches from our providers that we 830 // haven't yet shown the user. If there aren't yet as many matches as in 831 // |result|, we'll wait to display these in hopes of minimizing flicker in GUI 832 // observers. 833 AutocompleteResult latest_result_; 834 835 // True if |latest_result_| has been updated since it was last committed to 836 // |result_|. Used to determine whether we need to commit any changes. 837 bool updated_latest_result_; 838 839 // True when it's been at least one interval of the delay timer since we 840 // committed any updates. This is used to allow a new update to be committed 841 // immediately. 842 // 843 // NOTE: This can never be true when |have_committed_during_this_query_| is 844 // false (except transiently while processing the timer firing). 845 bool delay_interval_has_passed_; 846 847 // True when we've committed a result set at least once during this query. 848 // When this is false, we commit immediately when |done_| is set, since there 849 // are no more updates to come and thus no possible flicker due to committing 850 // immediately. 851 // 852 // NOTE: This can never be false when |delay_interval_has_passed_| is true 853 // (except transiently while processing the timer firing). 854 bool have_committed_during_this_query_; 855 856 // True if a query is not currently running. 857 bool done_; 858 859 // Timer that tracks how long it's been since the last time we sent our 860 // observers a new result set. This is used both to enforce a lower bound on 861 // the delay between most commits (to reduce flicker), and ensure that updates 862 // eventually get committed no matter what delays occur between them or how 863 // fast or continuously the user is typing. 864 base::RepeatingTimer<AutocompleteController> update_delay_timer_; 865 866 DISALLOW_COPY_AND_ASSIGN(AutocompleteController); 867}; 868 869// AutocompleteLog ------------------------------------------------------------ 870 871// The data to log (via the metrics service) when the user selects an item 872// from the omnibox popup. 873struct AutocompleteLog { 874 AutocompleteLog(std::wstring text, 875 AutocompleteInput::Type input_type, 876 size_t selected_index, 877 size_t inline_autocompleted_length, 878 const AutocompleteResult& result) 879 : text(text), 880 input_type(input_type), 881 selected_index(selected_index), 882 inline_autocompleted_length(inline_autocompleted_length), 883 result(result) { 884 } 885 // The user's input text in the omnibox. 886 std::wstring text; 887 // The detected type of the user's input. 888 AutocompleteInput::Type input_type; 889 // Selected index (if selected) or -1 (AutocompletePopupModel::kNoMatch). 890 size_t selected_index; 891 // Inline autocompleted length (if displayed). 892 size_t inline_autocompleted_length; 893 // Result set. 894 const AutocompleteResult& result; 895}; 896 897#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ 898