Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: athena/main/url_search_provider.cc

Issue 438023002: Add search suggestions fetched from the server (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "athena/main/url_search_provider.h" 5 #include "athena/main/url_search_provider.h"
6 6
7 #include "athena/activity/public/activity_factory.h" 7 #include "athena/activity/public/activity_factory.h"
8 #include "athena/activity/public/activity_manager.h" 8 #include "athena/activity/public/activity_manager.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h"
10 #include "components/autocomplete/autocomplete_input.h" 11 #include "components/autocomplete/autocomplete_input.h"
11 #include "components/autocomplete/autocomplete_scheme_classifier.h" 12 #include "components/autocomplete/autocomplete_scheme_classifier.h"
13 #include "components/autocomplete/search_suggestion_parser.h"
12 #include "components/metrics/proto/omnibox_event.pb.h" 14 #include "components/metrics/proto/omnibox_event.pb.h"
13 #include "components/metrics/proto/omnibox_input_type.pb.h" 15 #include "components/metrics/proto/omnibox_input_type.pb.h"
14 #include "components/search_engines/search_terms_data.h" 16 #include "components/search_engines/search_terms_data.h"
15 #include "components/search_engines/template_url.h" 17 #include "components/search_engines/template_url.h"
16 #include "components/search_engines/template_url_service.h" 18 #include "components/search_engines/template_url_service.h"
17 #include "components/search_engines/template_url_service_client.h" 19 #include "components/search_engines/template_url_service_client.h"
20 #include "content/public/browser/browser_context.h"
21 #include "net/base/load_flags.h"
22 #include "net/url_request/url_fetcher.h"
18 #include "net/url_request/url_request.h" 23 #include "net/url_request/url_request.h"
19 #include "ui/app_list/search_result.h" 24 #include "ui/app_list/search_result.h"
20 #include "url/gurl.h" 25 #include "url/gurl.h"
21 26
22 namespace athena { 27 namespace athena {
23 28
24 namespace { 29 namespace {
25 30
31 // The SearchTermsData implementation for Athena.
32 class AthenaSearchTermsData : public SearchTermsData {
33 public:
34 // SearchTermsData:
35 virtual std::string GetSuggestClient() const OVERRIDE {
36 return "chrome";
37 }
38 };
39
26 // The AutocompleteSchemeClassifier implementation for Athena. 40 // The AutocompleteSchemeClassifier implementation for Athena.
27 // TODO(mukai): Introduce supports of normal schemes like about: or blob: 41 // TODO(mukai): Introduce supports of normal schemes like about: or blob:
28 class AthenaSchemeClassifier : public AutocompleteSchemeClassifier { 42 class AthenaSchemeClassifier : public AutocompleteSchemeClassifier {
29 public: 43 public:
30 AthenaSchemeClassifier() {} 44 AthenaSchemeClassifier() {}
31 45
32 // AutocompleteSchemeClassifier: 46 // AutocompleteSchemeClassifier:
33 virtual metrics::OmniboxInputType::Type GetInputTypeForScheme( 47 virtual metrics::OmniboxInputType::Type GetInputTypeForScheme(
34 const std::string& scheme) const OVERRIDE { 48 const std::string& scheme) const OVERRIDE {
35 if (net::URLRequest::IsHandledProtocol(scheme)) 49 if (net::URLRequest::IsHandledProtocol(scheme))
(...skipping 21 matching lines...) Expand all
57 virtual void AddKeywordGeneratedVisit(const GURL& url) OVERRIDE {} 71 virtual void AddKeywordGeneratedVisit(const GURL& url) OVERRIDE {}
58 virtual void RestoreExtensionInfoIfNecessary( 72 virtual void RestoreExtensionInfoIfNecessary(
59 TemplateURL* template_url) OVERRIDE {} 73 TemplateURL* template_url) OVERRIDE {}
60 74
61 DISALLOW_COPY_AND_ASSIGN(AthenaTemplateURLServiceClient); 75 DISALLOW_COPY_AND_ASSIGN(AthenaTemplateURLServiceClient);
62 }; 76 };
63 77
64 class UrlSearchResult : public app_list::SearchResult { 78 class UrlSearchResult : public app_list::SearchResult {
65 public: 79 public:
66 UrlSearchResult(content::BrowserContext* browser_context, 80 UrlSearchResult(content::BrowserContext* browser_context,
67 TemplateURLService* template_url_service, 81 const GURL& url,
68 const base::string16& query) 82 const base::string16& title)
69 : browser_context_(browser_context), 83 : browser_context_(browser_context),
70 template_url_service_(template_url_service), 84 url_(url) {
71 input_(query, 85 set_title(title);
72 base::string16::npos /* cursor_position */, 86 set_id(url_.spec());
73 base::string16() /* desired_tld */,
74 GURL() /* current_url */,
75 metrics::OmniboxEventProto::INVALID_SPEC,
76 false /* prevent_inline_autocomplete */,
77 false /* prefer_keyword */,
78 true /* allow_extract_keyword_match */,
79 true /* want_asynchronous_matches */,
80 AthenaSchemeClassifier()) {
81 set_title(query);
82 app_list::SearchResult::Tags title_tags;
83 if (input_.type() == metrics::OmniboxInputType::URL) {
84 title_tags.push_back(app_list::SearchResult::Tag(
85 app_list::SearchResult::Tag::URL, 0, query.size()));
86 }
87 title_tags.push_back(app_list::SearchResult::Tag(
88 app_list::SearchResult::Tag::MATCH, 0, query.size()));
89 set_title_tags(title_tags);
90 set_id(base::UTF16ToUTF8(query));
91 } 87 }
92 88
93 private: 89 private:
94 // Overriddenn from app_list::SearchResult: 90 // Overriddenn from app_list::SearchResult:
95 virtual void Open(int event_flags) OVERRIDE { 91 virtual void Open(int event_flags) OVERRIDE {
96 GURL url;
97 if (input_.type() == metrics::OmniboxInputType::URL) {
98 url = input_.canonicalized_url();
99 } else {
100 TemplateURL* template_url =
101 template_url_service_->GetDefaultSearchProvider();
102 const TemplateURLRef& search_url = template_url->url_ref();
103 TemplateURLRef::SearchTermsArgs search_terms_args(input_.text());
104 url = GURL(search_url.ReplaceSearchTerms(
105 search_terms_args, template_url_service_->search_terms_data()));
106 }
107 ActivityManager::Get()->AddActivity( 92 ActivityManager::Get()->AddActivity(
108 ActivityFactory::Get()->CreateWebActivity(browser_context_, url)); 93 ActivityFactory::Get()->CreateWebActivity(browser_context_, url_));
109 } 94 }
110 95
111 content::BrowserContext* browser_context_; 96 content::BrowserContext* browser_context_;
112 TemplateURLService* template_url_service_; 97 GURL url_;
113 AutocompleteInput input_;
114 98
115 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult); 99 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult);
116 }; 100 };
117 101
102 scoped_ptr<app_list::SearchResult> CreateResultForSearchQuery(
103 content::BrowserContext* browser_context,
104 TemplateURLService* template_url_service,
105 const base::string16& search_query) {
106 TemplateURL* template_url =
107 template_url_service->GetDefaultSearchProvider();
108 const TemplateURLRef& search_url = template_url->url_ref();
109 TemplateURLRef::SearchTermsArgs search_terms_args(search_query);
110 return scoped_ptr<app_list::SearchResult>(new UrlSearchResult(
111 browser_context,
112 GURL(search_url.ReplaceSearchTerms(
113 search_terms_args, template_url_service->search_terms_data())),
114 search_query));
115 }
116
117 scoped_ptr<app_list::SearchResult> CreateResultForInput(
118 content::BrowserContext* browser_context,
119 TemplateURLService* template_url_service,
120 const AutocompleteInput& input) {
121 scoped_ptr<app_list::SearchResult> result;
122 app_list::SearchResult::Tags title_tags;
123 if (input.type() == metrics::OmniboxInputType::URL) {
124 result.reset(new UrlSearchResult(
125 browser_context, input.canonicalized_url(), input.text()));
126 title_tags.push_back(app_list::SearchResult::Tag(
127 app_list::SearchResult::Tag::URL, 0, input.text().size()));
128 } else {
129 result = CreateResultForSearchQuery(
130 browser_context, template_url_service, input.text());
131 }
132 title_tags.push_back(app_list::SearchResult::Tag(
133 app_list::SearchResult::Tag::MATCH, 0, input.text().size()));
134 result->set_title_tags(title_tags);
135 return result.Pass();
136 }
137
118 } // namespace 138 } // namespace
119 139
120 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context) 140 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context)
121 : browser_context_(browser_context), 141 : browser_context_(browser_context),
122 // TODO(mukai): introduce the real parameters when it's necessary. 142 // TODO(mukai): introduce the real parameters when it's necessary.
123 template_url_service_( 143 template_url_service_(
124 new TemplateURLService(NULL /* prefs */, 144 new TemplateURLService(NULL /* prefs */,
125 make_scoped_ptr(new SearchTermsData()), 145 scoped_ptr<SearchTermsData>(
146 new AthenaSearchTermsData()),
126 NULL /* KeywordWebDataService */, 147 NULL /* KeywordWebDataService */,
127 scoped_ptr<TemplateURLServiceClient>( 148 scoped_ptr<TemplateURLServiceClient>(
128 new AthenaTemplateURLServiceClient()), 149 new AthenaTemplateURLServiceClient()),
129 NULL /*GoogleURLTracker */, 150 NULL /*GoogleURLTracker */,
130 NULL /* RapporService */, 151 NULL /* RapporService */,
131 base::Closure() /* dsp_change_callback */)) { 152 base::Closure() /* dsp_change_callback */)),
153 should_fetch_suggestions_again_(false) {
132 template_url_service_->Load(); 154 template_url_service_->Load();
133 } 155 }
134 156
135 UrlSearchProvider::~UrlSearchProvider() { 157 UrlSearchProvider::~UrlSearchProvider() {
136 } 158 }
137 159
138 void UrlSearchProvider::Start(const base::string16& query) { 160 void UrlSearchProvider::Start(const base::string16& query) {
161 input_ = AutocompleteInput(query,
162 base::string16::npos /* cursor_position */,
163 base::string16() /* desired_tld */,
164 GURL() /* current_url */,
165 metrics::OmniboxEventProto::INVALID_SPEC,
166 false /* prevent_inline_autocomplete */,
167 false /* prefer_keyword */,
168 true /* allow_extract_keyword_match */,
169 true /* want_asynchronous_matches */,
170 AthenaSchemeClassifier());
139 ClearResults(); 171 ClearResults();
140 Add(scoped_ptr<app_list::SearchResult>(new UrlSearchResult( 172 Add(CreateResultForInput(browser_context_, template_url_service_.get(),
141 browser_context_, template_url_service_.get(), query))); 173 input_));
174 StartFetchingSuggestions();
142 } 175 }
143 176
144 void UrlSearchProvider::Stop() { 177 void UrlSearchProvider::Stop() {
178 suggestion_fetcher_.reset();
179 }
180
181 void UrlSearchProvider::OnURLFetchComplete(const net::URLFetcher* source) {
182 DCHECK_EQ(suggestion_fetcher_.get(), source);
183
184 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
185 std::string json_data = SearchSuggestionParser::ExtractJsonData(source);
186 scoped_ptr<base::Value> data(
187 SearchSuggestionParser::DeserializeJsonData(json_data));
188 if (data) {
189 const int kDefaultRelevance = 0;
190 SearchSuggestionParser::Results results;
191 if (SearchSuggestionParser::ParseSuggestResults(
192 *data, input_, AthenaSchemeClassifier(), kDefaultRelevance,
193 std::string(), // languages
194 false, // is_keyword_result
195 &results)) {
196 ClearResults();
197 Add(CreateResultForInput(browser_context_, template_url_service_.get(),
198 input_));
199 for (size_t i = 0; i < results.suggest_results.size(); ++i) {
200 const SearchSuggestionParser::SuggestResult& result =
201 results.suggest_results[i];
202 Add(CreateResultForSearchQuery(browser_context_,
203 template_url_service_.get(),
204 result.suggestion()));
205 }
206 for (size_t i = 0; i < results.navigation_results.size(); ++i) {
207 const SearchSuggestionParser::NavigationResult& result =
208 results.navigation_results[i];
209 Add(scoped_ptr<app_list::SearchResult>(
210 new UrlSearchResult(browser_context_, result.url(),
211 result.description())));
212 }
213 }
214 }
215 }
216 suggestion_fetcher_.reset();
217 if (should_fetch_suggestions_again_)
218 StartFetchingSuggestions();
219 }
220
221 void UrlSearchProvider::StartFetchingSuggestions() {
222 if (suggestion_fetcher_) {
223 should_fetch_suggestions_again_ = true;
224 return;
225 }
226 should_fetch_suggestions_again_ = false;
227
228 // Bail if the suggestion URL is invalid with the given replacements.
229 TemplateURL* template_url = template_url_service_->GetDefaultSearchProvider();
230 TemplateURLRef::SearchTermsArgs search_term_args(input_.text());
231 search_term_args.input_type = input_.type();
232 search_term_args.cursor_position = input_.cursor_position();
233 search_term_args.page_classification = input_.current_page_classification();
234 GURL suggest_url(template_url->suggestions_url_ref().ReplaceSearchTerms(
235 search_term_args, template_url_service_->search_terms_data()));
236 if (!suggest_url.is_valid()) {
237 DLOG(ERROR) << "Invalid URL: " << suggest_url;
238 return;
239 }
240 suggestion_fetcher_.reset(
241 net::URLFetcher::Create(suggest_url, net::URLFetcher::GET, this));
242 suggestion_fetcher_->SetRequestContext(browser_context_->GetRequestContext());
243 suggestion_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
244 suggestion_fetcher_->Start();
145 } 245 }
146 246
147 } // namespace athena 247 } // namespace athena
OLDNEW
« athena/home/app_list_view_delegate.cc ('K') | « athena/main/url_search_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698