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

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: Add TODO 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
« no previous file with comments | « athena/main/url_search_provider.h ('k') | athena/resources/athena_resources.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_client.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 AutocompleteProviderClient for Athena.
77 class AthenaAutocompleteProviderClient : public AutocompleteProviderClient {
78 public:
79 explicit AthenaAutocompleteProviderClient(
80 content::BrowserContext* browser_context)
81 : browser_context_(browser_context) {}
82 virtual ~AthenaAutocompleteProviderClient() {}
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 // TODO(hashimoto): Return the value stored in the prefs.
92 return "en-US";
93 }
94 virtual bool SearchSuggestEnabled() OVERRIDE { return true; }
95 virtual bool ShowBookmarkBar() OVERRIDE { return false; }
96 virtual const AutocompleteSchemeClassifier& SchemeClassifier() OVERRIDE {
97 return scheme_classifier_;
98 }
99 virtual void Classify(
100 const base::string16& text,
101 bool prefer_keyword,
102 bool allow_exact_keyword_match,
103 metrics::OmniboxEventProto::PageClassification page_classification,
104 AutocompleteMatch* match,
105 GURL* alternate_nav_url) OVERRIDE {}
106 virtual history::URLDatabase* InMemoryDatabase() OVERRIDE { return NULL; }
107 virtual void DeleteMatchingURLsForKeywordFromHistory(
108 history::KeywordID keyword_id,
109 const base::string16& term) OVERRIDE {}
110 virtual bool TabSyncEnabledAndUnencrypted() OVERRIDE { return false; }
111 virtual void PrefetchImage(const GURL& url) OVERRIDE {}
112
113 private:
114 content::BrowserContext* browser_context_;
115 AthenaSchemeClassifier scheme_classifier_;
116
117 DISALLOW_COPY_AND_ASSIGN(AthenaAutocompleteProviderClient);
118 };
119
120 int ACMatchStyleToTagStyle(int styles) {
121 int tag_styles = 0;
122 if (styles & ACMatchClassification::URL)
123 tag_styles |= app_list::SearchResult::Tag::URL;
124 if (styles & ACMatchClassification::MATCH)
125 tag_styles |= app_list::SearchResult::Tag::MATCH;
126 if (styles & ACMatchClassification::DIM)
127 tag_styles |= app_list::SearchResult::Tag::DIM;
128
129 return tag_styles;
130 }
131
132 // Translates ACMatchClassifications into SearchResult tags.
133 void ACMatchClassificationsToTags(
134 const base::string16& text,
135 const ACMatchClassifications& text_classes,
136 app_list::SearchResult::Tags* tags) {
137 int tag_styles = app_list::SearchResult::Tag::NONE;
138 size_t tag_start = 0;
139
140 for (size_t i = 0; i < text_classes.size(); ++i) {
141 const ACMatchClassification& text_class = text_classes[i];
142
143 // Closes current tag.
144 if (tag_styles != app_list::SearchResult::Tag::NONE) {
145 tags->push_back(app_list::SearchResult::Tag(
146 tag_styles, tag_start, text_class.offset));
147 tag_styles = app_list::SearchResult::Tag::NONE;
148 }
149
150 if (text_class.style == ACMatchClassification::NONE)
151 continue;
152
153 tag_start = text_class.offset;
154 tag_styles = ACMatchStyleToTagStyle(text_class.style);
155 }
156
157 if (tag_styles != app_list::SearchResult::Tag::NONE) {
158 tags->push_back(app_list::SearchResult::Tag(
159 tag_styles, tag_start, text.length()));
160 }
161 }
162
78 class UrlSearchResult : public app_list::SearchResult { 163 class UrlSearchResult : public app_list::SearchResult {
79 public: 164 public:
80 UrlSearchResult(content::BrowserContext* browser_context, 165 UrlSearchResult(content::BrowserContext* browser_context,
81 const GURL& url, 166 const AutocompleteMatch& match)
82 const base::string16& title)
83 : browser_context_(browser_context), 167 : browser_context_(browser_context),
84 url_(url) { 168 match_(match) {
85 set_title(title); 169 set_id(match_.destination_url.spec());
86 set_id(url_.spec()); 170
171 // Derive relevance from omnibox relevance and normalize it to [0, 1].
172 // The magic number 1500 is the highest score of an omnibox result.
173 // See comments in autocomplete_provider.h.
174 set_relevance(match_.relevance / 1500.0);
175
176 UpdateIcon();
177 UpdateTitleAndDetails();
87 } 178 }
88 179
180 virtual ~UrlSearchResult() {}
181
89 private: 182 private:
90 // Overriddenn from app_list::SearchResult: 183 // Overriddenn from app_list::SearchResult:
91 virtual void Open(int event_flags) OVERRIDE { 184 virtual void Open(int event_flags) OVERRIDE {
92 ActivityManager::Get()->AddActivity( 185 ActivityManager::Get()->AddActivity(
93 ActivityFactory::Get()->CreateWebActivity(browser_context_, url_)); 186 ActivityFactory::Get()->CreateWebActivity(browser_context_,
187 match_.destination_url));
188 }
189
190 void UpdateIcon() {
191 SetIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
192 AutocompleteMatch::TypeToIcon(match_.type)));
193 }
194
195 void UpdateTitleAndDetails() {
196 set_title(match_.contents);
197 SearchResult::Tags title_tags;
198 ACMatchClassificationsToTags(match_.contents,
199 match_.contents_class,
200 &title_tags);
201 set_title_tags(title_tags);
202
203 set_details(match_.description);
204 SearchResult::Tags details_tags;
205 ACMatchClassificationsToTags(match_.description,
206 match_.description_class,
207 &details_tags);
208 set_details_tags(details_tags);
94 } 209 }
95 210
96 content::BrowserContext* browser_context_; 211 content::BrowserContext* browser_context_;
97 GURL url_; 212 AutocompleteMatch match_;
98 213
99 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult); 214 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult);
100 }; 215 };
101 216
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 217 } // namespace
139 218
140 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context) 219 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context)
141 : browser_context_(browser_context), 220 : browser_context_(browser_context),
142 // TODO(mukai): introduce the real parameters when it's necessary. 221 // TODO(mukai): introduce the real parameters when it's necessary.
143 template_url_service_( 222 template_url_service_(
144 new TemplateURLService(NULL /* prefs */, 223 new TemplateURLService(NULL /* prefs */,
145 scoped_ptr<SearchTermsData>( 224 scoped_ptr<SearchTermsData>(
146 new AthenaSearchTermsData()), 225 new AthenaSearchTermsData()),
147 NULL /* KeywordWebDataService */, 226 NULL /* KeywordWebDataService */,
148 scoped_ptr<TemplateURLServiceClient>( 227 scoped_ptr<TemplateURLServiceClient>(
149 new AthenaTemplateURLServiceClient()), 228 new AthenaTemplateURLServiceClient()),
150 NULL /*GoogleURLTracker */, 229 NULL /*GoogleURLTracker */,
151 NULL /* RapporService */, 230 NULL /* RapporService */,
152 base::Closure() /* dsp_change_callback */)), 231 base::Closure() /* dsp_change_callback */)),
153 should_fetch_suggestions_again_(false) { 232 provider_(new ::SearchProvider(
233 this,
234 template_url_service_.get(),
235 scoped_ptr<AutocompleteProviderClient>(
236 new AthenaAutocompleteProviderClient(browser_context_)))) {
154 template_url_service_->Load(); 237 template_url_service_->Load();
155 } 238 }
156 239
157 UrlSearchProvider::~UrlSearchProvider() { 240 UrlSearchProvider::~UrlSearchProvider() {
158 } 241 }
159 242
160 void UrlSearchProvider::Start(const base::string16& query) { 243 void UrlSearchProvider::Start(const base::string16& query) {
244 const bool minimal_changes = query == input_.text();
161 input_ = AutocompleteInput(query, 245 input_ = AutocompleteInput(query,
162 base::string16::npos /* cursor_position */, 246 base::string16::npos /* cursor_position */,
163 base::string16() /* desired_tld */, 247 base::string16() /* desired_tld */,
164 GURL() /* current_url */, 248 GURL() /* current_url */,
165 metrics::OmniboxEventProto::INVALID_SPEC, 249 metrics::OmniboxEventProto::INVALID_SPEC,
166 false /* prevent_inline_autocomplete */, 250 false /* prevent_inline_autocomplete */,
167 false /* prefer_keyword */, 251 false /* prefer_keyword */,
168 true /* allow_extract_keyword_match */, 252 true /* allow_extract_keyword_match */,
169 true /* want_asynchronous_matches */, 253 true /* want_asynchronous_matches */,
170 AthenaSchemeClassifier()); 254 AthenaSchemeClassifier());
171 ClearResults(); 255
172 Add(CreateResultForInput(browser_context_, template_url_service_.get(), 256 provider_->Start(input_, minimal_changes);
173 input_));
174 StartFetchingSuggestions();
175 } 257 }
176 258
177 void UrlSearchProvider::Stop() { 259 void UrlSearchProvider::Stop() {
178 suggestion_fetcher_.reset(); 260 provider_->Stop(false);
179 } 261 }
180 262
181 void UrlSearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { 263 void UrlSearchProvider::OnProviderUpdate(bool updated_matches) {
182 DCHECK_EQ(suggestion_fetcher_.get(), source); 264 if (!updated_matches)
265 return;
183 266
184 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) { 267 ClearResults();
185 std::string json_data = SearchSuggestionParser::ExtractJsonData(source); 268
186 scoped_ptr<base::Value> data( 269 const ACMatches& matches = provider_->matches();
187 SearchSuggestionParser::DeserializeJsonData(json_data)); 270 for (ACMatches::const_iterator it = matches.begin(); it != matches.end();
188 if (data) { 271 ++it) {
189 const int kDefaultRelevance = 0; 272 if (!it->destination_url.is_valid())
190 SearchSuggestionParser::Results results; 273 continue;
191 if (SearchSuggestionParser::ParseSuggestResults( 274
192 *data, input_, AthenaSchemeClassifier(), kDefaultRelevance, 275 Add(scoped_ptr<app_list::SearchResult>(new UrlSearchResult(
193 std::string(), // languages 276 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 } 277 }
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 } 278 }
246 279
247 } // namespace athena 280 } // namespace athena
OLDNEW
« no previous file with comments | « athena/main/url_search_provider.h ('k') | athena/resources/athena_resources.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698