Index: chrome/browser/autocomplete/search_provider.cc |
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc |
index 4517eb74e7b7db690de13f25201a28b9044c40a8..2c2f4a7473bf85fa1428aca5153dbeefde400511 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,50 @@ bool SearchProvider::Results::HasServerProvidedScores() const { |
} |
+// SearchProvider::SuggestionDeletionHandler --------------------------------- |
+SearchProvider::SuggestionDeletionHandler::SuggestionDeletionHandler() { |
+}; |
+ |
+SearchProvider::SuggestionDeletionHandler::~SuggestionDeletionHandler() { |
+}; |
+ |
+void SearchProvider::SuggestionDeletionHandler::StartRequest( |
+ const std::string& deletion_url, Profile* profile, |
+ const base::Callback<void(bool)>& callback) { |
+ callback_ = callback; |
+ GURL url = GURL(deletion_url); |
+ if (url.is_valid()) { |
+ 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; |
+ callback_.Run(was_deletion_success); |
+}; |
+ |
// 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 +675,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 +1172,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 +1181,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)); |
} |
} |
@@ -1196,6 +1239,7 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { |
input_.text(), |
did_not_accept_default_suggestion, |
std::string(), |
+ std::string(), |
&map); |
} |
if (!keyword_input_.text().empty()) { |
@@ -1224,6 +1268,7 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { |
keyword_input_.text(), |
did_not_accept_keyword_suggestion, |
std::string(), |
+ std::string(), |
&map); |
} |
} |
@@ -1498,6 +1543,7 @@ void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, |
i->suggestion(), |
did_not_accept_suggestion, |
std::string(), |
+ std::string(), |
map); |
} |
UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", |
@@ -1548,7 +1594,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 |
@@ -1587,6 +1633,7 @@ void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, |
results[i].suggestion(), |
i, |
results[i].suggest_query_params(), |
+ results[i].deletion_url(), |
map); |
} |
} |
@@ -1699,6 +1746,42 @@ int SearchProvider::CalculateRelevanceForHistory( |
return std::max(0, base_score - score_discount); |
} |
+void SearchProvider::DeleteMatch(const AutocompleteMatch& match) { |
+ DCHECK(match.deletable); |
Anuj
2013/11/21 17:27:52
This deletes only the server provided suggestions.
Maria
2013/11/21 19:38:31
Done.
|
+ |
+ std::string deletion_url = match.GetAdditionalInfo( |
+ SearchProvider::kDeletionUrlKey); |
+ deletion_handler_.reset(new SuggestionDeletionHandler()); |
+ deletion_handler_.get()->StartRequest(deletion_url, profile_, |
Anuj
2013/11/21 17:27:52
Use deletion_handler_->StartRequest. -> is pass-th
Maria
2013/11/21 19:38:31
Done.
|
+ 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) { |
+ if (success) { |
+ UMA_HISTOGRAM_COUNTS("Omnibox.PsuggestDelete.Success", 1); |
Anuj
2013/11/21 17:27:52
Not sure about mentioning this event as "PsuggestD
Maria
2013/11/21 19:38:31
Done.
|
+ } else { |
+ UMA_HISTOGRAM_COUNTS("Omnibox.PsuggestDelete.Failure", 1); |
+ } |
+ deletion_handler_.reset(NULL); |
Anuj
2013/11/21 17:27:52
Doesn't this create race? What if I try to delete
Maria
2013/11/21 19:38:31
I think you are right. Trying a new memory managem
|
+} |
+ |
+void SearchProvider::DeleteMatchFromMatches(const AutocompleteMatch& match) { |
+ 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, |
@@ -1711,6 +1794,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. |
@@ -1743,6 +1827,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; |
Anuj
2013/11/21 17:27:52
Add a TODO about marking search-history suggestion
Maria
2013/11/21 19:38:31
I think when we implement it, we would have to do
|
+ } |
+ |
// Metadata is needed only for prefetching queries. |
if (should_prefetch) |
match.RecordAdditionalInfo(kSuggestMetadataKey, metadata); |