summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete/zero_suggest_provider.h
blob: 7980f53020dbfcc4245ac71055dd2e44676f1f59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file contains the zero-suggest autocomplete provider. This experimental
// provider is invoked when the user focuses in the omnibox prior to editing,
// and generates search query suggestions based on the current URL. To enable
// this provider, point --experimental-zero-suggest-url-prefix at an
// appropriate suggestion service.
//
// HUGE DISCLAIMER: This is just here for experimenting and will probably be
// deleted entirely as we revise how suggestions work with the omnibox.

#ifndef CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
#define CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_

#include <map>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/autocomplete/autocomplete_provider.h"
#include "chrome/browser/autocomplete/search_provider.h"
#include "net/url_request/url_fetcher_delegate.h"

class AutocompleteInput;
class GURL;
class TemplateURLService;

namespace base {
class ListValue;
class Value;
}

namespace net {
class URLFetcher;
}

// Autocomplete provider for searches based on the current URL.
//
// The controller will call StartZeroSuggest when the user focuses in the
// omnibox. After construction, the autocomplete controller repeatedly calls
// Start() with some user input, each time expecting to receive an updated
// set of matches.
//
// TODO(jered): Consider deleting this class and building this functionality
// into SearchProvider after dogfood and after we break the association between
// omnibox text and suggestions.
class ZeroSuggestProvider : public AutocompleteProvider,
                            public net::URLFetcherDelegate {
 public:
  // Creates and returns an instance of this provider.
  static ZeroSuggestProvider* Create(AutocompleteProviderListener* listener,
                                     Profile* profile);

  // AutocompleteProvider:
  virtual void Start(const AutocompleteInput& input,
                     bool /*minimal_changes*/) OVERRIDE;
  virtual void Stop(bool clear_cached_results) OVERRIDE;

  // Adds provider-specific information to omnibox event logs.
  virtual void AddProviderInfo(ProvidersInfo* provider_info) const OVERRIDE;

  // Sets |field_trial_triggered_| to false.
  virtual void ResetSession() OVERRIDE;

  // net::URLFetcherDelegate
  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;

  // Initiates a new fetch for the given |url| of classification
  // |page_classification|. |permanent_text| is the omnibox text
  // for the current page.
  void StartZeroSuggest(
      const GURL& url,
      AutocompleteInput::PageClassification page_classification,
      const string16& permanent_text);

  bool field_trial_triggered_in_session() const {
    return field_trial_triggered_in_session_;
  }

 private:
  ZeroSuggestProvider(AutocompleteProviderListener* listener,
                      Profile* profile);

  virtual ~ZeroSuggestProvider();

  bool ShouldRunZeroSuggest(
      const GURL& url,
      AutocompleteInput::PageClassification page_classification) const;

  // Whether the URL can get Zero Suggest.  For example, don't send the URL of
  // non-Google HTTPS requests because it may contain sensitive information.
  bool ShouldSendURL(
      const GURL& url,
      AutocompleteInput::PageClassification page_classification) const;

  // The 4 functions below (that take classes defined in SearchProvider as
  // arguments) were copied and trimmed from SearchProvider.
  // TODO(hfung): Refactor them into a new base class common to both
  // ZeroSuggestProvider and SearchProvider.

  // From the OpenSearch formatted response |root_val|, populate query
  // suggestions into |suggest_results|, navigation suggestions into
  // |navigation_results|, and the verbatim relevance score into
  // |verbatim_relevance|.
  void FillResults(const base::Value& root_val,
                   int* verbatim_relevance,
                   SearchProvider::SuggestResults* suggest_results,
                   SearchProvider::NavigationResults* navigation_results);

  // Creates AutocompleteMatches to search |template_url| for "<suggestion>" for
  // all suggestions in |results|, and adds them to |map|.
  void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results,
                              const TemplateURL* template_url,
                              SearchProvider::MatchMap* map);

  // Creates an AutocompleteMatch with the provided |relevance| and |type| to
  // search |template_url| for |query_string|.  |accepted_suggestion| will be
  // used to generate Assisted Query Stats.
  //
  // Adds this match to |map|; if such a match already exists, whichever one
  // has lower relevance is eliminated.
  void AddMatchToMap(int relevance,
                     AutocompleteMatch::Type type,
                     const TemplateURL* template_url,
                     const string16& query_string,
                     int accepted_suggestion,
                     SearchProvider::MatchMap* map);

  // Returns an AutocompleteMatch for a navigational suggestion |navigation|.
  AutocompleteMatch NavigationToMatch(
      const SearchProvider::NavigationResult& navigation);

  // Fetches zero-suggest suggestions for |current_query_|.
  void Run();

  // Parses results from the zero-suggest server and updates results.
  void ParseSuggestResults(const base::Value& root_val);

  // Converts the parsed results to a set of AutocompleteMatches and adds them
  // to |matches_|.  Also update the histograms for how many results were
  // received.
  void ConvertResultsToAutocompleteMatches();

  // Returns an AutocompleteMatch for the current URL. The match should be in
  // the top position so that pressing enter has the effect of reloading the
  // page.
  AutocompleteMatch MatchForCurrentURL();

  // When the user is in the Most Visited field trial, we ask the TopSites
  // service for the most visited URLs during Run().  It calls back to this
  // function to return those |urls|.
  void OnMostVisitedUrlsAvailable(const history::MostVisitedURLList& urls);

  // Used to build default search engine URLs for suggested queries.
  TemplateURLService* template_url_service_;

  // The URL for which a suggestion fetch is pending.
  std::string current_query_;

  // The type of page the user is viewing (a search results page doing search
  // term replacement, an arbitrary URL, etc.).
  AutocompleteInput::PageClassification current_page_classification_;

  // Copy of OmniboxEditModel::permanent_text_.
  string16 permanent_text_;

  // Fetcher used to retrieve results.
  scoped_ptr<net::URLFetcher> fetcher_;
  // Whether there's a pending request in flight.
  bool have_pending_request_;

  // Suggestion for the current URL.
  AutocompleteMatch current_url_match_;
  // Navigation suggestions for the most recent ZeroSuggest input URL.
  SearchProvider::NavigationResults navigation_results_;
  // Query suggestions for the most recent ZeroSuggest input URL.
  SearchProvider::MatchMap query_matches_map_;
  // The relevance score for the URL of the current page.
  int verbatim_relevance_;

  // Whether a field trial, if any, has triggered in the most recent
  // autocomplete query. This field is set to true if the last request
  // was a zero suggest request, the provider has completed and their
  // corresponding response contained '"google:fieldtrialtriggered":true'.
  bool field_trial_triggered_;
  // Whether a zero suggest request triggered a field trial in the omnibox
  // session.  The user could have clicked on a suggestion when zero suggest
  // triggered (same condition as field_trial_triggered_), or triggered zero
  // suggest but kept typing.
  bool field_trial_triggered_in_session_;

  history::MostVisitedURLList most_visited_urls_;

  // For callbacks that may be run after destruction.
  base::WeakPtrFactory<ZeroSuggestProvider> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider);
};

#endif  // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_