1 // Copyright (c) 2011 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 <map> 10 #include <string> 11 #include <vector> 12 13 #include "base/logging.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/string16.h" 16 #include "base/timer.h" 17 #include "googleurl/src/gurl.h" 18 #include "googleurl/src/url_parse.h" 19 20 // The AutocompleteController is the center of the autocomplete system. A 21 // class creates an instance of the controller, which in turn creates a set of 22 // AutocompleteProviders to serve it. The owning class can ask the controller 23 // to Start() a query; the controller in turn passes this call down to the 24 // providers, each of which keeps track of its own matches and whether it has 25 // finished processing the query. When a provider gets more matches or finishes 26 // processing, it notifies the controller, which merges the combined matches 27 // together and makes the result available to interested observers. 28 // 29 // The owner may also cancel the current query by calling Stop(), which the 30 // controller will in turn communicate to all the providers. No callbacks will 31 // happen after a request has been stopped. 32 // 33 // IMPORTANT: There is NO THREAD SAFETY built into this portion of the 34 // autocomplete system. All calls to and from the AutocompleteController should 35 // happen on the same thread. AutocompleteProviders are responsible for doing 36 // their own thread management when they need to return matches asynchronously. 37 // 38 // The AutocompleteProviders each return different kinds of matches, such as 39 // history or search matches. These matches are given "relevance" scores. 40 // Higher scores are better matches than lower scores. The relevance scores and 41 // classes providing the respective matches are as follows: 42 // 43 // UNKNOWN input type: 44 // --------------------------------------------------------------------|----- 45 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 46 // Extension App (exact match) | 1425 47 // HistoryURL (exact or inline autocomplete match) | 1400 48 // Search Primary Provider (past query in history within 2 days) | 1399** 49 // Search Primary Provider (what you typed) | 1300 50 // HistoryURL (what you typed) | 1200 51 // Extension App (inexact match) | 1175*~ 52 // Keyword (substituting, exact match) | 1100 53 // Search Primary Provider (past query in history older than 2 days) | 1050-- 54 // HistoryContents (any match in title of starred page) | 1000++ 55 // HistoryURL (inexact match) | 900++ 56 // Search Primary Provider (navigational suggestion) | 800++ 57 // HistoryContents (any match in title of nonstarred page) | 700++ 58 // Search Primary Provider (suggestion) | 600++ 59 // Built-in | 575++ 60 // HistoryContents (any match in body of starred page) | 550++ 61 // HistoryContents (any match in body of nonstarred page) | 500++ 62 // Keyword (inexact match) | 450 63 // Search Secondary Provider (what you typed) | 250 64 // Search Secondary Provider (past query in history) | 200-- 65 // Search Secondary Provider (navigational suggestion) | 150++ 66 // Search Secondary Provider (suggestion) | 100++ 67 // 68 // REQUESTED_URL input type: 69 // --------------------------------------------------------------------|----- 70 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 71 // Extension App (exact match) | 1425 72 // HistoryURL (exact or inline autocomplete match) | 1400 73 // Search Primary Provider (past query in history within 2 days) | 1399** 74 // HistoryURL (what you typed) | 1200 75 // Extension App (inexact match) | 1175*~ 76 // Search Primary Provider (what you typed) | 1150 77 // Keyword (substituting, exact match) | 1100 78 // Search Primary Provider (past query in history older than 2 days) | 1050-- 79 // HistoryContents (any match in title of starred page) | 1000++ 80 // HistoryURL (inexact match) | 900++ 81 // Search Primary Provider (navigational suggestion) | 800++ 82 // HistoryContents (any match in title of nonstarred page) | 700++ 83 // Search Primary Provider (suggestion) | 600++ 84 // Built-in | 575++ 85 // HistoryContents (any match in body of starred page) | 550++ 86 // HistoryContents (any match in body of nonstarred page) | 500++ 87 // Keyword (inexact match) | 450 88 // Search Secondary Provider (what you typed) | 250 89 // Search Secondary Provider (past query in history) | 200-- 90 // Search Secondary Provider (navigational suggestion) | 150++ 91 // Search Secondary Provider (suggestion) | 100++ 92 // 93 // URL input type: 94 // --------------------------------------------------------------------|----- 95 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 96 // Extension App (exact match) | 1425 97 // HistoryURL (exact or inline autocomplete match) | 1400 98 // HistoryURL (what you typed) | 1200 99 // Extension App (inexact match) | 1175*~ 100 // Keyword (substituting, exact match) | 1100 101 // HistoryURL (inexact match) | 900++ 102 // Search Primary Provider (what you typed) | 850 103 // Search Primary Provider (navigational suggestion) | 800++ 104 // Search Primary Provider (past query in history) | 750-- 105 // Keyword (inexact match) | 700 106 // Built-in | 575++ 107 // Search Primary Provider (suggestion) | 300++ 108 // Search Secondary Provider (what you typed) | 250 109 // Search Secondary Provider (past query in history) | 200-- 110 // Search Secondary Provider (navigational suggestion) | 150++ 111 // Search Secondary Provider (suggestion) | 100++ 112 // 113 // QUERY input type: 114 // --------------------------------------------------------------------|----- 115 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 116 // Keyword (substituting, exact match) | 1450 117 // Extension App (exact match) | 1425 118 // HistoryURL (exact or inline autocomplete match) | 1400 119 // Search Primary Provider (past query in history within 2 days) | 1399** 120 // Search Primary Provider (what you typed) | 1300 121 // Extension App (inexact match) | 1175*~ 122 // Search Primary Provider (past query in history older than 2 days) | 1050-- 123 // HistoryContents (any match in title of starred page) | 1000++ 124 // HistoryURL (inexact match) | 900++ 125 // Search Primary Provider (navigational suggestion) | 800++ 126 // HistoryContents (any match in title of nonstarred page) | 700++ 127 // Search Primary Provider (suggestion) | 600++ 128 // HistoryContents (any match in body of starred page) | 550++ 129 // HistoryContents (any match in body of nonstarred page) | 500++ 130 // Keyword (inexact match) | 450 131 // Search Secondary Provider (what you typed) | 250 132 // Search Secondary Provider (past query in history) | 200-- 133 // Search Secondary Provider (navigational suggestion) | 150++ 134 // Search Secondary Provider (suggestion) | 100++ 135 // 136 // FORCED_QUERY input type: 137 // --------------------------------------------------------------------|----- 138 // Extension App (exact match on title only, not url) | 1425 139 // Search Primary Provider (past query in history within 2 days) | 1399** 140 // Search Primary Provider (what you typed) | 1300 141 // Extension App (inexact match on title only, not url) | 1175*~ 142 // Search Primary Provider (past query in history older than 2 days) | 1050-- 143 // HistoryContents (any match in title of starred page) | 1000++ 144 // Search Primary Provider (navigational suggestion) | 800++ 145 // HistoryContents (any match in title of nonstarred page) | 700++ 146 // Search Primary Provider (suggestion) | 600++ 147 // HistoryContents (any match in body of starred page) | 550++ 148 // HistoryContents (any match in body of nonstarred page) | 500++ 149 // 150 // (A search keyword is a keyword with a replacement string; a bookmark keyword 151 // is a keyword with no replacement string, that is, a shortcut for a URL.) 152 // 153 // There are two possible providers for search suggestions. If the user has 154 // typed a keyword, then the primary provider is the keyword provider and the 155 // secondary provider is the default provider. If the user has not typed a 156 // keyword, then the primary provider corresponds to the default provider. 157 // 158 // The value column gives the ranking returned from the various providers. 159 // ++: a series of matches with relevance from n up to (n + max_matches). 160 // --: relevance score falls off over time (discounted 50 points @ 15 minutes, 161 // 450 points @ two weeks) 162 // **: relevance score falls off over two days (discounted 99 points after two 163 // days). 164 // *~: Partial matches get a score on a sliding scale from about 575-1125 based 165 // on how many times the URL for the Extension App has been typed and how 166 // many of the letters match. 167 168 class AutocompleteController; 169 class AutocompleteControllerDelegate; 170 class AutocompleteInput; 171 struct AutocompleteMatch; 172 class AutocompleteProvider; 173 class AutocompleteResult; 174 class HistoryContentsProvider; 175 class Profile; 176 class SearchProvider; 177 class TemplateURL; 178 179 typedef std::vector<AutocompleteMatch> ACMatches; 180 typedef std::vector<AutocompleteProvider*> ACProviders; 181 182 // AutocompleteInput ---------------------------------------------------------- 183 184 // The user input for an autocomplete query. Allows copying. 185 class AutocompleteInput { 186 public: 187 // Note that the type below may be misleading. For example, "http:/" alone 188 // cannot be opened as a URL, so it is marked as a QUERY; yet the user 189 // probably intends to type more and have it eventually become a URL, so we 190 // need to make sure we still run it through inline autocomplete. 191 enum Type { 192 INVALID, // Empty input 193 UNKNOWN, // Valid input whose type cannot be determined 194 REQUESTED_URL, // Input autodetected as UNKNOWN, which the user wants to 195 // treat as an URL by specifying a desired_tld 196 URL, // Input autodetected as a URL 197 QUERY, // Input autodetected as a query 198 FORCED_QUERY, // Input forced to be a query by an initial '?' 199 }; 200 201 // Enumeration of the possible match query types. Callers who only need some 202 // of the matches for a particular input can get answers more quickly by 203 // specifying that upfront. 204 enum MatchesRequested { 205 // Only the best match in the whole result set matters. Providers should at 206 // most return synchronously-available matches, and if possible do even less 207 // work, so that it's safe to ask for these repeatedly in the course of one 208 // higher-level "synchronous" query. 209 BEST_MATCH, 210 211 // Only synchronous matches should be returned. 212 SYNCHRONOUS_MATCHES, 213 214 // All matches should be fetched. 215 ALL_MATCHES, 216 }; 217 218 AutocompleteInput(); 219 AutocompleteInput(const string16& text, 220 const string16& desired_tld, 221 bool prevent_inline_autocomplete, 222 bool prefer_keyword, 223 bool allow_exact_keyword_match, 224 MatchesRequested matches_requested); 225 ~AutocompleteInput(); 226 227 // If type is |FORCED_QUERY| and |text| starts with '?', it is removed. 228 static void RemoveForcedQueryStringIfNecessary(Type type, string16* text); 229 230 // Converts |type| to a string representation. Used in logging. 231 static std::string TypeToString(Type type); 232 233 // Parses |text| and returns the type of input this will be interpreted as. 234 // The components of the input are stored in the output parameter |parts|, if 235 // it is non-NULL. The scheme is stored in |scheme| if it is non-NULL. The 236 // canonicalized URL is stored in |canonicalized_url|; however, this URL is 237 // not guaranteed to be valid, especially if the parsed type is, e.g., QUERY. 238 static Type Parse(const string16& text, 239 const string16& desired_tld, 240 url_parse::Parsed* parts, 241 string16* scheme, 242 GURL* canonicalized_url); 243 244 // Parses |text| and fill |scheme| and |host| by the positions of them. 245 // The results are almost as same as the result of Parse(), but if the scheme 246 // is view-source, this function returns the positions of scheme and host 247 // in the URL qualified by "view-source:" prefix. 248 static void ParseForEmphasizeComponents(const string16& text, 249 const string16& desired_tld, 250 url_parse::Component* scheme, 251 url_parse::Component* host); 252 253 // Code that wants to format URLs with a format flag including 254 // net::kFormatUrlOmitTrailingSlashOnBareHostname risk changing the meaning if 255 // the result is then parsed as AutocompleteInput. Such code can call this 256 // function with the URL and its formatted string, and it will return a 257 // formatted string with the same meaning as the original URL (i.e. it will 258 // re-append a slash if necessary). 259 static string16 FormattedStringWithEquivalentMeaning( 260 const GURL& url, 261 const string16& formatted_url); 262 263 // User-provided text to be completed. text()264 const string16& text() const { return text_; } 265 266 // Use of this setter is risky, since no other internal state is updated 267 // besides |text_|. Only callers who know that they're not changing the 268 // type/scheme/etc. should use this. set_text(const string16 & text)269 void set_text(const string16& text) { text_ = text; } 270 271 // The text supplied to the constructor. This differs from |text| if the text 272 // supplied to the constructor had leading or trailing white space. original_text()273 const string16& original_text() const { return original_text_; } 274 275 // User's desired TLD, if one is not already present in the text to 276 // autocomplete. When this is non-empty, it also implies that "www." should 277 // be prepended to the domain where possible. This should not have a leading 278 // '.' (use "com" instead of ".com"). desired_tld()279 const string16& desired_tld() const { return desired_tld_; } 280 281 // The type of input supplied. type()282 Type type() const { return type_; } 283 284 // Returns parsed URL components. parts()285 const url_parse::Parsed& parts() const { return parts_; } 286 287 // The scheme parsed from the provided text; only meaningful when type_ is 288 // URL. scheme()289 const string16& scheme() const { return scheme_; } 290 291 // The input as an URL to navigate to, if possible. canonicalized_url()292 const GURL& canonicalized_url() const { return canonicalized_url_; } 293 294 // Returns whether inline autocompletion should be prevented. prevent_inline_autocomplete()295 bool prevent_inline_autocomplete() const { 296 return prevent_inline_autocomplete_; 297 } 298 299 // Returns the value of |prevent_inline_autocomplete| supplied to the 300 // constructor. This differs from the value returned by 301 // |prevent_inline_autocomplete()| if the input contained trailing whitespace. initial_prevent_inline_autocomplete()302 bool initial_prevent_inline_autocomplete() const { 303 return initial_prevent_inline_autocomplete_; 304 } 305 306 // Returns whether, given an input string consisting solely of a substituting 307 // keyword, we should score it like a non-substituting keyword. prefer_keyword()308 bool prefer_keyword() const { return prefer_keyword_; } 309 310 // Returns whether this input is allowed to be treated as an exact 311 // keyword match. If not, the default result is guaranteed not to be a 312 // keyword search, even if the input is "<keyword> <search string>". allow_exact_keyword_match()313 bool allow_exact_keyword_match() const { return allow_exact_keyword_match_; } 314 315 // See description of enum for details. matches_requested()316 MatchesRequested matches_requested() const { return matches_requested_; } 317 318 // operator==() by another name. 319 bool Equals(const AutocompleteInput& other) const; 320 321 // Resets all internal variables to the null-constructed state. 322 void Clear(); 323 324 private: 325 string16 text_; 326 string16 original_text_; 327 string16 desired_tld_; 328 Type type_; 329 url_parse::Parsed parts_; 330 string16 scheme_; 331 GURL canonicalized_url_; 332 bool initial_prevent_inline_autocomplete_; 333 bool prevent_inline_autocomplete_; 334 bool prefer_keyword_; 335 bool allow_exact_keyword_match_; 336 MatchesRequested matches_requested_; 337 }; 338 339 // AutocompleteProvider ------------------------------------------------------- 340 341 // A single result provider for the autocomplete system. Given user input, the 342 // provider decides what (if any) matches to return, their relevance, and their 343 // classifications. 344 class AutocompleteProvider 345 : public base::RefCountedThreadSafe<AutocompleteProvider> { 346 public: 347 class ACProviderListener { 348 public: 349 // Called by a provider as a notification that something has changed. 350 // |updated_matches| should be true iff the matches have changed in some 351 // way (they may not have changed if, for example, the provider did an 352 // asynchronous query to get more matches, came up with none, and is now 353 // giving up). 354 // 355 // NOTE: Providers MUST only call this method while processing asynchronous 356 // queries. Do not call this for a synchronous query. 357 // 358 // NOTE: There's no parameter to tell the listener _which_ provider is 359 // calling it. Because the AutocompleteController (the typical listener) 360 // doesn't cache the providers' individual matches locally, it has to get 361 // them all again when this is called anyway, so such a parameter wouldn't 362 // actually be useful. 363 virtual void OnProviderUpdate(bool updated_matches) = 0; 364 365 protected: 366 virtual ~ACProviderListener(); 367 }; 368 369 AutocompleteProvider(ACProviderListener* listener, 370 Profile* profile, 371 const char* name); 372 373 // Invoked when the profile changes. 374 // NOTE: Do not access any previous Profile* at this point as it may have 375 // already been deleted. 376 void SetProfile(Profile* profile); 377 378 // Called to start an autocomplete query. The provider is responsible for 379 // tracking its matches for this query and whether it is done processing the 380 // query. When new matches are available or the provider finishes, it 381 // calls the controller's OnProviderUpdate() method. The controller can then 382 // get the new matches using the provider's accessors. 383 // Exception: Matches available immediately after starting the query (that 384 // is, synchronously) do not cause any notifications to be sent. The 385 // controller is expected to check for these without prompting (since 386 // otherwise, starting each provider running would result in a flurry of 387 // notifications). 388 // 389 // Once Stop() has been called, no more notifications should be sent. 390 // 391 // |minimal_changes| is an optimization that lets the provider do less work 392 // when the |input|'s text hasn't changed. See the body of 393 // AutocompletePopupModel::StartAutocomplete(). 394 virtual void Start(const AutocompleteInput& input, 395 bool minimal_changes) = 0; 396 397 // Called when a provider must not make any more callbacks for the current 398 // query. This will be called regardless of whether the provider is already 399 // done. 400 virtual void Stop(); 401 402 // Returns the set of matches for the current query. matches()403 const ACMatches& matches() const { return matches_; } 404 405 // Returns whether the provider is done processing the query. done()406 bool done() const { return done_; } 407 408 // Returns the name of this provider. name()409 const char* name() const { return name_; } 410 411 // Called to delete a match and the backing data that produced it. This 412 // match should not appear again in this or future queries. This can only be 413 // called for matches the provider marks as deletable. This should only be 414 // called when no query is running. 415 // NOTE: Remember to call OnProviderUpdate() if matches_ is updated. 416 virtual void DeleteMatch(const AutocompleteMatch& match); 417 418 // A suggested upper bound for how many matches a provider should return. 419 // TODO(pkasting): http://b/1111299 , http://b/933133 This should go away once 420 // we have good relevance heuristics; the controller should handle all 421 // culling. 422 static const size_t kMaxMatches; 423 424 protected: 425 friend class base::RefCountedThreadSafe<AutocompleteProvider>; 426 427 virtual ~AutocompleteProvider(); 428 429 // Returns whether |input| begins "http:" or "view-source:http:". 430 static bool HasHTTPScheme(const string16& input); 431 432 // Updates the starred state of each of the matches in matches_ from the 433 // profile's bookmark bar model. 434 void UpdateStarredStateOfMatches(); 435 436 // A convenience function to call net::FormatUrl() with the current set of 437 // "Accept Languages" when check_accept_lang is true. Otherwise, it's called 438 // with an empty list. 439 string16 StringForURLDisplay(const GURL& url, 440 bool check_accept_lang, 441 bool trim_http) const; 442 443 // The profile associated with the AutocompleteProvider. Reference is not 444 // owned by us. 445 Profile* profile_; 446 447 ACProviderListener* listener_; 448 ACMatches matches_; 449 bool done_; 450 451 // The name of this provider. Used for logging. 452 const char* name_; 453 454 private: 455 DISALLOW_COPY_AND_ASSIGN(AutocompleteProvider); 456 }; 457 458 typedef AutocompleteProvider::ACProviderListener ACProviderListener; 459 460 // AutocompleteResult --------------------------------------------------------- 461 462 // All matches from all providers for a particular query. This also tracks 463 // what the default match should be if the user doesn't manually select another 464 // match. 465 class AutocompleteResult { 466 public: 467 typedef ACMatches::const_iterator const_iterator; 468 typedef ACMatches::iterator iterator; 469 470 // The "Selection" struct is the information we need to select the same match 471 // in one result set that was selected in another. 472 struct Selection { SelectionSelection473 Selection() 474 : provider_affinity(NULL), 475 is_history_what_you_typed_match(false) { 476 } 477 478 // Clear the selection entirely. 479 void Clear(); 480 481 // True when the selection is empty. emptySelection482 bool empty() const { 483 return destination_url.is_empty() && !provider_affinity && 484 !is_history_what_you_typed_match; 485 } 486 487 // The desired destination URL. 488 GURL destination_url; 489 490 // The desired provider. If we can't find a match with the specified 491 // |destination_url|, we'll use the best match from this provider. 492 const AutocompleteProvider* provider_affinity; 493 494 // True when this is the HistoryURLProvider's "what you typed" match. This 495 // can't be tracked using |destination_url| because its URL changes on every 496 // keystroke, so if this is set, we'll preserve the selection by simply 497 // choosing the new "what you typed" entry and ignoring |destination_url|. 498 bool is_history_what_you_typed_match; 499 }; 500 501 AutocompleteResult(); 502 ~AutocompleteResult(); 503 504 // operator=() by another name. 505 void CopyFrom(const AutocompleteResult& rhs); 506 507 // Copies matches from |old_matches| to provide a consistant result set. See 508 // comments in code for specifics. 509 void CopyOldMatches(const AutocompleteInput& input, 510 const AutocompleteResult& old_matches); 511 512 // Adds a single match. The match is inserted at the appropriate position 513 // based on relevancy and display order. This is ONLY for use after 514 // SortAndCull() has been invoked, and preserves default_match_. 515 void AddMatch(const AutocompleteMatch& match); 516 517 // Adds a new set of matches to the result set. Does not re-sort. 518 void AppendMatches(const ACMatches& matches); 519 520 // Removes duplicates, puts the list in sorted order and culls to leave only 521 // the best kMaxMatches matches. Sets the default match to the best match 522 // and updates the alternate nav URL. 523 void SortAndCull(const AutocompleteInput& input); 524 525 // Returns true if at least one match was copied from the last result. 526 bool HasCopiedMatches() const; 527 528 // Vector-style accessors/operators. 529 size_t size() const; 530 bool empty() const; 531 const_iterator begin() const; 532 iterator begin(); 533 const_iterator end() const; 534 iterator end(); 535 536 // Returns the match at the given index. 537 const AutocompleteMatch& match_at(size_t index) const; 538 539 // Get the default match for the query (not necessarily the first). Returns 540 // end() if there is no default match. default_match()541 const_iterator default_match() const { return default_match_; } 542 alternate_nav_url()543 GURL alternate_nav_url() const { return alternate_nav_url_; } 544 545 // Clears the matches for this result set. 546 void Reset(); 547 548 void Swap(AutocompleteResult* other); 549 550 #ifndef NDEBUG 551 // Does a data integrity check on this result. 552 void Validate() const; 553 #endif 554 555 // Max number of matches we'll show from the various providers. 556 static const size_t kMaxMatches; 557 558 private: 559 typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches; 560 561 // Populates |provider_to_matches| from |matches_|. 562 void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const; 563 564 // Returns true if |matches| contains a match with the same destination as 565 // |match|. 566 static bool HasMatchByDestination(const AutocompleteMatch& match, 567 const ACMatches& matches); 568 569 // Copies matches into this result. |old_matches| gives the matches from the 570 // last result, and |new_matches| the results from this result. 571 void MergeMatchesByProvider(const ACMatches& old_matches, 572 const ACMatches& new_matches); 573 574 ACMatches matches_; 575 576 const_iterator default_match_; 577 578 // The "alternate navigation URL", if any, for this result set. This is a URL 579 // to try offering as a navigational option in case the user navigated to the 580 // URL of the default match but intended something else. For example, if the 581 // user's local intranet contains site "foo", and the user types "foo", we 582 // default to searching for "foo" when the user may have meant to navigate 583 // there. In cases like this, the default match will point to the "search for 584 // 'foo'" result, and this will contain "http://foo/". 585 GURL alternate_nav_url_; 586 587 DISALLOW_COPY_AND_ASSIGN(AutocompleteResult); 588 }; 589 590 // AutocompleteController ----------------------------------------------------- 591 592 // The coordinator for autocomplete queries, responsible for combining the 593 // matches from a series of providers into one AutocompleteResult. 594 class AutocompleteController : public ACProviderListener { 595 public: 596 // Used to indicate an index that is not selected in a call to Update(). 597 static const int kNoItemSelected; 598 599 // Normally, you will call the first constructor. Unit tests can use the 600 // second to set the providers to some known testing providers. The default 601 // providers will be overridden and the controller will take ownership of the 602 // providers, Release()ing them on destruction. 603 AutocompleteController(Profile* profile, 604 AutocompleteControllerDelegate* delegate); 605 #ifdef UNIT_TEST AutocompleteController(const ACProviders & providers)606 explicit AutocompleteController(const ACProviders& providers) 607 : delegate_(NULL), 608 providers_(providers), 609 search_provider_(NULL), 610 done_(true), 611 in_start_(false) { 612 } 613 #endif 614 ~AutocompleteController(); 615 616 // Invoked when the profile changes. This forwards the call down to all 617 // the AutocompleteProviders. 618 void SetProfile(Profile* profile); 619 620 // Starts an autocomplete query, which continues until all providers are 621 // done or the query is Stop()ed. It is safe to Start() a new query without 622 // Stop()ing the previous one. 623 // 624 // See AutocompleteInput::desired_tld() for meaning of |desired_tld|. 625 // 626 // |prevent_inline_autocomplete| is true if the generated result set should 627 // not require inline autocomplete for the default match. This is difficult 628 // to explain in the abstract; the practical use case is that after the user 629 // deletes text in the edit, the HistoryURLProvider should make sure not to 630 // promote a match requiring inline autocomplete too highly. 631 // 632 // |prefer_keyword| should be true when the keyword UI is onscreen; this will 633 // bias the autocomplete result set toward the keyword provider when the input 634 // string is a bare keyword. 635 // 636 // |allow_exact_keyword_match| should be false when triggering keyword mode on 637 // the input string would be surprising or wrong, e.g. when highlighting text 638 // in a page and telling the browser to search for it or navigate to it. This 639 // parameter only applies to substituting keywords. 640 641 // If |matches_requested| is BEST_MATCH or SYNCHRONOUS_MATCHES the controller 642 // asks the providers to only return matches which are synchronously 643 // available, which should mean that all providers will be done immediately. 644 // 645 // The controller calls AutocompleteControllerDelegate::OnResultChanged() from 646 // inside this call at least once. If matches are available later on that 647 // result in changing the result set the delegate is notified again. When the 648 // controller is done the notification AUTOCOMPLETE_CONTROLLER_RESULT_READY is 649 // sent. 650 void Start(const string16& text, 651 const string16& desired_tld, 652 bool prevent_inline_autocomplete, 653 bool prefer_keyword, 654 bool allow_exact_keyword_match, 655 AutocompleteInput::MatchesRequested matches_requested); 656 657 // Cancels the current query, ensuring there will be no future notifications 658 // fired. If new matches have come in since the most recent notification was 659 // fired, they will be discarded. 660 // 661 // If |clear_result| is true, the controller will also erase the result set. 662 void Stop(bool clear_result); 663 664 // Asks the relevant provider to delete |match|, and ensures observers are 665 // notified of resulting changes immediately. This should only be called when 666 // no query is running. 667 void DeleteMatch(const AutocompleteMatch& match); 668 669 // Removes any entries that were copied from the last result. This is used by 670 // the popup to ensure it's not showing an out-of-date query. 671 void ExpireCopiedEntries(); 672 search_provider()673 SearchProvider* search_provider() const { return search_provider_; } 674 675 // Getters input()676 const AutocompleteInput& input() const { return input_; } result()677 const AutocompleteResult& result() const { return result_; } done()678 bool done() const { return done_; } 679 680 // From AutocompleteProvider::Listener 681 virtual void OnProviderUpdate(bool updated_matches); 682 683 private: 684 // Updates |result_| to reflect the current provider state. Resets timers and 685 // fires notifications as necessary. |is_synchronous_pass| is true only when 686 // Start() is calling this to get the synchronous result. 687 void UpdateResult(bool is_synchronous_pass); 688 689 // Calls AutocompleteControllerDelegate::OnResultChanged() and if done sends 690 // AUTOCOMPLETE_CONTROLLER_RESULT_READY. 691 void NotifyChanged(bool notify_default_match); 692 693 // Updates |done_| to be accurate with respect to current providers' statuses. 694 void CheckIfDone(); 695 696 // Starts the expire timer. 697 void StartExpireTimer(); 698 699 AutocompleteControllerDelegate* delegate_; 700 701 // A list of all providers. 702 ACProviders providers_; 703 704 SearchProvider* search_provider_; 705 706 // Input passed to Start. 707 AutocompleteInput input_; 708 709 // Data from the autocomplete query. 710 AutocompleteResult result_; 711 712 // Timer used to remove any matches copied from the last result. When run 713 // invokes |ExpireCopiedEntries|. 714 base::OneShotTimer<AutocompleteController> expire_timer_; 715 716 // True if a query is not currently running. 717 bool done_; 718 719 // Are we in Start()? This is used to avoid updating |result_| and sending 720 // notifications until Start() has been invoked on all providers. 721 bool in_start_; 722 723 DISALLOW_COPY_AND_ASSIGN(AutocompleteController); 724 }; 725 726 // AutocompleteLog ------------------------------------------------------------ 727 728 // The data to log (via the metrics service) when the user selects an item 729 // from the omnibox popup. 730 struct AutocompleteLog { AutocompleteLogAutocompleteLog731 AutocompleteLog(const string16& text, 732 AutocompleteInput::Type input_type, 733 size_t selected_index, 734 size_t inline_autocompleted_length, 735 const AutocompleteResult& result) 736 : text(text), 737 input_type(input_type), 738 selected_index(selected_index), 739 inline_autocompleted_length(inline_autocompleted_length), 740 result(result) { 741 } 742 // The user's input text in the omnibox. 743 string16 text; 744 // The detected type of the user's input. 745 AutocompleteInput::Type input_type; 746 // Selected index (if selected) or -1 (AutocompletePopupModel::kNoMatch). 747 size_t selected_index; 748 // Inline autocompleted length (if displayed). 749 size_t inline_autocompleted_length; 750 // Result set. 751 const AutocompleteResult& result; 752 }; 753 754 #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ 755