summaryrefslogtreecommitdiffstats
path: root/chrome/browser/history
diff options
context:
space:
mode:
authormichaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 20:49:42 +0000
committermichaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 20:49:42 +0000
commitd41e657e56291958031238ec100afdaad65e3ce2 (patch)
treeb8f6a6f5dc97efe0d96ef8bcc5efa77b3d29c28b /chrome/browser/history
parentfccaa13593e4b371bce030c56e5176f0a82d9910 (diff)
downloadchromium_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.cc222
-rw-r--r--chrome/browser/history/android/android_history_provider_service.h178
-rw-r--r--chrome/browser/history/android/android_history_provider_service_unittest.cc261
-rw-r--r--chrome/browser/history/history.h32
-rw-r--r--chrome/browser/history/history_backend.cc27
-rw-r--r--chrome/browser/history/history_backend.h72
-rw-r--r--chrome/browser/history/history_backend_android.cc183
-rw-r--r--chrome/browser/history/history_marshaling.h4
-rw-r--r--chrome/browser/history/history_marshaling_android.h30
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_