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

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

Issue 514583002: Use SearchProvider for Athena (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
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 "base/values.h"
11 #include "components/metrics/proto/omnibox_event.pb.h" 11 #include "components/metrics/proto/omnibox_event.pb.h"
12 #include "components/metrics/proto/omnibox_input_type.pb.h" 12 #include "components/metrics/proto/omnibox_input_type.pb.h"
13 #include "components/omnibox/autocomplete_input.h" 13 #include "components/omnibox/autocomplete_input.h"
14 #include "components/omnibox/autocomplete_provider_delegate.h"
14 #include "components/omnibox/autocomplete_scheme_classifier.h" 15 #include "components/omnibox/autocomplete_scheme_classifier.h"
15 #include "components/omnibox/search_suggestion_parser.h" 16 #include "components/omnibox/search_provider.h"
16 #include "components/search_engines/search_terms_data.h" 17 #include "components/search_engines/search_terms_data.h"
17 #include "components/search_engines/template_url.h"
18 #include "components/search_engines/template_url_service.h" 18 #include "components/search_engines/template_url_service.h"
19 #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" 20 #include "content/public/browser/browser_context.h"
21 #include "net/base/load_flags.h"
22 #include "net/url_request/url_fetcher.h"
23 #include "net/url_request/url_request.h"
24 #include "ui/app_list/search_result.h" 21 #include "ui/app_list/search_result.h"
22 #include "ui/base/resource/resource_bundle.h"
25 #include "url/gurl.h" 23 #include "url/gurl.h"
26 24
27 namespace athena { 25 namespace athena {
28 26
29 namespace { 27 namespace {
30 28
31 // The SearchTermsData implementation for Athena. 29 // The SearchTermsData implementation for Athena.
32 class AthenaSearchTermsData : public SearchTermsData { 30 class AthenaSearchTermsData : public SearchTermsData {
33 public: 31 public:
34 // SearchTermsData: 32 // SearchTermsData:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 const GURL& url, 66 const GURL& url,
69 TemplateURLID id, 67 TemplateURLID id,
70 const base::string16& term) OVERRIDE {} 68 const base::string16& term) OVERRIDE {}
71 virtual void AddKeywordGeneratedVisit(const GURL& url) OVERRIDE {} 69 virtual void AddKeywordGeneratedVisit(const GURL& url) OVERRIDE {}
72 virtual void RestoreExtensionInfoIfNecessary( 70 virtual void RestoreExtensionInfoIfNecessary(
73 TemplateURL* template_url) OVERRIDE {} 71 TemplateURL* template_url) OVERRIDE {}
74 72
75 DISALLOW_COPY_AND_ASSIGN(AthenaTemplateURLServiceClient); 73 DISALLOW_COPY_AND_ASSIGN(AthenaTemplateURLServiceClient);
76 }; 74 };
77 75
76 // The AutocompleteProviderDelegate for Athena.
77 class AthenaAutocompleteProviderDelegate : public AutocompleteProviderDelegate {
78 public:
79 explicit AthenaAutocompleteProviderDelegate(
80 content::BrowserContext* browser_context)
81 : browser_context_(browser_context) {}
82 virtual ~AthenaAutocompleteProviderDelegate() {}
83
84 virtual net::URLRequestContextGetter* RequestContext() OVERRIDE {
85 return browser_context_->GetRequestContext();
86 }
87 virtual bool IsOffTheRecord() OVERRIDE {
88 return browser_context_->IsOffTheRecord();
89 }
90 virtual std::string AcceptLanguages() OVERRIDE {
91 return "en-US";
Jun Mukai 2014/08/27 17:03:20 Can you put a TODO comment here?
hashimoto 2014/08/28 06:30:09 Done.
92 }
93 virtual bool SearchSuggestEnabled() OVERRIDE { return true; }
94 virtual bool ShowBookmarkBar() OVERRIDE { return false; }
95 virtual const AutocompleteSchemeClassifier& SchemeClassifier() OVERRIDE {
96 return scheme_classifier_;
97 }
98 virtual void Classify(
99 const base::string16& text,
100 bool prefer_keyword,
101 bool allow_exact_keyword_match,
102 metrics::OmniboxEventProto::PageClassification page_classification,
103 AutocompleteMatch* match,
104 GURL* alternate_nav_url) OVERRIDE {}
105 virtual history::URLDatabase* InMemoryDatabase() OVERRIDE { return NULL; }
106 virtual void DeleteMatchingURLsForKeywordFromHistory(
107 history::KeywordID keyword_id,
108 const base::string16& term) OVERRIDE {}
109 virtual bool TabSyncEnabledAndUnencrypted() OVERRIDE { return false; }
110 virtual void PrefetchImage(const GURL& url) OVERRIDE {}
111
112 private:
113 content::BrowserContext* browser_context_;
114 AthenaSchemeClassifier scheme_classifier_;
115
116 DISALLOW_COPY_AND_ASSIGN(AthenaAutocompleteProviderDelegate);
117 };
118
119 int ACMatchStyleToTagStyle(int styles) {
120 int tag_styles = 0;
121 if (styles & ACMatchClassification::URL)
122 tag_styles |= app_list::SearchResult::Tag::URL;
123 if (styles & ACMatchClassification::MATCH)
124 tag_styles |= app_list::SearchResult::Tag::MATCH;
125 if (styles & ACMatchClassification::DIM)
126 tag_styles |= app_list::SearchResult::Tag::DIM;
127
128 return tag_styles;
129 }
130
131 // Translates ACMatchClassifications into SearchResult tags.
132 void ACMatchClassificationsToTags(
133 const base::string16& text,
134 const ACMatchClassifications& text_classes,
135 app_list::SearchResult::Tags* tags) {
136 int tag_styles = app_list::SearchResult::Tag::NONE;
137 size_t tag_start = 0;
138
139 for (size_t i = 0; i < text_classes.size(); ++i) {
140 const ACMatchClassification& text_class = text_classes[i];
141
142 // Closes current tag.
143 if (tag_styles != app_list::SearchResult::Tag::NONE) {
144 tags->push_back(app_list::SearchResult::Tag(
145 tag_styles, tag_start, text_class.offset));
146 tag_styles = app_list::SearchResult::Tag::NONE;
147 }
148
149 if (text_class.style == ACMatchClassification::NONE)
150 continue;
151
152 tag_start = text_class.offset;
153 tag_styles = ACMatchStyleToTagStyle(text_class.style);
154 }
155
156 if (tag_styles != app_list::SearchResult::Tag::NONE) {
157 tags->push_back(app_list::SearchResult::Tag(
158 tag_styles, tag_start, text.length()));
159 }
160 }
161
78 class UrlSearchResult : public app_list::SearchResult { 162 class UrlSearchResult : public app_list::SearchResult {
79 public: 163 public:
80 UrlSearchResult(content::BrowserContext* browser_context, 164 UrlSearchResult(content::BrowserContext* browser_context,
81 const GURL& url, 165 const AutocompleteMatch& match)
82 const base::string16& title)
83 : browser_context_(browser_context), 166 : browser_context_(browser_context),
84 url_(url) { 167 match_(match) {
85 set_title(title); 168 set_id(match_.destination_url.spec());
86 set_id(url_.spec()); 169
170 // Derive relevance from omnibox relevance and normalize it to [0, 1].
171 // The magic number 1500 is the highest score of an omnibox result.
172 // See comments in autocomplete_provider.h.
173 set_relevance(match_.relevance / 1500.0);
174
175 UpdateIcon();
176 UpdateTitleAndDetails();
87 } 177 }
88 178
179 virtual ~UrlSearchResult() {}
180
89 private: 181 private:
90 // Overriddenn from app_list::SearchResult: 182 // Overriddenn from app_list::SearchResult:
91 virtual void Open(int event_flags) OVERRIDE { 183 virtual void Open(int event_flags) OVERRIDE {
92 ActivityManager::Get()->AddActivity( 184 ActivityManager::Get()->AddActivity(
93 ActivityFactory::Get()->CreateWebActivity(browser_context_, url_)); 185 ActivityFactory::Get()->CreateWebActivity(browser_context_,
186 match_.destination_url));
187 }
188
189 void UpdateIcon() {
190 SetIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
191 AutocompleteMatch::TypeToIcon(match_.type)));
192 }
193
194 void UpdateTitleAndDetails() {
195 set_title(match_.contents);
196 SearchResult::Tags title_tags;
197 ACMatchClassificationsToTags(match_.contents,
198 match_.contents_class,
199 &title_tags);
200 set_title_tags(title_tags);
201
202 set_details(match_.description);
203 SearchResult::Tags details_tags;
204 ACMatchClassificationsToTags(match_.description,
205 match_.description_class,
206 &details_tags);
207 set_details_tags(details_tags);
94 } 208 }
95 209
96 content::BrowserContext* browser_context_; 210 content::BrowserContext* browser_context_;
97 GURL url_; 211 AutocompleteMatch match_;
98 212
99 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult); 213 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult);
100 }; 214 };
101 215
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
138 } // namespace 216 } // namespace
139 217
140 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context) 218 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context)
141 : browser_context_(browser_context), 219 : browser_context_(browser_context),
142 // TODO(mukai): introduce the real parameters when it's necessary. 220 // TODO(mukai): introduce the real parameters when it's necessary.
143 template_url_service_( 221 template_url_service_(
144 new TemplateURLService(NULL /* prefs */, 222 new TemplateURLService(NULL /* prefs */,
145 scoped_ptr<SearchTermsData>( 223 scoped_ptr<SearchTermsData>(
146 new AthenaSearchTermsData()), 224 new AthenaSearchTermsData()),
147 NULL /* KeywordWebDataService */, 225 NULL /* KeywordWebDataService */,
148 scoped_ptr<TemplateURLServiceClient>( 226 scoped_ptr<TemplateURLServiceClient>(
149 new AthenaTemplateURLServiceClient()), 227 new AthenaTemplateURLServiceClient()),
150 NULL /*GoogleURLTracker */, 228 NULL /*GoogleURLTracker */,
151 NULL /* RapporService */, 229 NULL /* RapporService */,
152 base::Closure() /* dsp_change_callback */)), 230 base::Closure() /* dsp_change_callback */)),
153 should_fetch_suggestions_again_(false) { 231 provider_(new ::SearchProvider(
232 this,
233 template_url_service_.get(),
234 scoped_ptr<AutocompleteProviderDelegate>(
235 new AthenaAutocompleteProviderDelegate(browser_context_)))) {
154 template_url_service_->Load(); 236 template_url_service_->Load();
155 } 237 }
156 238
157 UrlSearchProvider::~UrlSearchProvider() { 239 UrlSearchProvider::~UrlSearchProvider() {
158 } 240 }
159 241
160 void UrlSearchProvider::Start(const base::string16& query) { 242 void UrlSearchProvider::Start(const base::string16& query) {
243 const bool minimal_changes = query == input_.text();
161 input_ = AutocompleteInput(query, 244 input_ = AutocompleteInput(query,
162 base::string16::npos /* cursor_position */, 245 base::string16::npos /* cursor_position */,
163 base::string16() /* desired_tld */, 246 base::string16() /* desired_tld */,
164 GURL() /* current_url */, 247 GURL() /* current_url */,
165 metrics::OmniboxEventProto::INVALID_SPEC, 248 metrics::OmniboxEventProto::INVALID_SPEC,
166 false /* prevent_inline_autocomplete */, 249 false /* prevent_inline_autocomplete */,
167 false /* prefer_keyword */, 250 false /* prefer_keyword */,
168 true /* allow_extract_keyword_match */, 251 true /* allow_extract_keyword_match */,
169 true /* want_asynchronous_matches */, 252 true /* want_asynchronous_matches */,
170 AthenaSchemeClassifier()); 253 AthenaSchemeClassifier());
171 ClearResults(); 254
172 Add(CreateResultForInput(browser_context_, template_url_service_.get(), 255 provider_->Start(input_, minimal_changes);
173 input_));
174 StartFetchingSuggestions();
175 } 256 }
176 257
177 void UrlSearchProvider::Stop() { 258 void UrlSearchProvider::Stop() {
178 suggestion_fetcher_.reset(); 259 provider_->Stop(false);
179 } 260 }
180 261
181 void UrlSearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { 262 void UrlSearchProvider::OnProviderUpdate(bool updated_matches) {
182 DCHECK_EQ(suggestion_fetcher_.get(), source); 263 if (!updated_matches)
264 return;
183 265
184 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) { 266 ClearResults();
185 std::string json_data = SearchSuggestionParser::ExtractJsonData(source); 267
186 scoped_ptr<base::Value> data( 268 const ACMatches& matches = provider_->matches();
187 SearchSuggestionParser::DeserializeJsonData(json_data)); 269 for (ACMatches::const_iterator it = matches.begin(); it != matches.end();
188 if (data) { 270 ++it) {
189 const int kDefaultRelevance = 0; 271 if (!it->destination_url.is_valid())
190 SearchSuggestionParser::Results results; 272 continue;
191 if (SearchSuggestionParser::ParseSuggestResults( 273
192 *data, input_, AthenaSchemeClassifier(), kDefaultRelevance, 274 Add(scoped_ptr<app_list::SearchResult>(new UrlSearchResult(
193 std::string(), // languages 275 browser_context_, *it)));
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 } 276 }
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();
245 } 277 }
246 278
247 } // namespace athena 279 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698