blob: 0e09d170ef0c8b360415cbbef13ab1c022cdb8c5 [file] [log] [blame]
// Copyright 2019 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/media/history/media_history_store.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h"
#include "chrome/browser/media/feeds/media_feeds_service.h"
#include "chrome/browser/media/history/media_history_feed_items_table.h"
#include "chrome/browser/media/history/media_history_feeds_table.h"
#include "chrome/browser/media/history/media_history_images_table.h"
#include "chrome/browser/media/history/media_history_origin_table.h"
#include "chrome/browser/media/history/media_history_playback_table.h"
#include "chrome/browser/media/history/media_history_session_images_table.h"
#include "chrome/browser/media/history/media_history_session_table.h"
#include "content/public/browser/media_player_watch_time.h"
#include "services/media_session/public/cpp/media_image.h"
#include "services/media_session/public/cpp/media_position.h"
#include "sql/statement.h"
#include "url/origin.h"
namespace {
constexpr int kCurrentVersionNumber = 1;
constexpr int kCompatibleVersionNumber = 1;
constexpr base::FilePath::CharType kMediaHistoryDatabaseName[] =
FILE_PATH_LITERAL("Media History");
} // namespace
int GetCurrentVersion() {
return kCurrentVersionNumber;
}
namespace media_history {
// Refcounted as it is created, initialized and destroyed on a different thread
// from the DB sequence provided to the constructor of this class that is
// required for all methods performing database access.
class MediaHistoryStoreInternal
: public base::RefCountedThreadSafe<MediaHistoryStoreInternal> {
private:
friend class base::RefCountedThreadSafe<MediaHistoryStoreInternal>;
friend class MediaHistoryStore;
explicit MediaHistoryStoreInternal(
Profile* profile,
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner);
virtual ~MediaHistoryStoreInternal();
// Opens the database file from the |db_path|. Separated from the
// constructor to ease construction/destruction of this object on one thread
// and database access on the DB sequence of |db_task_runner_|.
void Initialize();
sql::InitStatus CreateOrUpgradeIfNeeded();
sql::InitStatus InitializeTables();
sql::Database* DB();
// Returns a flag indicating whether the origin id was created successfully.
bool CreateOriginId(const url::Origin& origin);
void SavePlayback(const content::MediaPlayerWatchTime& watch_time);
mojom::MediaHistoryStatsPtr GetMediaHistoryStats();
int GetTableRowCount(const std::string& table_name);
std::vector<mojom::MediaHistoryOriginRowPtr> GetOriginRowsForDebug();
std::vector<mojom::MediaHistoryPlaybackRowPtr>
GetMediaHistoryPlaybackRowsForDebug();
std::vector<media_feeds::mojom::MediaFeedPtr> GetMediaFeedsForDebug();
void SavePlaybackSession(
const GURL& url,
const media_session::MediaMetadata& metadata,
const base::Optional<media_session::MediaPosition>& position,
const std::vector<media_session::MediaImage>& artwork);
std::vector<mojom::MediaHistoryPlaybackSessionRowPtr> GetPlaybackSessions(
base::Optional<unsigned int> num_sessions,
base::Optional<MediaHistoryStore::GetPlaybackSessionsFilter> filter);
void RazeAndClose();
void DeleteAllOriginData(const std::set<url::Origin>& origins);
void DeleteAllURLData(const std::set<GURL>& urls);
std::set<GURL> GetURLsInTableForTest(const std::string& table);
void DiscoverMediaFeed(const GURL& url);
void StoreMediaFeedFetchResult(
const int64_t feed_id,
std::vector<media_feeds::mojom::MediaFeedItemPtr> items,
const media_feeds::mojom::FetchResult result,
const base::Time& expiry_time,
const std::vector<media_session::MediaImage>& logos,
const std::string& display_name);
std::vector<media_feeds::mojom::MediaFeedItemPtr>
GetItemsForMediaFeedForDebug(const int64_t feed_id);
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner_;
const base::FilePath db_path_;
std::unique_ptr<sql::Database> db_;
sql::MetaTable meta_table_;
scoped_refptr<MediaHistoryOriginTable> origin_table_;
scoped_refptr<MediaHistoryPlaybackTable> playback_table_;
scoped_refptr<MediaHistorySessionTable> session_table_;
scoped_refptr<MediaHistorySessionImagesTable> session_images_table_;
scoped_refptr<MediaHistoryImagesTable> images_table_;
scoped_refptr<MediaHistoryFeedsTable> feeds_table_;
scoped_refptr<MediaHistoryFeedItemsTable> feed_items_table_;
bool initialization_successful_;
DISALLOW_COPY_AND_ASSIGN(MediaHistoryStoreInternal);
};
MediaHistoryStoreInternal::MediaHistoryStoreInternal(
Profile* profile,
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner)
: db_task_runner_(db_task_runner),
db_path_(profile->GetPath().Append(kMediaHistoryDatabaseName)),
origin_table_(new MediaHistoryOriginTable(db_task_runner_)),
playback_table_(new MediaHistoryPlaybackTable(db_task_runner_)),
session_table_(new MediaHistorySessionTable(db_task_runner_)),
session_images_table_(
new MediaHistorySessionImagesTable(db_task_runner_)),
images_table_(new MediaHistoryImagesTable(db_task_runner_)),
feeds_table_(media_feeds::MediaFeedsService::IsEnabled()
? new MediaHistoryFeedsTable(db_task_runner_)
: nullptr),
feed_items_table_(media_feeds::MediaFeedsService::IsEnabled()
? new MediaHistoryFeedItemsTable(db_task_runner_)
: nullptr),
initialization_successful_(false) {}
MediaHistoryStoreInternal::~MediaHistoryStoreInternal() {
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(origin_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(playback_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(session_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(session_images_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(images_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(feeds_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(feed_items_table_));
db_task_runner_->DeleteSoon(FROM_HERE, std::move(db_));
}
sql::Database* MediaHistoryStoreInternal::DB() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
return db_.get();
}
void MediaHistoryStoreInternal::SavePlayback(
const content::MediaPlayerWatchTime& watch_time) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return;
if (!DB()->BeginTransaction()) {
LOG(ERROR) << "Failed to begin the transaction.";
return;
}
// TODO(https://crbug.com/1052436): Remove the separate origin.
auto origin = url::Origin::Create(watch_time.origin);
CHECK_EQ(origin, url::Origin::Create(watch_time.url));
if (!(CreateOriginId(origin) && playback_table_->SavePlayback(watch_time))) {
DB()->RollbackTransaction();
return;
}
if (watch_time.has_audio && watch_time.has_video) {
if (!origin_table_->IncrementAggregateAudioVideoWatchTime(
origin, watch_time.cumulative_watch_time)) {
DB()->RollbackTransaction();
return;
}
}
DB()->CommitTransaction();
}
void MediaHistoryStoreInternal::Initialize() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
db_ = std::make_unique<sql::Database>();
db_->set_histogram_tag("MediaHistory");
bool success = db_->Open(db_path_);
DCHECK(success);
db_->Preload();
if (!db_->Execute("PRAGMA foreign_keys=1")) {
LOG(ERROR) << "Failed to enable foreign keys on the media history store.";
db_->Poison();
return;
}
meta_table_.Init(db_.get(), GetCurrentVersion(), kCompatibleVersionNumber);
sql::InitStatus status = CreateOrUpgradeIfNeeded();
if (status != sql::INIT_OK) {
LOG(ERROR) << "Failed to create or update the media history store.";
db_->Poison();
return;
}
status = InitializeTables();
if (status != sql::INIT_OK) {
LOG(ERROR) << "Failed to initialize the media history store tables.";
db_->Poison();
return;
}
initialization_successful_ = true;
}
sql::InitStatus MediaHistoryStoreInternal::CreateOrUpgradeIfNeeded() {
if (!db_)
return sql::INIT_FAILURE;
int cur_version = meta_table_.GetVersionNumber();
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
LOG(WARNING) << "Media history database is too new.";
return sql::INIT_TOO_NEW;
}
LOG_IF(WARNING, cur_version < GetCurrentVersion())
<< "Media history database version " << cur_version
<< " is too old to handle.";
return sql::INIT_OK;
}
sql::InitStatus MediaHistoryStoreInternal::InitializeTables() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
sql::InitStatus status = origin_table_->Initialize(db_.get());
if (status == sql::INIT_OK)
status = playback_table_->Initialize(db_.get());
if (status == sql::INIT_OK)
status = session_table_->Initialize(db_.get());
if (status == sql::INIT_OK)
status = session_images_table_->Initialize(db_.get());
if (status == sql::INIT_OK)
status = images_table_->Initialize(db_.get());
if (feeds_table_ && status == sql::INIT_OK)
status = feeds_table_->Initialize(db_.get());
if (feed_items_table_ && status == sql::INIT_OK)
status = feed_items_table_->Initialize(db_.get());
return status;
}
bool MediaHistoryStoreInternal::CreateOriginId(const url::Origin& origin) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return false;
return origin_table_->CreateOriginId(origin);
}
mojom::MediaHistoryStatsPtr MediaHistoryStoreInternal::GetMediaHistoryStats() {
mojom::MediaHistoryStatsPtr stats(mojom::MediaHistoryStats::New());
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return stats;
sql::Statement statement(DB()->GetUniqueStatement(
"SELECT name FROM sqlite_master WHERE type='table' "
"AND name NOT LIKE 'sqlite_%';"));
std::vector<std::string> table_names;
while (statement.Step()) {
auto table_name = statement.ColumnString(0);
stats->table_row_counts.emplace(table_name, GetTableRowCount(table_name));
}
DCHECK(statement.Succeeded());
return stats;
}
std::vector<mojom::MediaHistoryOriginRowPtr>
MediaHistoryStoreInternal::GetOriginRowsForDebug() {
std::vector<mojom::MediaHistoryOriginRowPtr> origins;
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return origins;
sql::Statement statement(DB()->GetUniqueStatement(
base::StringPrintf(
"SELECT O.origin, O.last_updated_time_s, "
"O.aggregate_watchtime_audio_video_s, "
"(SELECT SUM(watch_time_s) FROM %s WHERE origin_id = O.id AND "
"has_video = 1 AND has_audio = 1) AS accurate_watchtime "
"FROM %s O",
MediaHistoryPlaybackTable::kTableName,
MediaHistoryOriginTable::kTableName)
.c_str()));
std::vector<std::string> table_names;
while (statement.Step()) {
mojom::MediaHistoryOriginRowPtr origin(mojom::MediaHistoryOriginRow::New());
origin->origin = url::Origin::Create(GURL(statement.ColumnString(0)));
origin->last_updated_time =
base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromSeconds(statement.ColumnInt64(1)))
.ToJsTime();
origin->cached_audio_video_watchtime =
base::TimeDelta::FromSeconds(statement.ColumnInt64(2));
origin->actual_audio_video_watchtime =
base::TimeDelta::FromSeconds(statement.ColumnInt64(3));
origins.push_back(std::move(origin));
}
DCHECK(statement.Succeeded());
return origins;
}
std::vector<mojom::MediaHistoryPlaybackRowPtr>
MediaHistoryStoreInternal::GetMediaHistoryPlaybackRowsForDebug() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return std::vector<mojom::MediaHistoryPlaybackRowPtr>();
return playback_table_->GetPlaybackRows();
}
std::vector<media_feeds::mojom::MediaFeedPtr>
MediaHistoryStoreInternal::GetMediaFeedsForDebug() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_ || !feeds_table_)
return std::vector<media_feeds::mojom::MediaFeedPtr>();
return feeds_table_->GetRows();
}
int MediaHistoryStoreInternal::GetTableRowCount(const std::string& table_name) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return -1;
sql::Statement statement(DB()->GetUniqueStatement(
base::StringPrintf("SELECT count(*) from %s", table_name.c_str())
.c_str()));
while (statement.Step()) {
return statement.ColumnInt(0);
}
return -1;
}
void MediaHistoryStoreInternal::SavePlaybackSession(
const GURL& url,
const media_session::MediaMetadata& metadata,
const base::Optional<media_session::MediaPosition>& position,
const std::vector<media_session::MediaImage>& artwork) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return;
if (!DB()->BeginTransaction()) {
LOG(ERROR) << "Failed to begin the transaction.";
return;
}
auto origin = url::Origin::Create(url);
if (!CreateOriginId(origin)) {
DB()->RollbackTransaction();
return;
}
auto session_id =
session_table_->SavePlaybackSession(url, origin, metadata, position);
if (!session_id) {
DB()->RollbackTransaction();
return;
}
for (auto& image : artwork) {
auto image_id =
images_table_->SaveOrGetImage(image.src, origin, image.type);
if (!image_id) {
DB()->RollbackTransaction();
return;
}
// If we do not have any sizes associated with the image we should save a
// link with a null size. Otherwise, we should save a link for each size.
if (image.sizes.empty()) {
session_images_table_->LinkImage(*session_id, *image_id, base::nullopt);
} else {
for (auto& size : image.sizes) {
session_images_table_->LinkImage(*session_id, *image_id, size);
}
}
}
DB()->CommitTransaction();
}
std::vector<mojom::MediaHistoryPlaybackSessionRowPtr>
MediaHistoryStoreInternal::GetPlaybackSessions(
base::Optional<unsigned int> num_sessions,
base::Optional<MediaHistoryStore::GetPlaybackSessionsFilter> filter) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return std::vector<mojom::MediaHistoryPlaybackSessionRowPtr>();
auto sessions =
session_table_->GetPlaybackSessions(num_sessions, std::move(filter));
for (auto& session : sessions) {
session->artwork = session_images_table_->GetImagesForSession(session->id);
}
return sessions;
}
void MediaHistoryStoreInternal::RazeAndClose() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (db_ && db_->is_open())
db_->RazeAndClose();
sql::Database::Delete(db_path_);
}
void MediaHistoryStoreInternal::DeleteAllOriginData(
const std::set<url::Origin>& origins) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return;
if (!DB()->BeginTransaction()) {
LOG(ERROR) << "Failed to begin the transaction.";
return;
}
for (auto& origin : origins) {
if (!origin_table_->Delete(origin)) {
DB()->RollbackTransaction();
return;
}
}
DB()->CommitTransaction();
}
void MediaHistoryStoreInternal::DeleteAllURLData(const std::set<GURL>& urls) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return;
if (!DB()->BeginTransaction()) {
LOG(ERROR) << "Failed to begin the transaction.";
return;
}
MediaHistoryTableBase* tables[] = {
playback_table_.get(),
session_table_.get(),
};
for (auto& url : urls) {
for (auto* table : tables) {
if (!table->DeleteURL(url)) {
DB()->RollbackTransaction();
return;
}
}
}
// The mediaImages table will not be automatically cleared when we remove
// single sessions so we should remove them manually.
sql::Statement statement(DB()->GetUniqueStatement(
"DELETE FROM mediaImage WHERE id IN ("
" SELECT id FROM mediaImage LEFT JOIN sessionImage"
" ON sessionImage.image_id = mediaImage.id"
" WHERE sessionImage.session_id IS NULL)"));
if (!statement.Run()) {
DB()->RollbackTransaction();
} else {
DB()->CommitTransaction();
}
}
std::set<GURL> MediaHistoryStoreInternal::GetURLsInTableForTest(
const std::string& table) {
std::set<GURL> urls;
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return urls;
sql::Statement statement(DB()->GetUniqueStatement(
base::StringPrintf("SELECT url from %s", table.c_str()).c_str()));
while (statement.Step()) {
urls.insert(GURL(statement.ColumnString(0)));
}
DCHECK(statement.Succeeded());
return urls;
}
void MediaHistoryStoreInternal::DiscoverMediaFeed(const GURL& url) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return;
if (!DB()->BeginTransaction()) {
LOG(ERROR) << "Failed to begin the transaction.";
return;
}
if (!feeds_table_)
return;
if (!(CreateOriginId(url::Origin::Create(url)) &&
feeds_table_->DiscoverFeed(url))) {
DB()->RollbackTransaction();
return;
}
DB()->CommitTransaction();
}
void MediaHistoryStoreInternal::StoreMediaFeedFetchResult(
const int64_t feed_id,
std::vector<media_feeds::mojom::MediaFeedItemPtr> items,
const media_feeds::mojom::FetchResult result,
const base::Time& expiry_time,
const std::vector<media_session::MediaImage>& logos,
const std::string& display_name) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_)
return;
if (!DB()->BeginTransaction()) {
LOG(ERROR) << "Failed to begin the transaction.";
return;
}
if (!feeds_table_ || !feed_items_table_)
return;
// Remove all the items currently associated with this feed.
if (!feed_items_table_->DeleteItems(feed_id)) {
DB()->RollbackTransaction();
return;
}
int item_play_next_count = 0;
int item_content_types = 0;
for (auto& item : items) {
// Save each item to the table.
if (!feed_items_table_->SaveItem(feed_id, item)) {
DB()->RollbackTransaction();
return;
}
// If the item has a play next candidate or the user is currently watching
// this media then we should add it to the play next count.
if (item->play_next_candidate ||
item->action_status ==
media_feeds::mojom::MediaFeedItemActionStatus::kActive) {
item_play_next_count++;
}
item_content_types |= static_cast<int>(item->type);
}
// Update the metadata associated with this feed.
if (!feeds_table_->UpdateFeedFromFetch(
feed_id, result, expiry_time, items.size(), item_play_next_count,
item_content_types, logos, display_name)) {
DB()->RollbackTransaction();
return;
}
DB()->CommitTransaction();
}
std::vector<media_feeds::mojom::MediaFeedItemPtr>
MediaHistoryStoreInternal::GetItemsForMediaFeedForDebug(const int64_t feed_id) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!initialization_successful_ || !feed_items_table_)
return std::vector<media_feeds::mojom::MediaFeedItemPtr>();
return feed_items_table_->GetItemsForFeed(feed_id);
}
MediaHistoryStore::MediaHistoryStore(
Profile* profile,
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner)
: db_(new MediaHistoryStoreInternal(profile, db_task_runner)),
profile_(profile) {
db_task_runner->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStoreInternal::Initialize, db_));
}
MediaHistoryStore::~MediaHistoryStore() {}
void MediaHistoryStore::SavePlayback(
const content::MediaPlayerWatchTime& watch_time) {
if (!db_->initialization_successful_)
return;
db_->db_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStoreInternal::SavePlayback, db_,
watch_time));
}
scoped_refptr<base::UpdateableSequencedTaskRunner>
MediaHistoryStore::GetDBTaskRunnerForTest() {
return db_->db_task_runner_;
}
void MediaHistoryStore::EraseDatabaseAndCreateNew() {
auto db_task_runner = db_->db_task_runner_;
auto db_path = db_->db_path_;
db_task_runner->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStoreInternal::RazeAndClose, db_));
// Create a new internal store.
db_ = new MediaHistoryStoreInternal(profile_, db_task_runner);
db_task_runner->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStoreInternal::Initialize, db_));
}
void MediaHistoryStore::GetMediaHistoryStats(
base::OnceCallback<void(mojom::MediaHistoryStatsPtr)> callback) {
if (!db_->initialization_successful_)
return std::move(callback).Run(mojom::MediaHistoryStats::New());
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::GetMediaHistoryStats, db_),
std::move(callback));
}
void MediaHistoryStore::GetOriginRowsForDebug(
base::OnceCallback<void(std::vector<mojom::MediaHistoryOriginRowPtr>)>
callback) {
if (!db_->initialization_successful_) {
return std::move(callback).Run(
std::vector<mojom::MediaHistoryOriginRowPtr>());
}
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::GetOriginRowsForDebug, db_),
std::move(callback));
}
void MediaHistoryStore::GetMediaHistoryPlaybackRowsForDebug(
base::OnceCallback<void(std::vector<mojom::MediaHistoryPlaybackRowPtr>)>
callback) {
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(
&MediaHistoryStoreInternal::GetMediaHistoryPlaybackRowsForDebug, db_),
std::move(callback));
}
void MediaHistoryStore::GetMediaFeedsForDebug(
base::OnceCallback<void(std::vector<media_feeds::mojom::MediaFeedPtr>)>
callback) {
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::GetMediaFeedsForDebug, db_),
std::move(callback));
}
void MediaHistoryStore::SavePlaybackSession(
const GURL& url,
const media_session::MediaMetadata& metadata,
const base::Optional<media_session::MediaPosition>& position,
const std::vector<media_session::MediaImage>& artwork) {
if (!db_->initialization_successful_)
return;
db_->db_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStoreInternal::SavePlaybackSession,
db_, url, metadata, position, artwork));
}
void MediaHistoryStore::GetPlaybackSessions(
base::Optional<unsigned int> num_sessions,
base::Optional<GetPlaybackSessionsFilter> filter,
base::OnceCallback<
void(std::vector<mojom::MediaHistoryPlaybackSessionRowPtr>)> callback) {
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::GetPlaybackSessions, db_,
num_sessions, std::move(filter)),
std::move(callback));
}
void MediaHistoryStore::DeleteAllOriginData(
const std::set<url::Origin>& origins) {
db_->db_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStoreInternal::DeleteAllOriginData,
db_, origins));
}
void MediaHistoryStore::DeleteAllURLData(const std::set<GURL>& urls) {
db_->db_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::DeleteAllURLData, db_, urls));
}
void MediaHistoryStore::GetURLsInTableForTest(
const std::string& table,
base::OnceCallback<void(std::set<GURL>)> callback) {
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::GetURLsInTableForTest, db_,
table),
std::move(callback));
}
void MediaHistoryStore::DiscoverMediaFeed(const GURL& url) {
db_->db_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::DiscoverMediaFeed, db_, url));
}
void MediaHistoryStore::PostTaskToDBForTest(base::OnceClosure callback) {
db_->db_task_runner_->PostTaskAndReply(FROM_HERE, base::DoNothing(),
std::move(callback));
}
void MediaHistoryStore::StoreMediaFeedFetchResult(
const int64_t feed_id,
std::vector<media_feeds::mojom::MediaFeedItemPtr> items,
const media_feeds::mojom::FetchResult result,
const base::Time& expiry_time,
const std::vector<media_session::MediaImage>& logos,
const std::string& display_name) {
db_->db_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::StoreMediaFeedFetchResult, db_,
feed_id, std::move(items), result, expiry_time, logos,
display_name));
}
void MediaHistoryStore::GetItemsForMediaFeedForDebug(
const int64_t feed_id,
base::OnceCallback<void(std::vector<media_feeds::mojom::MediaFeedItemPtr>)>
callback) {
base::PostTaskAndReplyWithResult(
db_->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::GetItemsForMediaFeedForDebug,
db_, feed_id),
std::move(callback));
}
} // namespace media_history