Chromium Code Reviews| Index: chrome/browser/history/android/android_history_provider_service.cc |
| diff --git a/chrome/browser/history/android/android_history_provider_service.cc b/chrome/browser/history/android/android_history_provider_service.cc |
| index 149fa5b3540ab89678209b8a657dec67e0838a4d..0e1fa6439a47ad49d3df1211064fe3045b35d9ee 100644 |
| --- a/chrome/browser/history/android/android_history_provider_service.cc |
| +++ b/chrome/browser/history/android/android_history_provider_service.cc |
| @@ -6,12 +6,235 @@ |
| #include "chrome/browser/favicon/favicon_service.h" |
| #include "chrome/browser/favicon/favicon_service_factory.h" |
| +#include "chrome/browser/history/android/android_provider_backend.h" |
| #include "chrome/browser/history/history_backend.h" |
| #include "chrome/browser/history/history_service.h" |
| #include "chrome/browser/history/history_service_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "components/history/core/browser/android/android_history_types.h" |
| +#include "components/history/core/browser/history_db_task.h" |
| -using history::HistoryBackend; |
| +namespace { |
| + |
| +// AndroidProviderTask wraps two callbacks into an HistoryDBTask so that they |
| +// can be passed to HistoryService::ScheduleDBTask. ResultType must be default |
| +// constructible and copyable. |
| +template <typename ResultType> |
| +class AndroidProviderTask : public history::HistoryDBTask { |
| + public: |
| + typedef base::Callback<ResultType(history::AndroidProviderBackend*)> |
| + RequestCallback; |
| + typedef base::Callback<void(ResultType)> ResultCallback; |
| + |
| + AndroidProviderTask(const RequestCallback& request_cb, |
| + const ResultCallback& result_cb) |
| + : request_cb_(request_cb), result_cb_(result_cb), result_(ResultType{}) { |
|
droger
2015/02/18 14:04:01
ResultType{}:
That "(Uniform) Initialization Synta
|
| + DCHECK(!request_cb_.is_null()); |
| + DCHECK(!result_cb_.is_null()); |
| + } |
| + |
| + ~AndroidProviderTask() override {} |
| + |
| + private: |
| + // history::HistoryDBTask implementation. |
| + bool RunOnDBThread(history::HistoryBackend* backend, |
| + history::HistoryDatabase* db) override { |
| + if (backend->android_provider_backend()) |
| + result_ = request_cb_.Run(backend->android_provider_backend()); |
| + return true; |
| + } |
| + |
| + void DoneRunOnMainThread() override { result_cb_.Run(result_); } |
| + |
| + RequestCallback request_cb_; |
| + ResultCallback result_cb_; |
| + ResultType result_; |
| +}; |
| + |
| +// Creates an instance of AndroidProviderTask using the two callback and using |
| +// type deduction. |
| +template <typename ResultType> |
| +scoped_ptr<history::HistoryDBTask> CreateAndroidProviderTask( |
| + const base::Callback<ResultType(history::AndroidProviderBackend*)>& |
| + request_cb, |
| + const base::Callback<void(ResultType)>& result_cb) { |
| + return scoped_ptr<history::HistoryDBTask>( |
| + new AndroidProviderTask<ResultType>(request_cb, result_cb)); |
| +} |
| + |
| +// History and bookmarks ---------------------------------------------------- |
| + |
| +// Inserts the given values into android provider backend. |
| +history::AndroidURLID InsertHistoryAndBookmarkAdapter( |
| + const history::HistoryAndBookmarkRow& row, |
| + history::AndroidProviderBackend* backend) { |
| + return backend->InsertHistoryAndBookmark(row); |
| +} |
| + |
| +// Runs the given query on android provider backend and returns the result. |
| +// |
| +// |projections| is the vector of the result columns. |
| +// |selection| is the SQL WHERE clause without 'WHERE'. |
| +// |selection_args| is the arguments for WHERE clause. |
| +// |sort_order| is the SQL ORDER clause. |
| +history::AndroidStatement* QueryHistoryAndBookmarksAdapter( |
| + const std::vector<history::HistoryAndBookmarkRow::ColumnID>& projections, |
| + const std::string& selection, |
| + const std::vector<base::string16>& selection_args, |
| + const std::string& sort_order, |
| + history::AndroidProviderBackend* backend) { |
| + return backend->QueryHistoryAndBookmarks(projections, selection, |
| + selection_args, sort_order); |
| +} |
| + |
| +// Returns the number of row updated by the update query. |
| +// |
| +// |row| is the value to update. |
| +// |selection| is the SQL WHERE clause without 'WHERE'. |
| +// |selection_args| is the arguments for the WHERE clause. |
| +int UpdateHistoryAndBookmarksAdapter( |
| + const history::HistoryAndBookmarkRow& row, |
| + const std::string& selection, |
| + const std::vector<base::string16>& selection_args, |
| + history::AndroidProviderBackend* backend) { |
| + int count = 0; |
| + backend->UpdateHistoryAndBookmarks(row, selection, selection_args, &count); |
| + return count; |
| +} |
| + |
| +// Deletes the specified rows and returns the number of rows deleted. |
| +// |
| +// |selection| is the SQL WHERE clause without 'WHERE'. |
| +// |selection_args| is the arguments for the WHERE clause. |
| +// |
| +// If |selection| is empty all history and bookmarks are deleted. |
| +int DeleteHistoryAndBookmarksAdapter( |
| + const std::string& selection, |
| + const std::vector<base::string16>& selection_args, |
| + history::AndroidProviderBackend* backend) { |
| + int count = 0; |
| + backend->DeleteHistoryAndBookmarks(selection, selection_args, &count); |
| + return count; |
| +} |
| + |
| +// Deletes the matched history and returns the number of rows deleted. |
| +int DeleteHistoryAdapter(const std::string& selection, |
| + const std::vector<base::string16>& selection_args, |
| + history::AndroidProviderBackend* backend) { |
| + int count = 0; |
| + backend->DeleteHistory(selection, selection_args, &count); |
| + return count; |
| +} |
| + |
| +// Statement ---------------------------------------------------------------- |
| + |
| +// Move the statement's current position. |
| +int MoveStatementAdapter(history::AndroidStatement* statement, |
| + int current_pos, |
| + int destination, |
| + history::AndroidProviderBackend* backend) { |
| + DCHECK_LE(-1, current_pos); |
| + DCHECK_LE(-1, destination); |
| + |
| + int cur = current_pos; |
| + if (current_pos > destination) { |
| + statement->statement()->Reset(false); |
| + cur = -1; |
| + } |
| + for (; cur < destination; ++cur) { |
| + if (!statement->statement()->Step()) |
| + break; |
| + } |
| + |
| + return cur; |
| +} |
| + |
| +// CloseStatementTask delete the passed |statement| in the DB thread (or in the |
| +// UI thread if the HistoryBackend is destroyed before the task is executed). |
| +class CloseStatementTask : public history::HistoryDBTask { |
| + public: |
| + // Close the given statement. The ownership is transfered. |
| + CloseStatementTask(history::AndroidStatement* statement) |
| + : statement_(statement) { |
| + DCHECK(statement_); |
| + } |
| + |
| + ~CloseStatementTask() override { delete statement_; } |
| + |
| + // Returns the cancelable task tracker to use for this task. The task owns it, |
| + // so it can never be cancelled. This is required due to be compatible with |
| + // HistoryService::ScheduleDBTask() interface. |
| + base::CancelableTaskTracker* tracker() { return &tracker_; } |
| + |
| + private: |
| + // history::HistoryDBTask implementation. |
| + bool RunOnDBThread(history::HistoryBackend* backend, |
| + history::HistoryDatabase* db) override { |
| + delete statement_; |
| + statement_ = nullptr; |
| + return true; |
| + } |
| + |
| + void DoneRunOnMainThread() override {} |
| + |
| + history::AndroidStatement* statement_; |
| + base::CancelableTaskTracker tracker_; |
| +}; |
| + |
| +// Search terms ------------------------------------------------------------- |
| + |
| +// Inserts the given values and returns the SearchTermID of the inserted row. |
| +history::SearchTermID InsertSearchTermAdapter( |
| + const history::SearchRow& row, |
| + history::AndroidProviderBackend* backend) { |
| + return backend->InsertSearchTerm(row); |
| +} |
| + |
| +// Returns the number of row updated by the update query. |
| +// |
| +// |row| is the value to update. |
| +// |selection| is the SQL WHERE clause without 'WHERE'. |
| +// |selection_args| is the arguments for the WHERE clause. |
| +int UpdateSearchTermsAdapter(const history::SearchRow& row, |
| + const std::string& selection, |
| + const std::vector<base::string16> selection_args, |
| + history::AndroidProviderBackend* backend) { |
| + int count = 0; |
| + backend->UpdateSearchTerms(row, selection, selection_args, &count); |
| + return count; |
| +} |
| + |
| +// Deletes the matched rows and returns the number of deleted rows. |
| +// |
| +// |selection| is the SQL WHERE clause without 'WHERE'. |
| +// |selection_args| is the arguments for WHERE clause. |
| +// |
| +// If |selection| is empty all search terms will be deleted. |
| +int DeleteSearchTermsAdapter(const std::string& selection, |
| + const std::vector<base::string16> selection_args, |
| + history::AndroidProviderBackend* backend) { |
| + int count = 0; |
| + backend->DeleteSearchTerms(selection, selection_args, &count); |
| + return count; |
| +} |
| + |
| +// Returns the result of the given query. |
| +// |
| +// |projections| specifies the result columns. |
| +// |selection| is the SQL WHERE clause without 'WHERE'. |
| +// |selection_args| is the arguments for WHERE clause. |
| +// |sort_order| is the SQL ORDER clause. |
| +history::AndroidStatement* QuerySearchTermsAdapter( |
| + const std::vector<history::SearchRow::ColumnID>& projections, |
| + const std::string& selection, |
| + const std::vector<base::string16>& selection_args, |
| + const std::string& sort_order, |
| + history::AndroidProviderBackend* backend) { |
| + return backend->QuerySearchTerms(projections, selection, selection_args, |
| + sort_order); |
| +} |
| + |
| +} // namespace |
| AndroidHistoryProviderService::AndroidHistoryProviderService(Profile* profile) |
| : profile_(profile) { |
| @@ -30,23 +253,16 @@ AndroidHistoryProviderService::QueryHistoryAndBookmarks( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::QueryHistoryAndBookmarks, |
| - hs->history_backend_.get(), |
| - projections, |
| - selection, |
| - selection_args, |
| - sort_order), |
| - callback); |
| - } else { |
| - callback.Run(NULL); |
| + if (!hs) { |
| + callback.Run(nullptr); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask( |
| + base::Bind(&QueryHistoryAndBookmarksAdapter, projections, selection, |
| + selection_args, sort_order), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -58,22 +274,15 @@ AndroidHistoryProviderService::UpdateHistoryAndBookmarks( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::UpdateHistoryAndBookmarks, |
| - hs->history_backend_.get(), |
| - row, |
| - selection, |
| - selection_args), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask(base::Bind(&UpdateHistoryAndBookmarksAdapter, |
| + row, selection, selection_args), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -84,21 +293,15 @@ AndroidHistoryProviderService::DeleteHistoryAndBookmarks( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::DeleteHistoryAndBookmarks, |
| - hs->history_backend_.get(), |
| - selection, |
| - selection_args), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask(base::Bind(&DeleteHistoryAndBookmarksAdapter, |
| + selection, selection_args), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -108,20 +311,14 @@ AndroidHistoryProviderService::InsertHistoryAndBookmark( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::InsertHistoryAndBookmark, |
| - hs->history_backend_.get(), |
| - values), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask( |
| + base::Bind(&InsertHistoryAndBookmarkAdapter, values), callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -132,21 +329,15 @@ AndroidHistoryProviderService::DeleteHistory( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::DeleteHistory, |
| - hs->history_backend_.get(), |
| - selection, |
| - selection_args), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask( |
| + base::Bind(&DeleteHistoryAdapter, selection, selection_args), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -158,35 +349,28 @@ AndroidHistoryProviderService::MoveStatement( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::MoveStatement, |
| - hs->history_backend_.get(), |
| - statement, |
| - current_pos, |
| - destination), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(current_pos); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask(base::Bind(&MoveStatementAdapter, statement, |
| + current_pos, destination), |
| + callback), |
| + tracker); |
| } |
| void AndroidHistoryProviderService::CloseStatement( |
| history::AndroidStatement* statement) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - hs->ScheduleTask(HistoryService::PRIORITY_NORMAL, |
| - base::Bind(&HistoryBackend::CloseStatement, |
| - hs->history_backend_.get(), statement)); |
| - } else { |
| + if (!hs) { |
| delete statement; |
| + return; |
| } |
| + scoped_ptr<CloseStatementTask> task(new CloseStatementTask(statement)); |
| + base::CancelableTaskTracker* tracker = task->tracker(); |
| + hs->ScheduleDBTask(task.Pass(), tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -196,19 +380,14 @@ AndroidHistoryProviderService::InsertSearchTerm( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind( |
| - &HistoryBackend::InsertSearchTerm, hs->history_backend_.get(), row), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask(base::Bind(&InsertSearchTermAdapter, row), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -220,22 +399,15 @@ AndroidHistoryProviderService::UpdateSearchTerms( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::UpdateSearchTerms, |
| - hs->history_backend_.get(), |
| - row, |
| - selection, |
| - selection_args), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask( |
| + base::Bind(&UpdateSearchTermsAdapter, row, selection, selection_args), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -246,21 +418,15 @@ AndroidHistoryProviderService::DeleteSearchTerms( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::DeleteSearchTerms, |
| - hs->history_backend_.get(), |
| - selection, |
| - selection_args), |
| - callback); |
| - } else { |
| + if (!hs) { |
| callback.Run(0); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask( |
| + base::Bind(&DeleteSearchTermsAdapter, selection, selection_args), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |
| @@ -273,23 +439,16 @@ AndroidHistoryProviderService::QuerySearchTerms( |
| base::CancelableTaskTracker* tracker) { |
| HistoryService* hs = HistoryServiceFactory::GetForProfile( |
| profile_, ServiceAccessType::EXPLICIT_ACCESS); |
| - if (hs) { |
| - DCHECK(hs->thread_) << "History service being called after cleanup"; |
| - DCHECK(hs->thread_checker_.CalledOnValidThread()); |
| - return tracker->PostTaskAndReplyWithResult( |
| - hs->thread_->message_loop_proxy().get(), |
| - FROM_HERE, |
| - base::Bind(&HistoryBackend::QuerySearchTerms, |
| - hs->history_backend_.get(), |
| - projections, |
| - selection, |
| - selection_args, |
| - sort_order), |
| - callback); |
| - } else { |
| - callback.Run(NULL); |
| + if (!hs) { |
| + callback.Run(nullptr); |
| return base::CancelableTaskTracker::kBadTaskId; |
| } |
| + return hs->ScheduleDBTask( |
| + CreateAndroidProviderTask( |
| + base::Bind(&QuerySearchTermsAdapter, projections, selection, |
| + selection_args, sort_order), |
| + callback), |
| + tracker); |
| } |
| base::CancelableTaskTracker::TaskId |