| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/autocomplete/zero_suggest_provider.h" | 5 #include "chrome/browser/autocomplete/zero_suggest_provider.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
| 9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 done_ = true; | 140 done_ = true; |
| 141 | 141 |
| 142 ConvertResultsToAutocompleteMatches(); | 142 ConvertResultsToAutocompleteMatches(); |
| 143 if (!matches_.empty()) | 143 if (!matches_.empty()) |
| 144 listener_->OnProviderUpdate(true); | 144 listener_->OnProviderUpdate(true); |
| 145 } | 145 } |
| 146 | 146 |
| 147 void ZeroSuggestProvider::StartZeroSuggest( | 147 void ZeroSuggestProvider::StartZeroSuggest( |
| 148 const GURL& current_page_url, | 148 const GURL& current_page_url, |
| 149 AutocompleteInput::PageClassification page_classification, | 149 AutocompleteInput::PageClassification page_classification, |
| 150 const string16& permanent_text) { | 150 const base::string16& permanent_text) { |
| 151 Stop(true); | 151 Stop(true); |
| 152 field_trial_triggered_ = false; | 152 field_trial_triggered_ = false; |
| 153 field_trial_triggered_in_session_ = false; | 153 field_trial_triggered_in_session_ = false; |
| 154 permanent_text_ = permanent_text; | 154 permanent_text_ = permanent_text; |
| 155 current_query_ = current_page_url.spec(); | 155 current_query_ = current_page_url.spec(); |
| 156 current_page_classification_ = page_classification; | 156 current_page_classification_ = page_classification; |
| 157 current_url_match_ = MatchForCurrentURL(); | 157 current_url_match_ = MatchForCurrentURL(); |
| 158 | 158 |
| 159 const TemplateURL* default_provider = | 159 const TemplateURL* default_provider = |
| 160 template_url_service_->GetDefaultSearchProvider(); | 160 template_url_service_->GetDefaultSearchProvider(); |
| 161 if (default_provider == NULL) | 161 if (default_provider == NULL) |
| 162 return; | 162 return; |
| 163 string16 prefix; | 163 base::string16 prefix; |
| 164 TemplateURLRef::SearchTermsArgs search_term_args(prefix); | 164 TemplateURLRef::SearchTermsArgs search_term_args(prefix); |
| 165 search_term_args.current_page_url = current_query_; | 165 search_term_args.current_page_url = current_query_; |
| 166 GURL suggest_url(default_provider->suggestions_url_ref(). | 166 GURL suggest_url(default_provider->suggestions_url_ref(). |
| 167 ReplaceSearchTerms(search_term_args)); | 167 ReplaceSearchTerms(search_term_args)); |
| 168 if (!SearchProvider::CanSendURL( | 168 if (!SearchProvider::CanSendURL( |
| 169 current_page_url, suggest_url, | 169 current_page_url, suggest_url, |
| 170 template_url_service_->GetDefaultSearchProvider(), | 170 template_url_service_->GetDefaultSearchProvider(), |
| 171 page_classification, profile_) || | 171 page_classification, profile_) || |
| 172 !OmniboxFieldTrial::InZeroSuggestFieldTrial()) | 172 !OmniboxFieldTrial::InZeroSuggestFieldTrial()) |
| 173 return; | 173 return; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 193 } | 193 } |
| 194 | 194 |
| 195 ZeroSuggestProvider::~ZeroSuggestProvider() { | 195 ZeroSuggestProvider::~ZeroSuggestProvider() { |
| 196 } | 196 } |
| 197 | 197 |
| 198 void ZeroSuggestProvider::FillResults( | 198 void ZeroSuggestProvider::FillResults( |
| 199 const Value& root_val, | 199 const Value& root_val, |
| 200 int* verbatim_relevance, | 200 int* verbatim_relevance, |
| 201 SearchProvider::SuggestResults* suggest_results, | 201 SearchProvider::SuggestResults* suggest_results, |
| 202 SearchProvider::NavigationResults* navigation_results) { | 202 SearchProvider::NavigationResults* navigation_results) { |
| 203 string16 query; | 203 base::string16 query; |
| 204 const ListValue* root_list = NULL; | 204 const ListValue* root_list = NULL; |
| 205 const ListValue* results = NULL; | 205 const ListValue* results = NULL; |
| 206 const ListValue* relevances = NULL; | 206 const ListValue* relevances = NULL; |
| 207 // The response includes the query, which should be empty for ZeroSuggest | 207 // The response includes the query, which should be empty for ZeroSuggest |
| 208 // responses. | 208 // responses. |
| 209 if (!root_val.GetAsList(&root_list) || !root_list->GetString(0, &query) || | 209 if (!root_val.GetAsList(&root_list) || !root_list->GetString(0, &query) || |
| 210 (!query.empty()) || !root_list->GetList(1, &results)) | 210 (!query.empty()) || !root_list->GetList(1, &results)) |
| 211 return; | 211 return; |
| 212 | 212 |
| 213 // 3rd element: Description list. | 213 // 3rd element: Description list. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 235 bool triggered = false; | 235 bool triggered = false; |
| 236 extras->GetBoolean("google:fieldtrialtriggered", &triggered); | 236 extras->GetBoolean("google:fieldtrialtriggered", &triggered); |
| 237 field_trial_triggered_ |= triggered; | 237 field_trial_triggered_ |= triggered; |
| 238 field_trial_triggered_in_session_ |= triggered; | 238 field_trial_triggered_in_session_ |= triggered; |
| 239 } | 239 } |
| 240 | 240 |
| 241 // Clear the previous results now that new results are available. | 241 // Clear the previous results now that new results are available. |
| 242 suggest_results->clear(); | 242 suggest_results->clear(); |
| 243 navigation_results->clear(); | 243 navigation_results->clear(); |
| 244 | 244 |
| 245 string16 result, title; | 245 base::string16 result, title; |
| 246 std::string type; | 246 std::string type; |
| 247 for (size_t index = 0; results->GetString(index, &result); ++index) { | 247 for (size_t index = 0; results->GetString(index, &result); ++index) { |
| 248 // Google search may return empty suggestions for weird input characters, | 248 // Google search may return empty suggestions for weird input characters, |
| 249 // they make no sense at all and can cause problems in our code. | 249 // they make no sense at all and can cause problems in our code. |
| 250 if (result.empty()) | 250 if (result.empty()) |
| 251 continue; | 251 continue; |
| 252 | 252 |
| 253 int relevance = kDefaultZeroSuggestRelevance; | 253 int relevance = kDefaultZeroSuggestRelevance; |
| 254 | 254 |
| 255 // Apply valid suggested relevance scores; discard invalid lists. | 255 // Apply valid suggested relevance scores; discard invalid lists. |
| 256 if (relevances != NULL && !relevances->GetInteger(index, &relevance)) | 256 if (relevances != NULL && !relevances->GetInteger(index, &relevance)) |
| 257 relevances = NULL; | 257 relevances = NULL; |
| 258 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) { | 258 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) { |
| 259 // Do not blindly trust the URL coming from the server to be valid. | 259 // Do not blindly trust the URL coming from the server to be valid. |
| 260 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string())); | 260 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string())); |
| 261 if (url.is_valid()) { | 261 if (url.is_valid()) { |
| 262 if (descriptions != NULL) | 262 if (descriptions != NULL) |
| 263 descriptions->GetString(index, &title); | 263 descriptions->GetString(index, &title); |
| 264 navigation_results->push_back(SearchProvider::NavigationResult( | 264 navigation_results->push_back(SearchProvider::NavigationResult( |
| 265 *this, url, title, false, relevance, relevances != NULL)); | 265 *this, url, title, false, relevance, relevances != NULL)); |
| 266 } | 266 } |
| 267 } else { | 267 } else { |
| 268 suggest_results->push_back(SearchProvider::SuggestResult( | 268 suggest_results->push_back(SearchProvider::SuggestResult( |
| 269 result, result, string16(), std::string(), std::string(), false, | 269 result, result, base::string16(), std::string(), std::string(), false, |
| 270 relevance, relevances != NULL, false)); | 270 relevance, relevances != NULL, false)); |
| 271 } | 271 } |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 | 274 |
| 275 void ZeroSuggestProvider::AddSuggestResultsToMap( | 275 void ZeroSuggestProvider::AddSuggestResultsToMap( |
| 276 const SearchProvider::SuggestResults& results, | 276 const SearchProvider::SuggestResults& results, |
| 277 const TemplateURL* template_url, | 277 const TemplateURL* template_url, |
| 278 SearchProvider::MatchMap* map) { | 278 SearchProvider::MatchMap* map) { |
| 279 for (size_t i = 0; i < results.size(); ++i) { | 279 for (size_t i = 0; i < results.size(); ++i) { |
| 280 AddMatchToMap(results[i].relevance(), AutocompleteMatchType::SEARCH_SUGGEST, | 280 AddMatchToMap(results[i].relevance(), AutocompleteMatchType::SEARCH_SUGGEST, |
| 281 template_url, results[i].suggestion(), i, map); | 281 template_url, results[i].suggestion(), i, map); |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 void ZeroSuggestProvider::AddMatchToMap(int relevance, | 285 void ZeroSuggestProvider::AddMatchToMap(int relevance, |
| 286 AutocompleteMatch::Type type, | 286 AutocompleteMatch::Type type, |
| 287 const TemplateURL* template_url, | 287 const TemplateURL* template_url, |
| 288 const string16& query_string, | 288 const base::string16& query_string, |
| 289 int accepted_suggestion, | 289 int accepted_suggestion, |
| 290 SearchProvider::MatchMap* map) { | 290 SearchProvider::MatchMap* map) { |
| 291 // Pass in query_string as the input_text since we don't want any bolding. | 291 // Pass in query_string as the input_text since we don't want any bolding. |
| 292 // TODO(samarth|melevin): use the actual omnibox margin here as well instead | 292 // TODO(samarth|melevin): use the actual omnibox margin here as well instead |
| 293 // of passing in -1. | 293 // of passing in -1. |
| 294 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( | 294 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( |
| 295 this, AutocompleteInput(), query_string, relevance, type, false, | 295 this, AutocompleteInput(), query_string, relevance, type, false, |
| 296 query_string, string16(), template_url, query_string, std::string(), | 296 query_string, base::string16(), template_url, query_string, std::string(), |
| 297 accepted_suggestion, -1, true); | 297 accepted_suggestion, -1, true); |
| 298 if (!match.destination_url.is_valid()) | 298 if (!match.destination_url.is_valid()) |
| 299 return; | 299 return; |
| 300 | 300 |
| 301 // Try to add |match| to |map|. If a match for |query_string| is already in | 301 // Try to add |match| to |map|. If a match for |query_string| is already in |
| 302 // |map|, replace it if |match| is more relevant. | 302 // |map|, replace it if |match| is more relevant. |
| 303 // NOTE: Keep this ToLower() call in sync with url_database.cc. | 303 // NOTE: Keep this ToLower() call in sync with url_database.cc. |
| 304 SearchProvider::MatchKey match_key( | 304 SearchProvider::MatchKey match_key( |
| 305 std::make_pair(base::i18n::ToLower(query_string), std::string())); | 305 std::make_pair(base::i18n::ToLower(query_string), std::string())); |
| 306 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( | 306 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 for (SearchProvider::MatchMap::const_iterator it(query_matches_map_.begin()); | 436 for (SearchProvider::MatchMap::const_iterator it(query_matches_map_.begin()); |
| 437 it != query_matches_map_.end(); ++it) | 437 it != query_matches_map_.end(); ++it) |
| 438 matches_.push_back(it->second); | 438 matches_.push_back(it->second); |
| 439 | 439 |
| 440 for (SearchProvider::NavigationResults::const_iterator it( | 440 for (SearchProvider::NavigationResults::const_iterator it( |
| 441 navigation_results_.begin()); it != navigation_results_.end(); ++it) | 441 navigation_results_.begin()); it != navigation_results_.end(); ++it) |
| 442 matches_.push_back(NavigationToMatch(*it)); | 442 matches_.push_back(NavigationToMatch(*it)); |
| 443 } | 443 } |
| 444 | 444 |
| 445 AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() { | 445 AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() { |
| 446 AutocompleteInput input(permanent_text_, string16::npos, string16(), | 446 AutocompleteInput input(permanent_text_, base::string16::npos, base::string16(
), |
| 447 GURL(current_query_), current_page_classification_, | 447 GURL(current_query_), current_page_classification_, |
| 448 false, false, true, AutocompleteInput::ALL_MATCHES); | 448 false, false, true, AutocompleteInput::ALL_MATCHES); |
| 449 | 449 |
| 450 AutocompleteMatch match; | 450 AutocompleteMatch match; |
| 451 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify( | 451 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify( |
| 452 permanent_text_, false, true, &match, NULL); | 452 permanent_text_, false, true, &match, NULL); |
| 453 match.is_history_what_you_typed_match = false; | 453 match.is_history_what_you_typed_match = false; |
| 454 match.allowed_to_be_default_match = true; | 454 match.allowed_to_be_default_match = true; |
| 455 | 455 |
| 456 // The placeholder suggestion for the current URL has high relevance so | 456 // The placeholder suggestion for the current URL has high relevance so |
| 457 // that it is in the first suggestion slot and inline autocompleted. It | 457 // that it is in the first suggestion slot and inline autocompleted. It |
| 458 // gets dropped as soon as the user types something. | 458 // gets dropped as soon as the user types something. |
| 459 match.relevance = verbatim_relevance_; | 459 match.relevance = verbatim_relevance_; |
| 460 | 460 |
| 461 return match; | 461 return match; |
| 462 } | 462 } |
| OLD | NEW |