blob: 77a7890ddc8d7edf04c25df5a6f747d78ece7eb4 [file] [log] [blame]
// 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 <utility>
#include "base/bind.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/android/android_provider_backend.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/favicon/core/favicon_service.h"
#include "components/history/core/browser/android/android_history_types.h"
#include "components/history/core/browser/history_backend.h"
#include "components/history/core/browser/history_db_task.h"
#include "components/history/core/browser/history_service.h"
namespace {
// AndroidProviderTask wraps two callbacks into an HistoryDBTask so that they
// can be passed to HistoryService::ScheduleDBTask. ResultType must be zero
// constructible (i.e. ResultType(0) should build an initialized default value)
// 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_(0) {
DCHECK(!request_cb_.is_null());
DCHECK(!result_cb_.is_null());
}
~AndroidProviderTask() override {}
private:
// history::HistoryDBTask implementation.
bool RunOnDBThread(history::HistoryBackend* history_backend,
history::HistoryDatabase* db) override {
history::AndroidProviderBackend* android_provider_backend =
history::AndroidProviderBackend::FromHistoryBackend(history_backend);
if (android_provider_backend)
result_ = request_cb_.Run(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>
std::unique_ptr<history::HistoryDBTask> CreateAndroidProviderTask(
const base::Callback<ResultType(history::AndroidProviderBackend*)>&
request_cb,
const base::Callback<void(ResultType)>& result_cb) {
return std::unique_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.
explicit 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) {
}
AndroidHistoryProviderService::~AndroidHistoryProviderService() {
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::QueryHistoryAndBookmarks(
const std::vector<history::HistoryAndBookmarkRow::ColumnID>& projections,
const std::string& selection,
const std::vector<base::string16>& selection_args,
const std::string& sort_order,
const QueryCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(nullptr);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(
base::Bind(&QueryHistoryAndBookmarksAdapter, projections, selection,
selection_args, sort_order),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::UpdateHistoryAndBookmarks(
const history::HistoryAndBookmarkRow& row,
const std::string& selection,
const std::vector<base::string16>& selection_args,
const UpdateCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(base::Bind(&UpdateHistoryAndBookmarksAdapter,
row, selection, selection_args),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::DeleteHistoryAndBookmarks(
const std::string& selection,
const std::vector<base::string16>& selection_args,
const DeleteCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(base::Bind(&DeleteHistoryAndBookmarksAdapter,
selection, selection_args),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::InsertHistoryAndBookmark(
const history::HistoryAndBookmarkRow& values,
const InsertCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(
base::Bind(&InsertHistoryAndBookmarkAdapter, values), callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::DeleteHistory(
const std::string& selection,
const std::vector<base::string16>& selection_args,
const DeleteCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(
base::Bind(&DeleteHistoryAdapter, selection, selection_args),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::MoveStatement(
history::AndroidStatement* statement,
int current_pos,
int destination,
const MoveStatementCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(current_pos);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(base::Bind(&MoveStatementAdapter, statement,
current_pos, destination),
callback),
tracker);
}
void AndroidHistoryProviderService::CloseStatement(
history::AndroidStatement* statement) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
delete statement;
return;
}
std::unique_ptr<CloseStatementTask> task(new CloseStatementTask(statement));
base::CancelableTaskTracker* tracker = task->tracker();
hs->ScheduleDBTask(FROM_HERE, std::move(task), tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::InsertSearchTerm(
const history::SearchRow& row,
const InsertCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(base::Bind(&InsertSearchTermAdapter, row),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::UpdateSearchTerms(
const history::SearchRow& row,
const std::string& selection,
const std::vector<base::string16>& selection_args,
const UpdateCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(
base::Bind(&UpdateSearchTermsAdapter, row, selection, selection_args),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::DeleteSearchTerms(
const std::string& selection,
const std::vector<base::string16>& selection_args,
const DeleteCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(0);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(
base::Bind(&DeleteSearchTermsAdapter, selection, selection_args),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::QuerySearchTerms(
const std::vector<history::SearchRow::ColumnID>& projections,
const std::string& selection,
const std::vector<base::string16>& selection_args,
const std::string& sort_order,
const QueryCallback& callback,
base::CancelableTaskTracker* tracker) {
history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
if (!hs) {
callback.Run(nullptr);
return base::CancelableTaskTracker::kBadTaskId;
}
return hs->ScheduleDBTask(
FROM_HERE,
CreateAndroidProviderTask(
base::Bind(&QuerySearchTermsAdapter, projections, selection,
selection_args, sort_order),
callback),
tracker);
}
base::CancelableTaskTracker::TaskId
AndroidHistoryProviderService::GetLargestRawFaviconForID(
favicon_base::FaviconID favicon_id,
const favicon_base::FaviconRawBitmapCallback& callback,
base::CancelableTaskTracker* tracker) {
favicon::FaviconService* fs = FaviconServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
DCHECK(fs);
return fs->GetLargestRawFaviconForID(favicon_id, callback, tracker);
}