diff options
author | michaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 20:49:42 +0000 |
---|---|---|
committer | michaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 20:49:42 +0000 |
commit | d41e657e56291958031238ec100afdaad65e3ce2 (patch) | |
tree | b8f6a6f5dc97efe0d96ef8bcc5efa77b3d29c28b /chrome/browser/history | |
parent | fccaa13593e4b371bce030c56e5176f0a82d9910 (diff) | |
download | chromium_src-d41e657e56291958031238ec100afdaad65e3ce2.zip chromium_src-d41e657e56291958031238ec100afdaad65e3ce2.tar.gz chromium_src-d41e657e56291958031238ec100afdaad65e3ce2.tar.bz2 |
Completed the code path from AndroidProviderService to HistoryBackend.
- Added AndroidProviderService.
- Added methods in HistoryService and HistoryBackend to support Android
content provider.
- Also fixed a issue in testing_profile.cc.
BUG=
TEST=Added the new tests
Review URL: http://codereview.chromium.org/10217010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135414 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/history')
-rw-r--r-- | chrome/browser/history/android/android_history_provider_service.cc | 222 | ||||
-rw-r--r-- | chrome/browser/history/android/android_history_provider_service.h | 178 | ||||
-rw-r--r-- | chrome/browser/history/android/android_history_provider_service_unittest.cc | 261 | ||||
-rw-r--r-- | chrome/browser/history/history.h | 32 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.cc | 27 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.h | 72 | ||||
-rw-r--r-- | chrome/browser/history/history_backend_android.cc | 183 | ||||
-rw-r--r-- | chrome/browser/history/history_marshaling.h | 4 | ||||
-rw-r--r-- | chrome/browser/history/history_marshaling_android.h | 30 |
9 files changed, 1008 insertions, 1 deletions
diff --git a/chrome/browser/history/android/android_history_provider_service.cc b/chrome/browser/history/android/android_history_provider_service.cc new file mode 100644 index 0000000..76395e4 --- /dev/null +++ b/chrome/browser/history/android/android_history_provider_service.cc @@ -0,0 +1,222 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/history/android/android_history_provider_service.h" + +#include "chrome/browser/history/history.h" +#include "chrome/browser/history/history_backend.h" +#include "chrome/browser/profiles/profile.h" + +using history::HistoryBackend; + +AndroidHistoryProviderService::AndroidHistoryProviderService(Profile* profile) + : profile_(profile) { +} + +AndroidHistoryProviderService::~AndroidHistoryProviderService() { +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::QueryHistoryAndBookmarks( + const std::vector<history::HistoryAndBookmarkRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order, + CancelableRequestConsumerBase* consumer, + const QueryCallback& callback) { + QueryRequest* request = new QueryRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::QueryHistoryAndBookmarks, NULL, request, + projections, selection, selection_args, sort_order); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::UpdateHistoryAndBookmarks( + const history::HistoryAndBookmarkRow& row, + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const UpdateCallback& callback) { + UpdateRequest* request = new UpdateRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::UpdateHistoryAndBookmarks, NULL, request, row, + selection, selection_args); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::DeleteHistoryAndBookmarks( + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const DeleteCallback& callback) { + DeleteRequest* request = new DeleteRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::DeleteHistoryAndBookmarks, NULL, request, + selection, selection_args); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::InsertHistoryAndBookmark( + const history::HistoryAndBookmarkRow& values, + CancelableRequestConsumerBase* consumer, + const InsertCallback& callback) { + InsertRequest* request = new InsertRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::InsertHistoryAndBookmark, NULL, request, values); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::DeleteHistory( + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const DeleteCallback& callback) { + DeleteRequest* request = new DeleteRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::DeleteHistory, NULL, request, selection, + selection_args); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::MoveStatement( + history::AndroidStatement* statement, + int current_pos, + int destination, + CancelableRequestConsumerBase* consumer, + const MoveStatementCallback& callback) { + MoveStatementRequest* request = new MoveStatementRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::MoveStatement, NULL, request, statement, + current_pos, destination); + } else { + request->ForwardResultAsync(request->handle(), current_pos); + } + return request->handle(); +} + +void AndroidHistoryProviderService::CloseStatement( + history::AndroidStatement* statement) { + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->ScheduleAndForget(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::CloseStatement, statement); + } else { + delete statement; + } +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::InsertSearchTerm( + const history::SearchRow& row, + CancelableRequestConsumerBase* consumer, + const InsertCallback& callback) { + InsertRequest* request = new InsertRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::InsertSearchTerm, NULL, request, row); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::UpdateSearchTerms( + const history::SearchRow& row, + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const UpdateCallback& callback) { + UpdateRequest* request = new UpdateRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::UpdateSearchTerms, NULL, request, row, selection, + selection_args); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::DeleteSearchTerms( + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const DeleteCallback& callback) { + DeleteRequest* request = new DeleteRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::DeleteSearchTerms, NULL, request, selection, + selection_args); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} + +AndroidHistoryProviderService::Handle +AndroidHistoryProviderService::QuerySearchTerms( + const std::vector<history::SearchRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order, + CancelableRequestConsumerBase* consumer, + const QueryCallback& callback) { + QueryRequest* request = new QueryRequest(callback); + AddRequest(request, consumer); + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (hs) { + hs->Schedule(HistoryService::PRIORITY_NORMAL, + &HistoryBackend::QuerySearchTerms, NULL, request, projections, + selection, selection_args, sort_order); + } else { + request->ForwardResultAsync(request->handle(), false, 0); + } + return request->handle(); +} diff --git a/chrome/browser/history/android/android_history_provider_service.h b/chrome/browser/history/android/android_history_provider_service.h new file mode 100644 index 0000000..1dca7b5 --- /dev/null +++ b/chrome/browser/history/android/android_history_provider_service.h @@ -0,0 +1,178 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_HISTORY_ANDROID_ANDROID_HISTORY_PROVIDER_SERVICE_H_ +#define CHROME_BROWSER_HISTORY_ANDROID_ANDROID_HISTORY_PROVIDER_SERVICE_H_ + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "chrome/browser/cancelable_request.h" +#include "chrome/browser/history/android/android_history_types.h" +#include "sql/statement.h" + +class Profile; + +// This class provides the methods to communicate with history backend service +// for the Android content provider. +// The methods of this class must run on the UI thread to cooperate with the +// BookmarkModel task posted in the DB thread. +class AndroidHistoryProviderService : public CancelableRequestProvider { + public: + explicit AndroidHistoryProviderService(Profile* profile); + virtual ~AndroidHistoryProviderService(); + + // The callback definitions ------------------------------------------------ + typedef base::Callback<void( + Handle, // handle + bool, // true if the query succeeded. + history::AndroidStatement*)> // the result of query + QueryCallback; + typedef CancelableRequest<QueryCallback> QueryRequest; + + typedef base::Callback<void( + Handle, // handle + bool, // true if the update succeeded. + int)> // the number of row updated. + UpdateCallback; + typedef CancelableRequest<UpdateCallback> UpdateRequest; + + typedef base::Callback<void( + Handle, // handle + bool, // true if the insert succeeded. + int64)> // the id of inserted row. + InsertCallback; + typedef CancelableRequest<InsertCallback> InsertRequest; + + typedef base::Callback<void( + Handle, // handle + bool, // true if the deletion succeeded. + int)> // the number of row deleted. + DeleteCallback; + typedef CancelableRequest<DeleteCallback> DeleteRequest; + + typedef base::Callback<void( + Handle, // handle + int)> // the new position. + MoveStatementCallback; + typedef CancelableRequest<MoveStatementCallback> MoveStatementRequest; + + // History and Bookmarks ---------------------------------------------------- + // + // Runs the given query on history backend, and invokes the |callback| to + // return 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. + Handle QueryHistoryAndBookmarks( + const std::vector<history::HistoryAndBookmarkRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order, + CancelableRequestConsumerBase* consumer, + const QueryCallback& callback); + + // Runs the given update and the number of the row updated is returned to the + // |callback| on success. + // + // |row| is the value to update. + // |selection| is the SQL WHERE clause without 'WHERE'. + // |selection_args| is the arguments for the WHERE clause. + Handle UpdateHistoryAndBookmarks(const history::HistoryAndBookmarkRow& row, + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const UpdateCallback& callback); + + // Deletes the specified rows and invokes the |callback| to return the number + // of row deleted on success. + // + // |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. + Handle DeleteHistoryAndBookmarks(const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const DeleteCallback& callback); + + // Inserts the given values into history backend, and invokes the |callback| + // to return the result. + Handle InsertHistoryAndBookmark(const history::HistoryAndBookmarkRow& values, + CancelableRequestConsumerBase* consumer, + const InsertCallback& callback); + + // Deletes the matched history and invokes |callback| to return the number of + // the row deleted from the |callback|. + Handle DeleteHistory(const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const DeleteCallback& callback); + + // Statement ---------------------------------------------------------------- + // Moves the statement's current row from |current_pos| to |destination| in DB + // thread. The new position is returned to the callback. The result supplied + // the callback is constrained by the number of rows might. + Handle MoveStatement(history::AndroidStatement* statement, + int current_pos, + int destination, + CancelableRequestConsumerBase* consumer, + const MoveStatementCallback& callback); + + // Closes the statement in db thread. The AndroidHistoryProviderService takes + // the ownership of |statement|. + void CloseStatement(history::AndroidStatement* statement); + + // Search term -------------------------------------------------------------- + // Inserts the given values and returns the SearchTermID of the inserted row + // from the |callback| on success. + Handle InsertSearchTerm(const history::SearchRow& row, + CancelableRequestConsumerBase* consumer, + const InsertCallback& callback); + + // Runs the given update and returns the number of the update rows from the + // |callback| on success. + // + // |row| is the value need to update. + // |selection| is the SQL WHERE clause without 'WHERE'. + // |selection_args| is the arguments for WHERE clause. + Handle UpdateSearchTerms(const history::SearchRow& row, + const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const UpdateCallback& callback); + + // Deletes the matched rows and the number of deleted rows is returned from + // the |callback| on success. + // |selection| is the SQL WHERE clause without 'WHERE'. + // |selection_args| is the arguments for WHERE clause. + // + // if |selection| is empty all search be deleted. + Handle DeleteSearchTerms(const std::string& selection, + const std::vector<string16>& selection_args, + CancelableRequestConsumerBase* consumer, + const DeleteCallback& callback); + + // Returns the result of the given query from the |callback|. + // |projections| specifies the result columns, can not be empty, otherwise + // NULL is returned. + // |selection| is the SQL WHERE clause without 'WHERE'. + // |selection_args| is the arguments for WHERE clause. + // |sort_order| the SQL ORDER clause. + Handle QuerySearchTerms( + const std::vector<history::SearchRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order, + CancelableRequestConsumerBase* consumer, + const QueryCallback& callback); + + private: + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(AndroidHistoryProviderService); +}; + +#endif // CHROME_BROWSER_HISTORY_ANDROID_ANDROID_HISTORY_PROVIDER_SERVICE_H_ diff --git a/chrome/browser/history/android/android_history_provider_service_unittest.cc b/chrome/browser/history/android/android_history_provider_service_unittest.cc new file mode 100644 index 0000000..ab3d713 --- /dev/null +++ b/chrome/browser/history/android/android_history_provider_service_unittest.cc @@ -0,0 +1,261 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/history/android/android_history_provider_service.h" + +#include "base/time.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/history/android/android_history_types.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/browser_thread.h" +#include "content/test/test_browser_thread.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +using base::Bind; +using base::Time; +using content::BrowserThread; +using history::AndroidStatement; +using history::HistoryAndBookmarkRow; +using history::SearchRow; + +// The test cases in this file don't intent to test the detail features of +// Android content provider which have been covered by +// android_provider_backend_unittest.cc, instead, they verify the code path to +// AndroidProviderBackend working fine. + +class AndroidHistoryProviderServiceTest : public testing::Test { + public: + AndroidHistoryProviderServiceTest() + : profile_manager_( + static_cast<TestingBrowserProcess*>(g_browser_process)), + ui_thread_(BrowserThread::UI, &message_loop_), + file_thread_(BrowserThread::FILE, &message_loop_) { + } + virtual ~AndroidHistoryProviderServiceTest() { + } + + protected: + virtual void SetUp() OVERRIDE { + // Setup the testing profile, so the bookmark_model_sql_handler could + // get the bookmark model from it. + ASSERT_TRUE(profile_manager_.SetUp()); + // It seems that the name has to be chrome::kInitialProfile, so it + // could be found by ProfileManager::GetLastUsedProfile(). + testing_profile_ = profile_manager_.CreateTestingProfile( + chrome::kInitialProfile); + + testing_profile_->CreateBookmarkModel(true); + testing_profile_->BlockUntilBookmarkModelLoaded(); + testing_profile_->CreateHistoryService(true, false); + service_.reset(new AndroidHistoryProviderService(testing_profile_)); + } + + virtual void TearDown() OVERRIDE { + testing_profile_->DestroyHistoryService(); + profile_manager_.DeleteTestingProfile(chrome::kInitialProfile); + testing_profile_=NULL; + } + + protected: + TestingProfileManager profile_manager_; + MessageLoop message_loop_; + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; + scoped_ptr<AndroidHistoryProviderService> service_; + CancelableRequestConsumer cancelable_consumer_; + TestingProfile* testing_profile_; + + private: + DISALLOW_COPY_AND_ASSIGN(AndroidHistoryProviderServiceTest); +}; + +class CallbackHelper : public base::RefCountedThreadSafe<CallbackHelper> { + public: + CallbackHelper() + : success_(false), + statement_(NULL), + cursor_position_(0), + count_(0) { + } + + bool success() const { + return success_; + } + + AndroidStatement* statement() const { + return statement_; + } + + int cursor_position() const { + return cursor_position_; + } + + int count() const { + return count_; + } + + void OnInserted(AndroidHistoryProviderService::Handle handle, + bool success, + int64 id) { + success_ = success; + MessageLoop::current()->Quit(); + } + + void OnQueryResult(AndroidHistoryProviderService::Handle handle, + bool success, + AndroidStatement* statement) { + success_ = success; + statement_ = statement; + MessageLoop::current()->Quit(); + } + + void OnUpdated(AndroidHistoryProviderService::Handle handle, + bool success, + int count) { + success_ = success; + count_ = count; + MessageLoop::current()->Quit(); + } + + void OnDeleted(AndroidHistoryProviderService::Handle handle, + bool success, + int count) { + success_ = success; + count_ = count; + MessageLoop::current()->Quit(); + } + + void OnStatementMoved(AndroidHistoryProviderService::Handle handle, + int cursor_position) { + cursor_position_ = cursor_position; + MessageLoop::current()->Quit(); + } + + private: + friend class base::RefCountedThreadSafe<CallbackHelper>; + ~CallbackHelper() { + } + + bool success_; + AndroidStatement* statement_; + int cursor_position_; + int count_; + + DISALLOW_COPY_AND_ASSIGN(CallbackHelper); +}; + +TEST_F(AndroidHistoryProviderServiceTest, TestHistoryAndBookmark) { + HistoryAndBookmarkRow row; + row.set_raw_url("http://www.google.com"); + row.set_url(GURL("http://www.google.com")); + + scoped_refptr<CallbackHelper> callback(new CallbackHelper()); + + // Insert a row and verify it succeeded. + service_->InsertHistoryAndBookmark(row, &cancelable_consumer_, + Bind(&CallbackHelper::OnInserted, callback.get())); + + MessageLoop::current()->Run(); + EXPECT_TRUE(callback->success()); + + std::vector<HistoryAndBookmarkRow::ColumnID> projections; + projections.push_back(HistoryAndBookmarkRow::ID); + + // Query the inserted row. + service_->QueryHistoryAndBookmarks(projections, std::string(), + std::vector<string16>(), std::string(), &cancelable_consumer_, + Bind(&CallbackHelper::OnQueryResult, callback.get())); + MessageLoop::current()->Run(); + ASSERT_TRUE(callback->success()); + + // Move the cursor to the begining and verify whether we could get + // the same result. + AndroidStatement* statement = callback->statement(); + service_->MoveStatement(statement, 0, -1, &cancelable_consumer_, + Bind(&CallbackHelper::OnStatementMoved, callback.get())); + MessageLoop::current()->Run(); + EXPECT_EQ(-1, callback->cursor_position()); + EXPECT_TRUE(callback->statement()->statement()->Step()); + EXPECT_FALSE(callback->statement()->statement()->Step()); + service_->CloseStatement(statement); + + // Update the row. + HistoryAndBookmarkRow update_row; + update_row.set_visit_count(3); + service_->UpdateHistoryAndBookmarks(update_row, std::string(), + std::vector<string16>(), &cancelable_consumer_, + Bind(&CallbackHelper::OnUpdated, callback.get())); + MessageLoop::current()->Run(); + EXPECT_TRUE(callback->success()); + EXPECT_EQ(1, callback->count()); + + // Delete the row. + service_->DeleteHistoryAndBookmarks(std::string(), std::vector<string16>(), + &cancelable_consumer_, Bind(&CallbackHelper::OnDeleted, callback.get())); + MessageLoop::current()->Run(); + EXPECT_TRUE(callback->success()); + EXPECT_EQ(1, callback->count()); +} + +TEST_F(AndroidHistoryProviderServiceTest, TestSearchTerm) { + SearchRow search_row; + search_row.set_search_term(UTF8ToUTF16("google")); + search_row.set_url(GURL("http://google.com")); + search_row.set_template_url_id(1); + search_row.set_search_time(Time::Now()); + + scoped_refptr<CallbackHelper> callback(new CallbackHelper()); + + // Insert a row and verify it succeeded. + service_->InsertSearchTerm(search_row, &cancelable_consumer_, + Bind(&CallbackHelper::OnInserted, callback.get())); + + MessageLoop::current()->Run(); + EXPECT_TRUE(callback->success()); + + std::vector<SearchRow::ColumnID> projections; + projections.push_back(SearchRow::ID); + + // Query the inserted row. + service_->QuerySearchTerms(projections, std::string(), + std::vector<string16>(), std::string(), &cancelable_consumer_, + Bind(&CallbackHelper::OnQueryResult, callback.get())); + MessageLoop::current()->Run(); + ASSERT_TRUE(callback->success()); + + // Move the cursor to the begining and verify whether we could get + // the same result. + AndroidStatement* statement = callback->statement(); + service_->MoveStatement(statement, 0, -1, &cancelable_consumer_, + Bind(&CallbackHelper::OnStatementMoved, callback.get())); + MessageLoop::current()->Run(); + EXPECT_EQ(-1, callback->cursor_position()); + EXPECT_TRUE(callback->statement()->statement()->Step()); + EXPECT_FALSE(callback->statement()->statement()->Step()); + service_->CloseStatement(statement); + + // Update the row. + SearchRow update_row; + update_row.set_search_time(Time::Now()); + service_->UpdateSearchTerms(update_row, std::string(), + std::vector<string16>(), &cancelable_consumer_, + Bind(&CallbackHelper::OnUpdated, callback.get())); + MessageLoop::current()->Run(); + EXPECT_TRUE(callback->success()); + EXPECT_EQ(1, callback->count()); + + // Delete the row. + service_->DeleteSearchTerms(std::string(), std::vector<string16>(), + &cancelable_consumer_, Bind(&CallbackHelper::OnDeleted, callback.get())); + MessageLoop::current()->Run(); + EXPECT_TRUE(callback->success()); + EXPECT_EQ(1, callback->count()); +} + +} // namespace diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h index b9c6879..1d76789 100644 --- a/chrome/browser/history/history.h +++ b/chrome/browser/history/history.h @@ -26,6 +26,10 @@ #include "content/public/common/page_transition_types.h" #include "sql/init_status.h" +#if defined(OS_ANDROID) +#include "chrome/browser/history/android/android_history_provider_service.h" +#endif + class BookmarkService; class FilePath; class GURL; @@ -620,6 +624,9 @@ class HistoryService : public CancelableRequestProvider, private: class BackendDelegate; +#if defined(OS_ANDROID) + friend class AndroidHistoryProviderService; +#endif friend class base::RefCountedThreadSafe<HistoryService>; friend class BackendDelegate; friend class FaviconService; @@ -806,6 +813,31 @@ class HistoryService : public CancelableRequestProvider, return request->handle(); } + template<typename BackendFunc, + class RequestType, // Descendant of CancelableRequstBase. + typename ArgA, + typename ArgB, + typename ArgC, + typename ArgD> + Handle Schedule(SchedulePriority priority, + BackendFunc func, // Function to call on the HistoryBackend. + CancelableRequestConsumerBase* consumer, + RequestType* request, + const ArgA& a, + const ArgB& b, + const ArgC& c, + const ArgD& d) { + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); + if (consumer) + AddRequest(request, consumer); + ScheduleTask(priority, + base::Bind(func, history_backend_.get(), + scoped_refptr<RequestType>(request), + a, b, c, d)); + return request->handle(); + } + // ScheduleAndForget --------------------------------------------------------- // // Functions for scheduling operations on the history thread that do not need diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc index 5095ef3..59ad541 100644 --- a/chrome/browser/history/history_backend.cc +++ b/chrome/browser/history/history_backend.cc @@ -36,6 +36,10 @@ #include "grit/generated_resources.h" #include "net/base/registry_controlled_domain.h" +#if defined(OS_ANDROID) +#include "chrome/browser/history/android/android_provider_backend.h" +#endif + using base::Time; using base::TimeDelta; using base::TimeTicks; @@ -217,6 +221,11 @@ HistoryBackend::~HistoryBackend() { DCHECK(!scheduled_commit_) << "Deleting without cleanup"; ReleaseDBTasks(); +#if defined(OS_ANDROID) + // Release AndroidProviderBackend before other objects. + android_provider_backend_.reset(); +#endif + // First close the databases before optionally running the "destroy" task. if (db_.get()) { // Commit the long-running transaction. @@ -241,6 +250,10 @@ HistoryBackend::~HistoryBackend() { DCHECK(backend_destroy_message_loop_); backend_destroy_message_loop_->PostTask(FROM_HERE, backend_destroy_task_); } + +#if defined(OS_ANDROID) + file_util::Delete(GetAndroidCacheFileName(), false); +#endif } void HistoryBackend::Init(const std::string& languages, bool force_fail) { @@ -283,6 +296,12 @@ FilePath HistoryBackend::GetArchivedFileName() const { return history_dir_.Append(chrome::kArchivedHistoryFilename); } +#if defined(OS_ANDROID) +FilePath HistoryBackend::GetAndroidCacheFileName() const { + return history_dir_.Append(chrome::kAndroidCacheFilename); +} +#endif + SegmentID HistoryBackend::GetLastSegmentID(VisitID from_visit) { // Set is used to detect referrer loops. Should not happen, but can // if the database is corrupt. @@ -702,6 +721,14 @@ void HistoryBackend::InitImpl(const std::string& languages) { // Start expiring old stuff. expirer_.StartArchivingOldStuff(TimeDelta::FromDays(kArchiveDaysThreshold)); +#if defined(OS_ANDROID) + if (thumbnail_db_.get()) { + android_provider_backend_.reset(new AndroidProviderBackend( + GetAndroidCacheFileName(), db_.get(), thumbnail_db_.get(), + bookmark_service_, delegate_.get())); + } +#endif + HISTOGRAM_TIMES("History.InitTime", TimeTicks::Now() - beginning_time); } diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h index d4e7fa0..5418764 100644 --- a/chrome/browser/history/history_backend.h +++ b/chrome/browser/history/history_backend.h @@ -34,7 +34,9 @@ struct DownloadPersistentStoreInfo; } namespace history { - +#if defined(OS_ANDROID) +class AndroidProviderBackend; +#endif class CommitLaterTask; class HistoryPublisher; class VisitFilter; @@ -309,6 +311,64 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, const string16& prefix, int max_count); +#if defined(OS_ANDROID) + // Android Provider --------------------------------------------------------- + + // History and bookmarks ---------------------------------------------------- + void InsertHistoryAndBookmark(scoped_refptr<InsertRequest> request, + const HistoryAndBookmarkRow& row); + + void QueryHistoryAndBookmarks( + scoped_refptr<QueryRequest> request, + const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order); + + void UpdateHistoryAndBookmarks(scoped_refptr<UpdateRequest> request, + const HistoryAndBookmarkRow& row, + const std::string& selection, + const std::vector<string16>& selection_args); + + void DeleteHistoryAndBookmarks(scoped_refptr<DeleteRequest> request, + const std::string& selection, + const std::vector<string16>& selection_args); + + void DeleteHistory(scoped_refptr<DeleteRequest> request, + const std::string& selection, + const std::vector<string16>& selection_args); + + // Statement ---------------------------------------------------------------- + // Move the statement's current position. + void MoveStatement(scoped_refptr<MoveStatementRequest> request, + history::AndroidStatement* statement, + int current_pos, + int destination); + + // Close the given statement. The ownership is transfered. + void CloseStatement(AndroidStatement* statement); + + // Search terms ------------------------------------------------------------- + void InsertSearchTerm(scoped_refptr<InsertRequest> request, + const SearchRow& row); + + void UpdateSearchTerms(scoped_refptr<UpdateRequest> request, + const SearchRow& row, + const std::string& selection, + const std::vector<string16> selection_args); + + void DeleteSearchTerms(scoped_refptr<DeleteRequest> request, + const std::string& selection, + const std::vector<string16> selection_args); + + void QuerySearchTerms(scoped_refptr<QueryRequest> request, + const std::vector<SearchRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order); + +#endif // defined(OS_ANDROID) + // Generic operations -------------------------------------------------------- void ProcessDBTask(scoped_refptr<HistoryDBTaskRequest> request); @@ -422,6 +482,11 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, FilePath GetFaviconsFileName() const; FilePath GetArchivedFileName() const; +#if defined(OS_ANDROID) + // Returns the name of android cache database. + FilePath GetAndroidCacheFileName() const; +#endif + class URLQuerier; friend class URLQuerier; @@ -685,6 +750,11 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, // history data from us. Can be NULL if there are no listeners. scoped_ptr<HistoryPublisher> history_publisher_; +#if defined(OS_ANDROID) + // Used to provide the Android ContentProvider APIs. + scoped_ptr<AndroidProviderBackend> android_provider_backend_; +#endif + DISALLOW_COPY_AND_ASSIGN(HistoryBackend); }; diff --git a/chrome/browser/history/history_backend_android.cc b/chrome/browser/history/history_backend_android.cc new file mode 100644 index 0000000..763f70c --- /dev/null +++ b/chrome/browser/history/history_backend_android.cc @@ -0,0 +1,183 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/history/history_backend.h" + +#include "chrome/browser/history/android/android_provider_backend.h" + +namespace history { + +void HistoryBackend::InsertHistoryAndBookmark( + scoped_refptr<InsertRequest> request, + const HistoryAndBookmarkRow& row) { + if (request->canceled()) + return; + + AndroidURLID id = 0; + if (android_provider_backend_.get()) + id = android_provider_backend_->InsertHistoryAndBookmark(row); + + request->ForwardResult(request->handle(), id != 0, id); +} + +void HistoryBackend::QueryHistoryAndBookmarks( + scoped_refptr<QueryRequest> request, + const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order) { + if (request->canceled()) + return; + + AndroidStatement* statement = NULL; + if (android_provider_backend_.get()) { + statement = android_provider_backend_->QueryHistoryAndBookmarks( + projections, selection, selection_args, sort_order); + } + request->ForwardResult(request->handle(), statement, statement); +} + +void HistoryBackend::UpdateHistoryAndBookmarks( + scoped_refptr<UpdateRequest> request, + const HistoryAndBookmarkRow& row, + const std::string& selection, + const std::vector<string16>& selection_args) { + if (request->canceled()) + return; + + int count = 0; + bool result = false; + if (android_provider_backend_.get()) { + result = android_provider_backend_->UpdateHistoryAndBookmarks(row, + selection, selection_args, &count); + } + + request->ForwardResult(request->handle(), result, count); +} + +void HistoryBackend::DeleteHistoryAndBookmarks( + scoped_refptr<DeleteRequest> request, + const std::string& selection, + const std::vector<string16>& selection_args) { + if (request->canceled()) + return; + + int count = 0; + bool result = false; + if (android_provider_backend_.get()) + result = android_provider_backend_->DeleteHistoryAndBookmarks(selection, + selection_args, &count); + + request->ForwardResult(request->handle(), result, count); +} + +void HistoryBackend::DeleteHistory( + scoped_refptr<DeleteRequest> request, + const std::string& selection, + const std::vector<string16>& selection_args) { + if (request->canceled()) + return; + + int count = 0; + bool result = false; + if (android_provider_backend_.get()) { + result = android_provider_backend_->DeleteHistory(selection, selection_args, + &count); + } + request->ForwardResult(request->handle(), result, count); +} + +// Statement ------------------------------------------------------------------- + +void HistoryBackend::MoveStatement( + scoped_refptr<MoveStatementRequest> request, + history::AndroidStatement* statement, + int current_pos, + int destination) { + 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; + } + + request->ForwardResult(request->handle(), cur); +} + +void HistoryBackend::CloseStatement(AndroidStatement* statement) { + delete statement; +} + +// Search Term ----------------------------------------------------------------- + +void HistoryBackend::InsertSearchTerm(scoped_refptr<InsertRequest> request, + const SearchRow& row) { + if (request->canceled()) + return; + + SearchTermID id = 0; + if (android_provider_backend_.get()) + id = android_provider_backend_->InsertSearchTerm(row); + + request->ForwardResult(request->handle(), id != 0, id); +} + +void HistoryBackend::UpdateSearchTerms( + scoped_refptr<UpdateRequest> request, + const SearchRow& row, + const std::string& selection, + const std::vector<string16> selection_args) { + if (request->canceled()) + return; + + int count = 0; + bool result = false; + if (android_provider_backend_.get()) { + result = android_provider_backend_->UpdateSearchTerms(row, selection, + selection_args, &count); + } + request->ForwardResult(request->handle(), result, count); +} + +void HistoryBackend::DeleteSearchTerms( + scoped_refptr<DeleteRequest> request, + const std::string& selection, + const std::vector<string16> selection_args) { + if (request->canceled()) + return; + + int count = 0; + bool result = false; + if (android_provider_backend_.get()) { + result = android_provider_backend_->DeleteSearchTerms(selection, + selection_args, &count); + } + + request->ForwardResult(request->handle(), result, count); +} + +void HistoryBackend::QuerySearchTerms( + scoped_refptr<QueryRequest> request, + const std::vector<SearchRow::ColumnID>& projections, + const std::string& selection, + const std::vector<string16>& selection_args, + const std::string& sort_order) { + if (request->canceled()) + return; + + AndroidStatement* statement = NULL; + if (android_provider_backend_.get()) + statement = android_provider_backend_->QuerySearchTerms(projections, + selection, selection_args, sort_order); + + request->ForwardResult(request->handle(), statement, statement); +} + +} // namespace history diff --git a/chrome/browser/history/history_marshaling.h b/chrome/browser/history/history_marshaling.h index dc91c5e..6200393 100644 --- a/chrome/browser/history/history_marshaling.h +++ b/chrome/browser/history/history_marshaling.h @@ -15,6 +15,10 @@ #include "chrome/browser/history/history.h" #include "chrome/browser/history/page_usage_data.h" +#if defined(OS_ANDROID) +#include "chrome/browser/history/history_marshaling_android.h" +#endif + namespace history { // Querying ------------------------------------------------------------------- diff --git a/chrome/browser/history/history_marshaling_android.h b/chrome/browser/history/history_marshaling_android.h new file mode 100644 index 0000000..2f6fc14 --- /dev/null +++ b/chrome/browser/history/history_marshaling_android.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Data structures for communication between the history service on the main +// thread and the backend on the history thread. + +#ifndef CHROME_BROWSER_HISTORY_HISTORY_MARSHALING_ANDROID_H_ +#define CHROME_BROWSER_HISTORY_HISTORY_MARSHALING_ANDROID_H_ +#pragma once + +#include "chrome/browser/cancelable_request.h" +#include "chrome/browser/history/android/android_history_provider_service.h" + +namespace history { + +typedef CancelableRequest<AndroidHistoryProviderService::InsertCallback> + InsertRequest; +typedef CancelableRequest<AndroidHistoryProviderService::QueryCallback> + QueryRequest; +typedef CancelableRequest<AndroidHistoryProviderService::UpdateCallback> + UpdateRequest; +typedef CancelableRequest<AndroidHistoryProviderService::DeleteCallback> + DeleteRequest; +typedef CancelableRequest<AndroidHistoryProviderService::MoveStatementCallback> + MoveStatementRequest; + +} // namespace history + +#endif // CHROME_BROWSER_HISTORY_HISTORY_MARSHALING_ANDROID_H_ |