diff options
author | dubroy@chromium.org <dubroy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-23 09:14:42 +0000 |
---|---|---|
committer | dubroy@chromium.org <dubroy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-23 09:14:42 +0000 |
commit | 54da54383e22fc77955a5df778b78d085af7773f (patch) | |
tree | 62fe9d7913056cb4fd8bfc6bf0a492a758a81778 | |
parent | 94fb51044f14d5a2c97bbdebd9d8f4f6a1c05ff9 (diff) | |
download | chromium_src-54da54383e22fc77955a5df778b78d085af7773f.zip chromium_src-54da54383e22fc77955a5df778b78d085af7773f.tar.gz chromium_src-54da54383e22fc77955a5df778b78d085af7773f.tar.bz2 |
History: Add support for deleting synced history entries from the server.
When history sync is enabled, this adds support for deleting synced
visits from the server in the same way as local visits can be deleted.
BUG=170957
Review URL: https://codereview.chromium.org/12022028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178273 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/history/web_history_service.cc | 128 | ||||
-rw-r--r-- | chrome/browser/history/web_history_service.h | 12 | ||||
-rw-r--r-- | chrome/browser/ui/webui/history_ui.cc | 24 | ||||
-rw-r--r-- | chrome/browser/ui/webui/history_ui.h | 8 |
4 files changed, 144 insertions, 28 deletions
diff --git a/chrome/browser/history/web_history_service.cc b/chrome/browser/history/web_history_service.cc index fc4882e..42d177c 100644 --- a/chrome/browser/history/web_history_service.cc +++ b/chrome/browser/history/web_history_service.cc @@ -4,7 +4,10 @@ #include "chrome/browser/history/web_history_service.h" +#include "base/bind.h" #include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/string_number_conversions.h" #include "base/values.h" #include "chrome/browser/signin/oauth2_token_service.h" #include "chrome/browser/signin/oauth2_token_service_factory.h" @@ -23,9 +26,14 @@ namespace { const char kHistoryOAuthScope[] = "https://www.googleapis.com/auth/chromesync"; -const char kHistoryGetHistoryUrl[] = +const char kHistoryQueryHistoryUrl[] = "https://history.google.com/history/api/lookup?client=chrome"; +const char kHistoryDeleteHistoryUrl[] = + "https://history.google.com/history/api/delete?client=chrome"; + +const char kPostDataMimeType[] = "text/plain"; + // The maximum number of retries for the URLFetcher requests. const size_t kMaxRetries = 1; @@ -36,13 +44,25 @@ class RequestImpl : public WebHistoryService::Request, virtual ~RequestImpl() { } + // Returns the response code received from the server, which will only be + // valid if the request succeeded. + int response_code() { return response_code_; } + + // Returns the contents of the response body received from the server. + const std::string& response_body() { return response_body_; } + private: friend class history::WebHistoryService; + typedef base::Callback<void(Request*, bool)> CompletionCallback; + RequestImpl(Profile* profile, const std::string& url, - const WebHistoryService::QueryWebHistoryCallback& callback) - : profile_(profile), url_(GURL(url)), query_history_callback_(callback) { + const CompletionCallback& callback) + : profile_(profile), + url_(GURL(url)), + response_code_(0), + callback_(callback) { } // Tells the request to do its thang. @@ -58,20 +78,10 @@ class RequestImpl : public WebHistoryService::Request, // content::URLFetcherDelegate interface. virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { DCHECK_EQ(source, url_fetcher_.get()); - std::string result_body; - int response_code = url_fetcher_->GetResponseCode(); - url_fetcher_->GetResponseAsString(&result_body); + response_code_ = url_fetcher_->GetResponseCode(); + url_fetcher_->GetResponseAsString(&response_body_); url_fetcher_.reset(); - - if (response_code == net::HTTP_OK) { - scoped_ptr<base::Value> value(base::JSONReader::Read(result_body)); - if (value.get() && value->IsType(base::Value::TYPE_DICTIONARY)) { - query_history_callback_.Run(this, - static_cast<DictionaryValue*>(value.get())); - return; - } - } - query_history_callback_.Run(this, NULL); + callback_.Run(this, true); } // OAuth2TokenService::Consumer interface. @@ -92,43 +102,74 @@ class RequestImpl : public WebHistoryService::Request, const GoogleServiceAuthError& error) OVERRIDE { token_request_.reset(); LOG(WARNING) << "Failed to get OAuth token: " << error.ToString(); - query_history_callback_.Run(this, NULL); + callback_.Run(this, false); } // Helper for creating a new URLFetcher for the API request. net::URLFetcher* CreateUrlFetcher(const std::string& access_token) { + net::URLFetcher::RequestType request_type = post_data_.empty() ? + net::URLFetcher::GET : net::URLFetcher::POST; net::URLFetcher* fetcher = net::URLFetcher::Create( - url_, net::URLFetcher::GET, this); + url_, request_type, this); fetcher->SetRequestContext(profile_->GetRequestContext()); fetcher->SetMaxRetriesOn5xx(kMaxRetries); fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); fetcher->AddExtraRequestHeader("Authorization: Bearer " + access_token); + if (request_type == net::URLFetcher::POST) + fetcher->SetUploadData(kPostDataMimeType, post_data_); return fetcher; } + void set_post_data(const std::string& post_data) { + post_data_ = post_data; + } + Profile* profile_; // The URL of the API endpoint. GURL url_; + // POST data to be sent with the request (may be empty). + std::string post_data_; + // The OAuth2 access token request. scoped_ptr<OAuth2TokenService::Request> token_request_; // Handles the actual API requests after the OAuth token is acquired. scoped_ptr<net::URLFetcher> url_fetcher_; - // The callback to execute when the query is complete, whether successful - // or not. - WebHistoryService::QueryWebHistoryCallback query_history_callback_; + // Holds the response code received from the server. + int response_code_; + + // Holds the response body received from the server. + std::string response_body_; + + // The callback to execute when the query is complete. + CompletionCallback callback_; }; +// Called when a query to web history has completed, successfully or not. +void QueryHistoryCompletionCallback( + const WebHistoryService::QueryWebHistoryCallback& callback, + WebHistoryService::Request* request, + bool success) { + RequestImpl* request_impl = static_cast<RequestImpl*>(request); + if (success && request_impl->response_code() == net::HTTP_OK) { + scoped_ptr<base::Value> value( + base::JSONReader::Read(request_impl->response_body())); + if (value.get() && value->IsType(base::Value::TYPE_DICTIONARY)) + callback.Run(request, static_cast<DictionaryValue*>(value.get())); + } + callback.Run(request, NULL); +} + } // namespace -WebHistoryService::Request::~Request() { +WebHistoryService::Request::Request() { } -WebHistoryService::Request::Request() { +WebHistoryService::Request::~Request() { } WebHistoryService::WebHistoryService(Profile* profile) @@ -142,8 +183,47 @@ scoped_ptr<WebHistoryService::Request> WebHistoryService::QueryHistory( const string16& text_query, const QueryOptions& options, const WebHistoryService::QueryWebHistoryCallback& callback) { + // Wrap the original callback into a generic completion callback. + RequestImpl::CompletionCallback completion_callback = base::Bind( + &QueryHistoryCompletionCallback, callback); + + scoped_ptr<RequestImpl> request( + new RequestImpl(profile_, kHistoryQueryHistoryUrl, completion_callback)); + request->Start(); + return request.PassAs<Request>(); +} + +scoped_ptr<WebHistoryService::Request> WebHistoryService::ExpireHistoryBetween( + const std::set<GURL>& urls, + base::Time begin_time, + base::Time end_time, + const WebHistoryService::ExpireWebHistoryCallback& callback) { + + // Determine the timestamps representing the beginning and end of the day. + std::string min_timestamp(base::Int64ToString( + (begin_time - base::Time::FromJsTime(0)).InMicroseconds())); + std::string max_timestamp(base::Int64ToString( + (end_time - base::Time::FromJsTime(0)).InMicroseconds())); + + DictionaryValue delete_request; + ListValue* deletions = new ListValue; + delete_request.Set("del", deletions); + + for (std::set<GURL>::const_iterator it = urls.begin(); + it != urls.end(); ++it) { + DictionaryValue* deletion = new DictionaryValue; + deletion->SetString("type", "CHROME_HISTORY"); + deletion->SetString("url", it->spec()); + deletion->SetString("min_timestamp_usec", min_timestamp); + deletion->SetString("max_timestamp_usec", max_timestamp); + deletions->Append(deletion); + } + std::string post_data; + base::JSONWriter::Write(&delete_request, &post_data); + scoped_ptr<RequestImpl> request( - new RequestImpl(profile_, kHistoryGetHistoryUrl, callback)); + new RequestImpl(profile_, kHistoryDeleteHistoryUrl, callback)); + request->set_post_data(post_data); request->Start(); return request.PassAs<Request>(); } diff --git a/chrome/browser/history/web_history_service.h b/chrome/browser/history/web_history_service.h index c3321a6..039ab14 100644 --- a/chrome/browser/history/web_history_service.h +++ b/chrome/browser/history/web_history_service.h @@ -30,6 +30,7 @@ class WebHistoryService : public ProfileKeyedService { class Request { public: virtual ~Request(); + protected: Request(); }; @@ -40,6 +41,9 @@ class WebHistoryService : public ProfileKeyedService { typedef base::Callback<void(Request*, const DictionaryValue*)> QueryWebHistoryCallback; + typedef base::Callback<void(Request*, bool success)> + ExpireWebHistoryCallback; + explicit WebHistoryService(Profile* profile); virtual ~WebHistoryService(); @@ -54,6 +58,14 @@ class WebHistoryService : public ProfileKeyedService { const QueryOptions& options, const QueryWebHistoryCallback& callback); + // Deletes all visits to the given set of URLs between |begin_time| and + // |end_time|. + scoped_ptr<Request> ExpireHistoryBetween( + const std::set<GURL>& restrict_urls, + base::Time begin_time, + base::Time end_time, + const ExpireWebHistoryCallback& callback); + private: Profile* profile_; diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc index 75c1e50..88f5624 100644 --- a/chrome/browser/ui/webui/history_ui.cc +++ b/chrome/browser/ui/webui/history_ui.cc @@ -291,10 +291,7 @@ void BrowsingHistoryHandler::HandleRemoveURLsOnOneDay(const ListValue* args) { web_ui()->CallJavascriptFunction("deleteFailed"); return; } - base::Time::Exploded exploded; - base::Time::FromJsTime(visit_time).LocalExplode(&exploded); - exploded.hour = exploded.minute = exploded.second = exploded.millisecond = 0; - base::Time begin_time = base::Time::FromLocalExploded(exploded); + base::Time begin_time = base::Time::FromJsTime(visit_time).LocalMidnight(); base::Time end_time = begin_time + base::TimeDelta::FromDays(1); // Get URLs. @@ -311,6 +308,7 @@ void BrowsingHistoryHandler::HandleRemoveURLsOnOneDay(const ListValue* args) { urls_to_be_deleted_.insert(GURL(string16_value)); } + Profile* profile = Profile::FromWebUI(web_ui()); HistoryService* hs = HistoryServiceFactory::GetForProfile( Profile::FromWebUI(web_ui()), Profile::EXPLICIT_ACCESS); hs->ExpireHistoryBetween( @@ -318,6 +316,17 @@ void BrowsingHistoryHandler::HandleRemoveURLsOnOneDay(const ListValue* args) { base::Bind(&BrowsingHistoryHandler::RemoveComplete, base::Unretained(this)), &delete_task_tracker_); + + history::WebHistoryService* web_history = + WebHistoryServiceFactory::GetForProfile(profile); + if (web_history) { + web_history_delete_request_ = web_history->ExpireHistoryBetween( + urls_to_be_deleted_, + begin_time, + end_time, + base::Bind(&BrowsingHistoryHandler::RemoveWebHistoryComplete, + base::Unretained(this))); + } } void BrowsingHistoryHandler::HandleClearBrowsingData(const ListValue* args) { @@ -477,6 +486,13 @@ void BrowsingHistoryHandler::RemoveComplete() { web_ui()->CallJavascriptFunction("deleteComplete"); } +void BrowsingHistoryHandler::RemoveWebHistoryComplete( + history::WebHistoryService::Request* request, bool success) { + // Notify the page that the deletion request is complete. + base::FundamentalValue success_value(success); + web_ui()->CallJavascriptFunction("webHistoryDeleteComplete", success_value); +} + // Helper function for Observe that determines if there are any differences // between the URLs noticed for deletion and the ones we are expecting. static bool DeletionsDiffer(const history::URLRows& deleted_rows, diff --git a/chrome/browser/ui/webui/history_ui.h b/chrome/browser/ui/webui/history_ui.h index 5ee6cde..6e3acb7 100644 --- a/chrome/browser/ui/webui/history_ui.h +++ b/chrome/browser/ui/webui/history_ui.h @@ -77,6 +77,10 @@ class BrowsingHistoryHandler : public content::WebUIMessageHandler, // Callback from the history system when visits were deleted. void RemoveComplete(); + // Callback from history server when visits were deleted. + void RemoveWebHistoryComplete(history::WebHistoryService::Request* request, + bool success); + bool ExtractIntegerValueAtIndex( const base::ListValue* value, int index, int* out_int); @@ -95,6 +99,10 @@ class BrowsingHistoryHandler : public content::WebUIMessageHandler, // Deleting the request will cancel it. scoped_ptr<history::WebHistoryService::Request> web_history_request_; + // The currently-executing delete request for synced history. + // Deleting the request will cancel it. + scoped_ptr<history::WebHistoryService::Request> web_history_delete_request_; + // Tracker for delete requests to the history service. CancelableTaskTracker delete_task_tracker_; |