Home | History | Annotate | Download | only in autocomplete
      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
      3 // found in the LICENSE file.
      4 //
      5 // This file contains the zero-suggest autocomplete provider. This experimental
      6 // provider is invoked when the user focuses in the omnibox prior to editing,
      7 // and generates search query suggestions based on the current URL. To enable
      8 // this provider, point --experimental-zero-suggest-url-prefix at an
      9 // appropriate suggestion service.
     10 //
     11 // HUGE DISCLAIMER: This is just here for experimenting and will probably be
     12 // deleted entirely as we revise how suggestions work with the omnibox.
     13 
     14 #ifndef CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
     15 #define CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
     16 
     17 #include <map>
     18 #include <string>
     19 #include <vector>
     20 
     21 #include "base/basictypes.h"
     22 #include "base/compiler_specific.h"
     23 #include "base/memory/scoped_ptr.h"
     24 #include "base/strings/string16.h"
     25 #include "chrome/browser/autocomplete/autocomplete_provider.h"
     26 #include "chrome/browser/autocomplete/search_provider.h"
     27 #include "net/url_request/url_fetcher_delegate.h"
     28 
     29 class AutocompleteInput;
     30 class GURL;
     31 class TemplateURLService;
     32 
     33 namespace base {
     34 class ListValue;
     35 class Value;
     36 }
     37 
     38 namespace net {
     39 class URLFetcher;
     40 }
     41 
     42 // Autocomplete provider for searches based on the current URL.
     43 //
     44 // The controller will call StartZeroSuggest when the user focuses in the
     45 // omnibox. After construction, the autocomplete controller repeatedly calls
     46 // Start() with some user input, each time expecting to receive an updated
     47 // set of matches.
     48 //
     49 // TODO(jered): Consider deleting this class and building this functionality
     50 // into SearchProvider after dogfood and after we break the association between
     51 // omnibox text and suggestions.
     52 class ZeroSuggestProvider : public AutocompleteProvider,
     53                             public net::URLFetcherDelegate {
     54  public:
     55   // Creates and returns an instance of this provider.
     56   static ZeroSuggestProvider* Create(AutocompleteProviderListener* listener,
     57                                      Profile* profile);
     58 
     59   // AutocompleteProvider:
     60   virtual void Start(const AutocompleteInput& input,
     61                      bool /*minimal_changes*/) OVERRIDE;
     62   virtual void Stop(bool clear_cached_results) OVERRIDE;
     63 
     64   // Adds provider-specific information to omnibox event logs.
     65   virtual void AddProviderInfo(ProvidersInfo* provider_info) const OVERRIDE;
     66 
     67   // Sets |field_trial_triggered_| to false.
     68   virtual void ResetSession() OVERRIDE;
     69 
     70   // net::URLFetcherDelegate
     71   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
     72 
     73   // Initiates a new fetch for the given |url| of classification
     74   // |page_classification|. |permanent_text| is the omnibox text
     75   // for the current page.
     76   void StartZeroSuggest(
     77       const GURL& url,
     78       AutocompleteInput::PageClassification page_classification,
     79       const string16& permanent_text);
     80 
     81   bool field_trial_triggered_in_session() const {
     82     return field_trial_triggered_in_session_;
     83   }
     84 
     85  private:
     86   ZeroSuggestProvider(AutocompleteProviderListener* listener,
     87                       Profile* profile);
     88 
     89   virtual ~ZeroSuggestProvider();
     90 
     91   bool ShouldRunZeroSuggest(const GURL& url) const;
     92 
     93   // Whether the URL can get Zero Suggest.  For example, don't send the URL of
     94   // non-Google HTTPS requests because it may contain sensitive information.
     95   bool ShouldSendURL(const GURL& url) const;
     96 
     97   // The 4 functions below (that take classes defined in SearchProvider as
     98   // arguments) were copied and trimmed from SearchProvider.
     99   // TODO(hfung): Refactor them into a new base class common to both
    100   // ZeroSuggestProvider and SearchProvider.
    101 
    102   // From the OpenSearch formatted response |root_val|, populate query
    103   // suggestions into |suggest_results|, navigation suggestions into
    104   // |navigation_results|, and the verbatim relevance score into
    105   // |verbatim_relevance|.
    106   void FillResults(const base::Value& root_val,
    107                    int* verbatim_relevance,
    108                    SearchProvider::SuggestResults* suggest_results,
    109                    SearchProvider::NavigationResults* navigation_results);
    110 
    111   // Creates AutocompleteMatches to search |template_url| for "<suggestion>" for
    112   // all suggestions in |results|, and adds them to |map|.
    113   void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results,
    114                               const TemplateURL* template_url,
    115                               SearchProvider::MatchMap* map);
    116 
    117   // Creates an AutocompleteMatch with the provided |relevance| and |type| to
    118   // search |template_url| for |query_string|.  |accepted_suggestion| will be
    119   // used to generate Assisted Query Stats.
    120   //
    121   // Adds this match to |map|; if such a match already exists, whichever one
    122   // has lower relevance is eliminated.
    123   void AddMatchToMap(int relevance,
    124                      AutocompleteMatch::Type type,
    125                      const TemplateURL* template_url,
    126                      const string16& query_string,
    127                      int accepted_suggestion,
    128                      SearchProvider::MatchMap* map);
    129 
    130   // Returns an AutocompleteMatch for a navigational suggestion |navigation|.
    131   AutocompleteMatch NavigationToMatch(
    132       const SearchProvider::NavigationResult& navigation);
    133 
    134   // Fetches zero-suggest suggestions for |current_query_|.
    135   void Run();
    136 
    137   // Parses results from the zero-suggest server and updates results.
    138   void ParseSuggestResults(const base::Value& root_val);
    139 
    140   // Converts the parsed results to a set of AutocompleteMatches and adds them
    141   // to |matches_|.  Also update the histograms for how many results were
    142   // received.
    143   void ConvertResultsToAutocompleteMatches();
    144 
    145   // Returns an AutocompleteMatch for the current URL. The match should be in
    146   // the top position so that pressing enter has the effect of reloading the
    147   // page.
    148   AutocompleteMatch MatchForCurrentURL();
    149 
    150   // Used to build default search engine URLs for suggested queries.
    151   TemplateURLService* template_url_service_;
    152 
    153   // The URL for which a suggestion fetch is pending.
    154   std::string current_query_;
    155 
    156   // The type of page the user is viewing (a search results page doing search
    157   // term replacement, an arbitrary URL, etc.).
    158   AutocompleteInput::PageClassification current_page_classification_;
    159 
    160   // Copy of OmniboxEditModel::permanent_text_.
    161   string16 permanent_text_;
    162 
    163   // Fetcher used to retrieve results.
    164   scoped_ptr<net::URLFetcher> fetcher_;
    165   // Whether there's a pending request in flight.
    166   bool have_pending_request_;
    167 
    168   // Suggestion for the current URL.
    169   AutocompleteMatch current_url_match_;
    170   // Navigation suggestions for the most recent ZeroSuggest input URL.
    171   SearchProvider::NavigationResults navigation_results_;
    172   // Query suggestions for the most recent ZeroSuggest input URL.
    173   SearchProvider::MatchMap query_matches_map_;
    174   // The relevance score for the URL of the current page.
    175   int verbatim_relevance_;
    176 
    177   // Whether a field trial, if any, has triggered in the most recent
    178   // autocomplete query. This field is set to true if the last request
    179   // was a zero suggest request, the provider has completed and their
    180   // corresponding response contained '"google:fieldtrialtriggered":true'.
    181   bool field_trial_triggered_;
    182   // Whether a zero suggest request triggered a field trial in the omnibox
    183   // session.  The user could have clicked on a suggestion when zero suggest
    184   // triggered (same condition as field_trial_triggered_), or triggered zero
    185   // suggest but kept typing.
    186   bool field_trial_triggered_in_session_;
    187 
    188   DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider);
    189 };
    190 
    191 #endif  // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
    192