Chromium Code Reviews| Index: chrome/browser/autocomplete/search_provider.cc |
| diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc |
| index 2e79b08f3841cd8c1562bf669ea5ce13ea10a12b..d95ebd56d059ad1ceda733cfbfa9dd74492043ee 100644 |
| --- a/chrome/browser/autocomplete/search_provider.cc |
| +++ b/chrome/browser/autocomplete/search_provider.cc |
| @@ -213,6 +213,7 @@ SearchProvider::SuggestResult::SuggestResult( |
| const string16& match_contents, |
| const string16& annotation, |
| const std::string& suggest_query_params, |
| + const std::string& deletion_url, |
| bool from_keyword_provider, |
| int relevance, |
| bool relevance_from_server, |
| @@ -222,6 +223,7 @@ SearchProvider::SuggestResult::SuggestResult( |
| match_contents_(match_contents), |
| annotation_(annotation), |
| suggest_query_params_(suggest_query_params), |
| + deletion_url_(deletion_url), |
| should_prefetch_(should_prefetch) { |
| } |
| @@ -321,15 +323,51 @@ bool SearchProvider::Results::HasServerProvidedScores() const { |
| } |
| +// SearchProvider::SuggestionDeletionHandler --------------------------------- |
| +SearchProvider::SuggestionDeletionHandler::SuggestionDeletionHandler() { |
|
Peter Kasting
2013/11/23 00:08:43
Nit: Blank line above this
Maria
2013/11/26 02:36:27
Done.
|
| +}; |
| + |
| +SearchProvider::SuggestionDeletionHandler::~SuggestionDeletionHandler() { |
|
Peter Kasting
2013/11/23 00:08:43
Nit: Function definition order should match the cl
Maria
2013/11/26 02:36:27
Done.
Quick question: that doesn't seem currently
Peter Kasting
2013/11/26 02:46:22
All class definitions in all files should always m
Maria
2013/11/27 02:18:06
Done.
|
| +}; |
| + |
| +void SearchProvider::SuggestionDeletionHandler::StartRequest( |
| + const std::string& deletion_url, Profile* profile, |
|
Peter Kasting
2013/11/23 00:08:43
Nit: One arg per line
Maria
2013/11/26 02:36:27
Done.
|
| + const base::Callback<void(bool)>& callback) { |
| + callback_ = callback; |
| + GURL url = GURL(deletion_url); |
|
Peter Kasting
2013/11/23 00:08:43
Nit: GURL url(deletion_url);
Maria
2013/11/26 02:36:27
Done. Sorry, Java habits die hard.
|
| + if (url.is_valid()) { |
|
Peter Kasting
2013/11/23 00:08:43
Perhaps we should check GURL validity in AddMatchT
Maria
2013/11/26 02:36:27
Done.
|
| + deletion_fetcher_.reset(net::URLFetcher::Create( |
| + SearchProvider::kDeletionURLFetcherID, |
| + url, |
| + net::URLFetcher::GET, |
| + this)); |
| + deletion_fetcher_->SetRequestContext(profile->GetRequestContext()); |
| + deletion_fetcher_->Start(); |
| + } else { |
| + callback_.Run(false); |
| + } |
| +}; |
| + |
| +void SearchProvider::SuggestionDeletionHandler::OnURLFetchComplete( |
| + const net::URLFetcher* source) { |
| + DCHECK(source == deletion_fetcher_.get()); |
| + const bool was_deletion_success = source->GetStatus().is_success() && |
| + source->GetResponseCode() == 200; |
|
Peter Kasting
2013/11/23 00:08:43
Nit: Parens around binary subexprs
Optional: Inli
Maria
2013/11/26 02:36:27
Done.
|
| + callback_.Run(was_deletion_success); |
| + delete this; |
| +}; |
| + |
|
Peter Kasting
2013/11/23 00:08:43
Nit: One more blank line here
Maria
2013/11/26 02:36:27
Done.
|
| // SearchProvider ------------------------------------------------------------- |
| // static |
| const int SearchProvider::kDefaultProviderURLFetcherID = 1; |
| const int SearchProvider::kKeywordProviderURLFetcherID = 2; |
| +const int SearchProvider::kDeletionURLFetcherID = 3; |
| int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100; |
| const char SearchProvider::kRelevanceFromServerKey[] = "relevance_from_server"; |
| const char SearchProvider::kShouldPrefetchKey[] = "should_prefetch"; |
| const char SearchProvider::kSuggestMetadataKey[] = "suggest_metadata"; |
| +const char SearchProvider::kDeletionUrlKey[] = "deletion_url"; |
| const char SearchProvider::kTrue[] = "true"; |
| const char SearchProvider::kFalse[] = "false"; |
| @@ -638,6 +676,7 @@ void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { |
| source->GetResponseHeaders(); |
| std::string json_data; |
| source->GetResponseAsString(&json_data); |
| + |
| // JSON is supposed to be UTF-8, but some suggest service providers send |
| // JSON files in non-UTF-8 encodings. The actual encoding is usually |
| // specified in the Content-Type header field. |
| @@ -1134,6 +1173,7 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) { |
| string16 disambiguating_query; |
| string16 annotation; |
| std::string suggest_query_params; |
| + std::string deletion_url; |
| if (suggestion_details && (type == "ENTITY") && |
| suggestion_details->GetDictionary(index, &suggestion_detail) && |
| suggestion_detail) { |
| @@ -1142,11 +1182,15 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) { |
| !disambiguating_query.empty()) |
| suggestion = disambiguating_query; |
| suggestion_detail->GetString("q", &suggest_query_params); |
| + } else if (suggestion_details && (type == "PERSONALIZED_QUERY") && |
| + suggestion_details->GetDictionary(index, &suggestion_detail) && |
| + suggestion_detail) { |
| + suggestion_detail->GetString("du", &deletion_url); |
| } |
| // TODO(kochi): Improve calculator suggestion presentation. |
| results->suggest_results.push_back(SuggestResult( |
| suggestion, match_contents, annotation, suggest_query_params, |
| - is_keyword, relevance, true, should_prefetch)); |
| + deletion_url, is_keyword, relevance, true, should_prefetch)); |
| } |
| } |
| @@ -1206,6 +1250,7 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { |
| input_.text(), |
| did_not_accept_default_suggestion, |
| std::string(), |
| + std::string(), |
| &map); |
| } |
| if (!keyword_input_.text().empty()) { |
| @@ -1234,6 +1279,7 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { |
| keyword_input_.text(), |
| did_not_accept_keyword_suggestion, |
| std::string(), |
| + std::string(), |
| &map); |
| } |
| } |
| @@ -1508,6 +1554,7 @@ void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, |
| i->suggestion(), |
| did_not_accept_suggestion, |
| std::string(), |
| + std::string(), |
| map); |
| } |
| UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", |
| @@ -1558,7 +1605,7 @@ SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults( |
| prevent_search_history_inlining); |
| scored_results.push_back( |
| SuggestResult(i->term, string16(), string16(), std::string(), |
| - is_keyword, relevance, false, false)); |
| + std::string(), is_keyword, relevance, false, false)); |
| } |
| // History returns results sorted for us. However, we may have docked some |
| @@ -1597,6 +1644,7 @@ void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, |
| results[i].suggestion(), |
| i, |
| results[i].suggest_query_params(), |
| + results[i].deletion_url(), |
| map); |
| } |
| } |
| @@ -1709,6 +1757,43 @@ int SearchProvider::CalculateRelevanceForHistory( |
| return std::max(0, base_score - score_discount); |
| } |
| +void SearchProvider::DeleteMatch(const AutocompleteMatch& match) { |
| + // TODO(mariakhomenko): Add support for deleting search history suggestions. |
| + DCHECK(match.deletable); |
| + |
| + std::string deletion_url = match.GetAdditionalInfo( |
| + SearchProvider::kDeletionUrlKey); |
| + // Allocate on the heap, class will delete itself when the request is done. |
|
Peter Kasting
2013/11/23 00:08:43
I think the SearchProvider should probably own thi
Maria
2013/11/26 02:36:27
Done.
|
| + SuggestionDeletionHandler* deletionHandler = new SuggestionDeletionHandler(); |
| + deletionHandler->StartRequest(deletion_url, profile_, |
| + base::Bind(&SearchProvider::OnDeletionComplete, base::Unretained(this))); |
| + // Immediately updates the list of matches to show the match was deleted, |
| + // regardless of whether the server request actually succeeds. |
| + DeleteMatchFromMatches(match); |
| +} |
| + |
| +void SearchProvider::OnDeletionComplete(bool success) { |
|
Peter Kasting
2013/11/23 00:08:43
If we check URL validity in AddMatchToMap(), then
Maria
2013/11/26 02:36:27
True, but I thought this may be a more flexible ap
Peter Kasting
2013/11/26 02:46:22
I would say, let's add that capability when it bec
Maria
2013/11/27 02:18:06
Now this callback has another use which is to dele
|
| + if (success) { |
| + UMA_HISTOGRAM_COUNTS("Omnibox.ServerSuggestDelete.Success", 1); |
|
Peter Kasting
2013/11/23 00:08:43
Nit: Is it possible to use ?: to simplify this to
Maria
2013/11/26 02:36:27
I read a bit about this and figured we should be u
|
| + } else { |
| + UMA_HISTOGRAM_COUNTS("Omnibox.ServerSuggestDelete.Failure", 1); |
| + } |
| +} |
| + |
| +void SearchProvider::DeleteMatchFromMatches(const AutocompleteMatch& match) { |
|
Peter Kasting
2013/11/23 00:08:43
The body of this function is akin to the identical
Maria
2013/11/26 02:36:27
It is a similar function, but it's not identical.
Peter Kasting
2013/11/26 02:46:22
Hmm. That actually worries me. With things like
Maria
2013/11/27 02:18:06
Right now the only deletable suggestions in search
|
| + bool found = false; |
| + for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i) { |
| + if (i->contents == match.contents && i->type == match.type) { |
| + found = true; |
| + matches_.erase(i); |
| + break; |
| + } |
| + } |
| + DCHECK(found) << "Asked to delete a search suggestion that isn't in our set " |
| + << "of matches"; |
| + listener_->OnProviderUpdate(true); |
| +} |
| + |
| void SearchProvider::AddMatchToMap(const string16& input_text, |
| int relevance, |
| bool relevance_from_server, |
| @@ -1721,6 +1806,7 @@ void SearchProvider::AddMatchToMap(const string16& input_text, |
| const string16& query_string, |
| int accepted_suggestion, |
| const std::string& suggest_query_params, |
| + const std::string& deletion_url, |
| MatchMap* map) { |
| // On non-mobile, ask the instant controller for the appropriate start margin. |
| // On mobile the start margin is unused, so leave the value as default there. |
| @@ -1753,6 +1839,11 @@ void SearchProvider::AddMatchToMap(const string16& input_text, |
| match.RecordAdditionalInfo(kShouldPrefetchKey, |
| should_prefetch ? kTrue : kFalse); |
| + if (!deletion_url.empty()) { |
| + match.RecordAdditionalInfo(kDeletionUrlKey, deletion_url); |
| + match.deletable = true; |
| + } |
| + |
| // Metadata is needed only for prefetching queries. |
| if (should_prefetch) |
| match.RecordAdditionalInfo(kSuggestMetadataKey, metadata); |