Commit 7f6eed59 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Feeds] Store feeds in Media History

Adds a feeds table that will store feeds in
Media History.

BUG=1057765

Change-Id: I68e38fdeb608da9f9279c74ffbed3f7efc5037a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2082300Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#746155}
parent cc5f83fa
...@@ -693,6 +693,8 @@ jumbo_static_library("browser") { ...@@ -693,6 +693,8 @@ jumbo_static_library("browser") {
"media/feeds/media_feeds_service_factory.h", "media/feeds/media_feeds_service_factory.h",
"media/history/media_history_contents_observer.cc", "media/history/media_history_contents_observer.cc",
"media/history/media_history_contents_observer.h", "media/history/media_history_contents_observer.h",
"media/history/media_history_feeds_table.cc",
"media/history/media_history_feeds_table.h",
"media/history/media_history_images_table.cc", "media/history/media_history_images_table.cc",
"media/history/media_history_images_table.h", "media/history/media_history_images_table.h",
"media/history/media_history_keyed_service.cc", "media/history/media_history_keyed_service.cc",
......
// Copyright 2020 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_feeds_table.h"
#include "base/strings/stringprintf.h"
#include "base/updateable_sequenced_task_runner.h"
#include "chrome/browser/media/history/media_history_store.h"
#include "sql/statement.h"
#include "url/gurl.h"
namespace media_history {
const char MediaHistoryFeedsTable::kTableName[] = "mediaFeed";
MediaHistoryFeedsTable::MediaHistoryFeedsTable(
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner)
: MediaHistoryTableBase(std::move(db_task_runner)) {}
MediaHistoryFeedsTable::~MediaHistoryFeedsTable() = default;
sql::InitStatus MediaHistoryFeedsTable::CreateTableIfNonExistent() {
if (!CanAccessDatabase())
return sql::INIT_FAILURE;
bool success =
DB()->Execute(base::StringPrintf("CREATE TABLE IF NOT EXISTS %s("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"origin_id INTEGER NOT NULL UNIQUE,"
"url TEXT NOT NULL, "
"CONSTRAINT fk_origin "
"FOREIGN KEY (origin_id) "
"REFERENCES origin(id) "
"ON DELETE CASCADE"
")",
kTableName)
.c_str());
if (success) {
success = DB()->Execute(
base::StringPrintf(
"CREATE INDEX IF NOT EXISTS media_feed_origin_id_index ON "
"%s (origin_id)",
kTableName)
.c_str());
}
if (!success) {
ResetDB();
LOG(ERROR) << "Failed to create media history feeds table.";
return sql::INIT_FAILURE;
}
return sql::INIT_OK;
}
bool MediaHistoryFeedsTable::SaveFeed(const GURL& url) {
DCHECK_LT(0, DB()->transaction_nesting());
if (!CanAccessDatabase())
return false;
sql::Statement statement(DB()->GetCachedStatement(
SQL_FROM_HERE,
base::StringPrintf("INSERT OR REPLACE INTO %s "
"(origin_id, url) VALUES "
"((SELECT id FROM origin WHERE origin = ?), ?)",
kTableName)
.c_str()));
statement.BindString(0, MediaHistoryOriginTable::GetOriginForStorage(
url::Origin::Create(url)));
statement.BindString(1, url.spec());
return statement.Run();
}
} // namespace media_history
// Copyright 2020 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_MEDIA_HISTORY_MEDIA_HISTORY_FEEDS_TABLE_H_
#define CHROME_BROWSER_MEDIA_HISTORY_MEDIA_HISTORY_FEEDS_TABLE_H_
#include "chrome/browser/media/history/media_history_table_base.h"
#include "sql/init_status.h"
#include "url/gurl.h"
namespace base {
class UpdateableSequencedTaskRunner;
} // namespace base
namespace media_history {
class MediaHistoryFeedsTable : public MediaHistoryTableBase {
public:
static const char kTableName[];
private:
friend class MediaHistoryStoreInternal;
explicit MediaHistoryFeedsTable(
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner);
MediaHistoryFeedsTable(const MediaHistoryFeedsTable&) = delete;
MediaHistoryFeedsTable& operator=(const MediaHistoryFeedsTable&) = delete;
~MediaHistoryFeedsTable() override;
// MediaHistoryTableBase:
sql::InitStatus CreateTableIfNonExistent() override;
// Saves a newly discovered feed in the database.
bool SaveFeed(const GURL& url);
};
} // namespace media_history
#endif // CHROME_BROWSER_MEDIA_HISTORY_MEDIA_HISTORY_FEEDS_TABLE_H_
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "chrome/browser/media/feeds/media_feeds_service.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_images_table.h"
#include "chrome/browser/media/history/media_history_origin_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_playback_table.h"
...@@ -86,6 +88,8 @@ class MediaHistoryStoreInternal ...@@ -86,6 +88,8 @@ class MediaHistoryStoreInternal
std::set<GURL> GetURLsInTableForTest(const std::string& table); std::set<GURL> GetURLsInTableForTest(const std::string& table);
void SaveMediaFeed(const GURL& url);
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner_; scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner_;
const base::FilePath db_path_; const base::FilePath db_path_;
std::unique_ptr<sql::Database> db_; std::unique_ptr<sql::Database> db_;
...@@ -95,6 +99,7 @@ class MediaHistoryStoreInternal ...@@ -95,6 +99,7 @@ class MediaHistoryStoreInternal
scoped_refptr<MediaHistorySessionTable> session_table_; scoped_refptr<MediaHistorySessionTable> session_table_;
scoped_refptr<MediaHistorySessionImagesTable> session_images_table_; scoped_refptr<MediaHistorySessionImagesTable> session_images_table_;
scoped_refptr<MediaHistoryImagesTable> images_table_; scoped_refptr<MediaHistoryImagesTable> images_table_;
scoped_refptr<MediaHistoryFeedsTable> feeds_table_;
bool initialization_successful_; bool initialization_successful_;
DISALLOW_COPY_AND_ASSIGN(MediaHistoryStoreInternal); DISALLOW_COPY_AND_ASSIGN(MediaHistoryStoreInternal);
...@@ -111,6 +116,9 @@ MediaHistoryStoreInternal::MediaHistoryStoreInternal( ...@@ -111,6 +116,9 @@ MediaHistoryStoreInternal::MediaHistoryStoreInternal(
session_images_table_( session_images_table_(
new MediaHistorySessionImagesTable(db_task_runner_)), new MediaHistorySessionImagesTable(db_task_runner_)),
images_table_(new MediaHistoryImagesTable(db_task_runner_)), images_table_(new MediaHistoryImagesTable(db_task_runner_)),
feeds_table_(media_feeds::MediaFeedsService::IsEnabled()
? new MediaHistoryFeedsTable(db_task_runner_)
: nullptr),
initialization_successful_(false) {} initialization_successful_(false) {}
MediaHistoryStoreInternal::~MediaHistoryStoreInternal() { MediaHistoryStoreInternal::~MediaHistoryStoreInternal() {
...@@ -119,6 +127,7 @@ MediaHistoryStoreInternal::~MediaHistoryStoreInternal() { ...@@ -119,6 +127,7 @@ MediaHistoryStoreInternal::~MediaHistoryStoreInternal() {
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(session_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(session_images_table_));
db_task_runner_->ReleaseSoon(FROM_HERE, std::move(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_->DeleteSoon(FROM_HERE, std::move(db_)); db_task_runner_->DeleteSoon(FROM_HERE, std::move(db_));
} }
...@@ -220,6 +229,8 @@ sql::InitStatus MediaHistoryStoreInternal::InitializeTables() { ...@@ -220,6 +229,8 @@ sql::InitStatus MediaHistoryStoreInternal::InitializeTables() {
status = session_images_table_->Initialize(db_.get()); status = session_images_table_->Initialize(db_.get());
if (status == sql::INIT_OK) if (status == sql::INIT_OK)
status = images_table_->Initialize(db_.get()); status = images_table_->Initialize(db_.get());
if (feeds_table_ && status == sql::INIT_OK)
status = feeds_table_->Initialize(db_.get());
return status; return status;
} }
...@@ -435,6 +446,28 @@ std::set<GURL> MediaHistoryStoreInternal::GetURLsInTableForTest( ...@@ -435,6 +446,28 @@ std::set<GURL> MediaHistoryStoreInternal::GetURLsInTableForTest(
return urls; return urls;
} }
void MediaHistoryStoreInternal::SaveMediaFeed(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_->SaveFeed(url))) {
DB()->RollbackTransaction();
return;
}
DB()->CommitTransaction();
}
MediaHistoryStore::MediaHistoryStore( MediaHistoryStore::MediaHistoryStore(
Profile* profile, Profile* profile,
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner) scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner)
...@@ -551,4 +584,10 @@ void MediaHistoryStore::GetURLsInTableForTest( ...@@ -551,4 +584,10 @@ void MediaHistoryStore::GetURLsInTableForTest(
std::move(callback)); std::move(callback));
} }
void MediaHistoryStore::SaveMediaFeed(const GURL& url) {
db_->db_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&MediaHistoryStoreInternal::SaveMediaFeed, db_, url));
}
} // namespace media_history } // namespace media_history
...@@ -87,6 +87,9 @@ class MediaHistoryStore { ...@@ -87,6 +87,9 @@ class MediaHistoryStore {
const base::Optional<media_session::MediaPosition>& position, const base::Optional<media_session::MediaPosition>& position,
const std::vector<media_session::MediaImage>& artwork); const std::vector<media_session::MediaImage>& artwork);
// Saves a newly discovered media feed in the media history store.
void SaveMediaFeed(const GURL& url);
scoped_refptr<base::UpdateableSequencedTaskRunner> GetDBTaskRunnerForTest(); scoped_refptr<base::UpdateableSequencedTaskRunner> GetDBTaskRunnerForTest();
protected: protected:
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/task/thread_pool/pooled_sequenced_task_runner.h" #include "base/task/thread_pool/pooled_sequenced_task_runner.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h" #include "base/test/test_timeouts.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_images_table.h"
#include "chrome/browser/media/history/media_history_session_images_table.h" #include "chrome/browser/media/history/media_history_session_images_table.h"
#include "chrome/browser/media/history/media_history_session_table.h" #include "chrome/browser/media/history/media_history_session_table.h"
...@@ -20,6 +22,7 @@ ...@@ -20,6 +22,7 @@
#include "content/public/browser/media_player_watch_time.h" #include "content/public/browser/media_player_watch_time.h"
#include "content/public/test/browser_task_environment.h" #include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "media/base/media_switches.h"
#include "services/media_session/public/cpp/media_image.h" #include "services/media_session/public/cpp/media_image.h"
#include "services/media_session/public/cpp/media_metadata.h" #include "services/media_session/public/cpp/media_metadata.h"
#include "services/media_session/public/cpp/media_position.h" #include "services/media_session/public/cpp/media_position.h"
...@@ -131,6 +134,7 @@ TEST_F(MediaHistoryStoreUnitTest, CreateDatabaseTables) { ...@@ -131,6 +134,7 @@ TEST_F(MediaHistoryStoreUnitTest, CreateDatabaseTables) {
ASSERT_TRUE(GetDB().DoesTableExist("playbackSession")); ASSERT_TRUE(GetDB().DoesTableExist("playbackSession"));
ASSERT_TRUE(GetDB().DoesTableExist("sessionImage")); ASSERT_TRUE(GetDB().DoesTableExist("sessionImage"));
ASSERT_TRUE(GetDB().DoesTableExist("mediaImage")); ASSERT_TRUE(GetDB().DoesTableExist("mediaImage"));
ASSERT_FALSE(GetDB().DoesTableExist("mediaFeed"));
} }
TEST_F(MediaHistoryStoreUnitTest, SavePlayback) { TEST_F(MediaHistoryStoreUnitTest, SavePlayback) {
...@@ -350,4 +354,57 @@ TEST_F(MediaHistoryStoreUnitTest, SavePlayback_IncrementAggregateWatchtime) { ...@@ -350,4 +354,57 @@ TEST_F(MediaHistoryStoreUnitTest, SavePlayback_IncrementAggregateWatchtime) {
origins[1]->actual_audio_video_watchtime); origins[1]->actual_audio_video_watchtime);
} }
TEST_F(MediaHistoryStoreUnitTest, SaveMediaFeed_Noop) {
GetMediaHistoryStore()->SaveMediaFeed(GURL("https://www.google.com/feed"));
content::RunAllTasksUntilIdle();
{
// Check the feeds were not recorded.
mojom::MediaHistoryStatsPtr stats = GetStatsSync();
EXPECT_FALSE(base::Contains(stats->table_row_counts,
MediaHistoryFeedsTable::kTableName));
}
}
// Runs the tests with the media feeds feature enabled.
class MediaHistoryStoreFeedsTest : public MediaHistoryStoreUnitTest {
public:
void SetUp() override {
features_.InitAndEnableFeature(media::kMediaFeeds);
MediaHistoryStoreUnitTest::SetUp();
}
private:
base::test::ScopedFeatureList features_;
};
TEST_F(MediaHistoryStoreFeedsTest, CreateDatabaseTables) {
ASSERT_TRUE(GetDB().DoesTableExist("mediaFeed"));
}
TEST_F(MediaHistoryStoreFeedsTest, SaveMediaFeed) {
GURL url_a("https://www.google.com/feed");
GURL url_b("https://www.google.co.uk/feed");
GURL url_c("https://www.google.com/feed2");
GetMediaHistoryStore()->SaveMediaFeed(url_a);
GetMediaHistoryStore()->SaveMediaFeed(url_b);
content::RunAllTasksUntilIdle();
{
// Check the feeds were recorded.
mojom::MediaHistoryStatsPtr stats = GetStatsSync();
EXPECT_EQ(2, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
}
GetMediaHistoryStore()->SaveMediaFeed(url_c);
content::RunAllTasksUntilIdle();
{
// Check the feeds were recorded.
mojom::MediaHistoryStatsPtr stats = GetStatsSync();
EXPECT_EQ(2, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
}
}
} // namespace media_history } // namespace media_history
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment