Commit e38f8594 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

Add caching for frameless code

Adds caching for the frameless code. Will store the
data in Media History and will clear every 24 hours
or if the user signs in or out.

BUG=1121360

Change-Id: I0ae9112cbd5dc272158f2e369d8807da02f0e2b6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2375701
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804285}
parent b8af58e9
......@@ -658,6 +658,8 @@ static_library("browser") {
"media/history/media_history_feeds_table.h",
"media/history/media_history_images_table.cc",
"media/history/media_history_images_table.h",
"media/history/media_history_kaleidoscope_data_table.cc",
"media/history/media_history_kaleidoscope_data_table.h",
"media/history/media_history_keyed_service.cc",
"media/history/media_history_keyed_service.h",
"media/history/media_history_keyed_service_factory.cc",
......@@ -1879,6 +1881,7 @@ static_library("browser") {
"//chrome/browser/media:mojo_bindings",
"//chrome/browser/media/feeds:mojo_bindings",
"//chrome/browser/media/feeds:proto",
"//chrome/browser/media/kaleidoscope/mojom",
"//chrome/browser/media/router",
"//chrome/browser/metrics:expired_histograms_array",
"//chrome/browser/metrics/variations:chrome_ui_string_overrider_factory",
......@@ -3824,7 +3827,6 @@ static_library("browser") {
"//base/util/memory_pressure",
"//base/util/timer",
"//chrome/app/vector_icons",
"//chrome/browser/media/kaleidoscope/mojom",
"//chrome/browser/nearby_sharing:share_target",
"//chrome/browser/nearby_sharing/certificates",
"//chrome/browser/nearby_sharing/client",
......
......@@ -1049,6 +1049,11 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData(
media_history_service->ResetMediaFeedDueToCacheClearing(
delete_begin_, delete_end_, nullable_filter,
CreateTaskCompletionClosure(TracingDataType::kMediaFeeds));
if (nullable_filter.is_null() ||
nullable_filter.Run(GaiaUrls::GetInstance()->google_url())) {
media_history_service->DeleteKaleidoscopeData();
}
}
}
......
// 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_kaleidoscope_data_table.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "sql/statement.h"
namespace media_history {
const char MediaHistoryKaleidoscopeDataTable::kTableName[] = "kaleidoscopeData";
MediaHistoryKaleidoscopeDataTable::MediaHistoryKaleidoscopeDataTable(
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner)
: MediaHistoryTableBase(std::move(db_task_runner)) {}
MediaHistoryKaleidoscopeDataTable::~MediaHistoryKaleidoscopeDataTable() =
default;
sql::InitStatus MediaHistoryKaleidoscopeDataTable::CreateTableIfNonExistent() {
if (!CanAccessDatabase())
return sql::INIT_FAILURE;
bool success = DB()->Execute(
"CREATE TABLE IF NOT EXISTS kaleidoscopeData("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"data BLOB, "
"result INTEGER, "
"gaia_id TEXT UNIQUE, "
"last_updated_time_s INTEGER)");
if (!success) {
ResetDB();
DLOG(ERROR) << "Failed to create media history kaleidoscope data table.";
return sql::INIT_FAILURE;
}
return sql::INIT_OK;
}
bool MediaHistoryKaleidoscopeDataTable::Set(
media::mojom::GetCollectionsResponsePtr data,
const std::string& gaia_id) {
DCHECK_LT(0, DB()->transaction_nesting());
if (!CanAccessDatabase())
return false;
sql::Statement statement(DB()->GetCachedStatement(
SQL_FROM_HERE,
"INSERT OR REPLACE INTO kaleidoscopeData "
"(id, data, result, gaia_id, last_updated_time_s) VALUES "
"(0, ?, ?, ?, ?)"));
statement.BindBlob(0, data->response.data(), data->response.length());
statement.BindInt64(1, static_cast<int>(data->result));
statement.BindString(2, gaia_id);
statement.BindInt64(3,
base::Time::Now().ToDeltaSinceWindowsEpoch().InSeconds());
if (!statement.Run()) {
DLOG(ERROR) << "Failed to update the data.";
return false;
}
return true;
}
media::mojom::GetCollectionsResponsePtr MediaHistoryKaleidoscopeDataTable::Get(
const std::string& gaia_id) {
DCHECK_LT(0, DB()->transaction_nesting());
if (!CanAccessDatabase())
return nullptr;
sql::Statement statement(DB()->GetCachedStatement(
SQL_FROM_HERE,
"SELECT data, result, gaia_id, last_updated_time_s FROM "
"kaleidoscopeData WHERE id = 0"));
while (statement.Step()) {
// If the GAIA id for the current user does not match the one we stored then
// wipe the stored data and return an empty string.
if (statement.ColumnString(2) != gaia_id) {
CHECK(Delete());
return nullptr;
}
// If the data that was stored was older than 24 hours then we should wipe
// the stored data and return an empty string.
auto updated_time = base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromSeconds(statement.ColumnInt64(3)));
if ((base::Time::Now() - updated_time) > base::TimeDelta::FromDays(1)) {
CHECK(Delete());
return nullptr;
}
auto out = media::mojom::GetCollectionsResponse::New();
statement.ColumnBlobAsString(0, &out->response);
out->result = static_cast<media::mojom::GetCollectionsResult>(
statement.ColumnInt64(1));
return out;
}
// If there is no data then return nullptr.
return nullptr;
}
bool MediaHistoryKaleidoscopeDataTable::Delete() {
DCHECK_LT(0, DB()->transaction_nesting());
if (!CanAccessDatabase())
return false;
sql::Statement statement(
DB()->GetCachedStatement(SQL_FROM_HERE, "DELETE FROM kaleidoscopeData"));
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_KALEIDOSCOPE_DATA_TABLE_H_
#define CHROME_BROWSER_MEDIA_HISTORY_MEDIA_HISTORY_KALEIDOSCOPE_DATA_TABLE_H_
#include <string>
#include "base/updateable_sequenced_task_runner.h"
#include "chrome/browser/media/history/media_history_table_base.h"
#include "chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom.h"
#include "sql/init_status.h"
namespace media_history {
class MediaHistoryKaleidoscopeDataTable : public MediaHistoryTableBase {
public:
static const char kTableName[];
private:
friend class MediaHistoryStore;
explicit MediaHistoryKaleidoscopeDataTable(
scoped_refptr<base::UpdateableSequencedTaskRunner> db_task_runner);
~MediaHistoryKaleidoscopeDataTable() override;
// MediaHistoryTableBase:
sql::InitStatus CreateTableIfNonExistent() override;
bool Set(media::mojom::GetCollectionsResponsePtr data,
const std::string& gaia_id);
media::mojom::GetCollectionsResponsePtr Get(const std::string& gaia_id);
bool Delete();
DISALLOW_COPY_AND_ASSIGN(MediaHistoryKaleidoscopeDataTable);
};
} // namespace media_history
#endif // CHROME_BROWSER_MEDIA_HISTORY_MEDIA_HISTORY_KALEIDOSCOPE_DATA_TABLE_H_
......@@ -556,4 +556,35 @@ void MediaHistoryKeyedService::GetMediaFeedFetchDetails(
std::move(callback));
}
void MediaHistoryKeyedService::SetKaleidoscopeData(
media::mojom::GetCollectionsResponsePtr data,
const std::string& gaia_id) {
if (auto* store = store_->GetForWrite()) {
store->db_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&MediaHistoryStore::SetKaleidoscopeData,
store, std::move(data), gaia_id));
}
}
void MediaHistoryKeyedService::GetKaleidoscopeData(
const std::string& gaia_id,
GetKaleidoscopeDataCallback callback) {
if (auto* store = store_->GetForWrite()) {
base::PostTaskAndReplyWithResult(
store_->GetForRead()->db_task_runner_.get(), FROM_HERE,
base::BindOnce(&MediaHistoryStore::GetKaleidoscopeData, store, gaia_id),
std::move(callback));
} else {
std::move(callback).Run(nullptr);
}
}
void MediaHistoryKeyedService::DeleteKaleidoscopeData() {
if (auto* store = store_->GetForWrite()) {
store->db_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&MediaHistoryStore::DeleteKaleidoscopeData, store));
}
}
} // namespace media_history
......@@ -9,6 +9,7 @@
#include "base/time/time.h"
#include "chrome/browser/media/feeds/media_feeds_store.mojom.h"
#include "chrome/browser/media/history/media_history_store.mojom.h"
#include "chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/media_player_watch_time.h"
......@@ -341,6 +342,20 @@ class MediaHistoryKeyedService : public KeyedService,
void UpdateFeedUserStatus(const int64_t feed_id,
media_feeds::mojom::FeedUserStatus status);
// Stores the Kaleidocope data keyed against a GAIA ID.
void SetKaleidoscopeData(media::mojom::GetCollectionsResponsePtr data,
const std::string& gaia_id);
// Retrieves the Kaleidoscope data keyed against a GAIA ID. The data expires
// after 24 hours or if the GAIA ID changes.
using GetKaleidoscopeDataCallback =
base::OnceCallback<void(media::mojom::GetCollectionsResponsePtr)>;
void GetKaleidoscopeData(const std::string& gaia_id,
GetKaleidoscopeDataCallback callback);
// Delete any stored data.
void DeleteKaleidoscopeData();
protected:
friend class media_feeds::MediaFeedsService;
......
......@@ -15,6 +15,7 @@
#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_kaleidoscope_data_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"
......@@ -191,6 +192,8 @@ MediaHistoryStore::MediaHistoryStore(
feed_items_table_(IsMediaFeedsEnabled()
? new MediaHistoryFeedItemsTable(db_task_runner_)
: nullptr),
kaleidoscope_table_(
new MediaHistoryKaleidoscopeDataTable(db_task_runner_)),
initialization_successful_(false) {
db_->set_histogram_tag("MediaHistory");
db_->set_exclusive_locking();
......@@ -452,6 +455,8 @@ sql::InitStatus MediaHistoryStore::InitializeTables() {
status = feeds_table_->Initialize(db_.get());
if (feed_items_table_ && status == sql::INIT_OK)
status = feed_items_table_->Initialize(db_.get());
if (status == sql::INIT_OK)
status = kaleidoscope_table_->Initialize(db_.get());
return status;
}
......@@ -1218,4 +1223,58 @@ void MediaHistoryStore::UpdateFeedUserStatus(
DB()->CommitTransaction();
}
void MediaHistoryStore::SetKaleidoscopeData(
media::mojom::GetCollectionsResponsePtr data,
const std::string& gaia_id) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!CanAccessDatabase())
return;
if (!DB()->BeginTransaction()) {
DLOG(ERROR) << "Failed to begin the transaction.";
return;
}
if (!kaleidoscope_table_->Set(std::move(data), gaia_id)) {
DB()->RollbackTransaction();
return;
}
DB()->CommitTransaction();
}
media::mojom::GetCollectionsResponsePtr MediaHistoryStore::GetKaleidoscopeData(
const std::string& gaia_id) {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!CanAccessDatabase())
return nullptr;
if (!DB()->BeginTransaction()) {
DLOG(ERROR) << "Failed to begin the transaction.";
return nullptr;
}
auto out = kaleidoscope_table_->Get(gaia_id);
DB()->CommitTransaction();
return out;
}
void MediaHistoryStore::DeleteKaleidoscopeData() {
DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
if (!CanAccessDatabase())
return;
if (!DB()->BeginTransaction()) {
DLOG(ERROR) << "Failed to begin the transaction.";
return;
}
if (!kaleidoscope_table_->Delete()) {
DB()->RollbackTransaction();
return;
}
DB()->CommitTransaction();
}
} // namespace media_history
......@@ -42,6 +42,7 @@ class MediaHistorySessionImagesTable;
class MediaHistoryImagesTable;
class MediaHistoryFeedsTable;
class MediaHistoryFeedItemsTable;
class MediaHistoryKaleidoscopeDataTable;
// 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
......@@ -202,6 +203,14 @@ class MediaHistoryStore : public base::RefCountedThreadSafe<MediaHistoryStore> {
void UpdateFeedUserStatus(const int64_t feed_id,
media_feeds::mojom::FeedUserStatus status);
void SetKaleidoscopeData(media::mojom::GetCollectionsResponsePtr data,
const std::string& gaia_id);
media::mojom::GetCollectionsResponsePtr GetKaleidoscopeData(
const std::string& gaia_id);
void DeleteKaleidoscopeData();
private:
friend class base::RefCountedThreadSafe<MediaHistoryStore>;
......@@ -224,6 +233,7 @@ class MediaHistoryStore : public base::RefCountedThreadSafe<MediaHistoryStore> {
scoped_refptr<MediaHistoryImagesTable> images_table_;
scoped_refptr<MediaHistoryFeedsTable> feeds_table_;
scoped_refptr<MediaHistoryFeedItemsTable> feed_items_table_;
scoped_refptr<MediaHistoryKaleidoscopeDataTable> kaleidoscope_table_;
bool initialization_successful_;
base::AtomicFlag cancelled_;
};
......
......@@ -179,6 +179,23 @@ class MediaHistoryStoreUnitTest
return out;
}
media::mojom::GetCollectionsResponsePtr GetKaleidoscopeDataSync(
MediaHistoryKeyedService* service,
const std::string& gaia_id) {
base::RunLoop run_loop;
media::mojom::GetCollectionsResponsePtr out;
service->GetKaleidoscopeData(
gaia_id, base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr data) {
out = std::move(data);
run_loop.Quit();
}));
run_loop.Run();
return out;
}
std::vector<mojom::MediaHistoryPlaybackRowPtr> GetPlaybackRowsSync(
MediaHistoryKeyedService* service) {
base::RunLoop run_loop;
......@@ -268,6 +285,13 @@ class MediaHistoryStoreUnitTest
Profile* GetProfile() { return profile_.get(); }
media::mojom::GetCollectionsResponsePtr GetExpectedKaleidoscopeData() {
auto data = media::mojom::GetCollectionsResponse::New();
data->response = "abcd";
data->result = media::mojom::GetCollectionsResult::kFailed;
return data;
}
private:
base::ScopedTempDir temp_dir_;
......@@ -612,6 +636,64 @@ TEST_P(MediaHistoryStoreUnitTest, SavePlayback_IncrementAggregateWatchtime) {
EXPECT_EQ(origins, GetOriginRowsSync(otr_service()));
}
TEST_P(MediaHistoryStoreUnitTest, KaleidoscopeData) {
{
// The data should be empty at the start.
auto data = GetKaleidoscopeDataSync(service(), "123");
EXPECT_TRUE(data.is_null());
}
service()->SetKaleidoscopeData(GetExpectedKaleidoscopeData(), "123");
WaitForDB();
{
// We should be able to get the data.
auto data = GetKaleidoscopeDataSync(service(), "123");
if (IsReadOnly()) {
EXPECT_TRUE(data.is_null());
} else {
EXPECT_EQ(GetExpectedKaleidoscopeData(), data);
}
}
{
// Getting with a different GAIA ID should wipe the data and return an
// empty string.
auto data = GetKaleidoscopeDataSync(service(), "1234");
EXPECT_TRUE(data.is_null());
}
{
// The data should be empty for the other GAIA ID too.
auto data = GetKaleidoscopeDataSync(service(), "123");
EXPECT_TRUE(data.is_null());
}
service()->SetKaleidoscopeData(GetExpectedKaleidoscopeData(), "123");
WaitForDB();
{
// We should be able to get the data.
auto data = GetKaleidoscopeDataSync(service(), "123");
if (IsReadOnly()) {
EXPECT_TRUE(data.is_null());
} else {
EXPECT_EQ(GetExpectedKaleidoscopeData(), data);
}
}
service()->DeleteKaleidoscopeData();
WaitForDB();
{
// The data should have been deleted.
auto data = GetKaleidoscopeDataSync(service(), "123");
EXPECT_TRUE(data.is_null());
}
}
TEST_P(MediaHistoryStoreUnitTest, GetOriginsWithHighWatchTime) {
const GURL url("http://google.com/test");
const GURL url_alt("http://example.org/test");
......
......@@ -287,7 +287,8 @@ void KaleidoscopeDataProviderImpl::OnGotCredentialsForCollections(
media::mojom::CredentialsResult result) {
// If we have no credentials then we should return an empty response.
if (result != media::mojom::CredentialsResult::kSuccess) {
std::move(cb).Run("");
std::move(cb).Run(media::mojom::GetCollectionsResponse::New(
"", media::mojom::GetCollectionsResult::kFailed));
return;
}
......
......@@ -8,6 +8,7 @@
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/strcat.h"
#include "chrome/browser/media/history/media_history_store.h"
#include "chrome/browser/media/kaleidoscope/kaleidoscope_service_factory.h"
#include "chrome/browser/media/kaleidoscope/kaleidoscope_switches.h"
#include "chrome/browser/profiles/profile.h"
......@@ -15,6 +16,7 @@
#include "media/base/media_switches.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
......@@ -101,7 +103,29 @@ class GetCollectionsRequest {
std::string gaia_id() const { return gaia_id_; }
network::SimpleURLLoader& url_loader() const {
return *pending_request_.get();
}
bool has_failed() const {
return url_loader().NetError() != net::OK ||
response_code() != net::HTTP_OK;
}
bool not_available() const {
return url_loader().NetError() == net::OK &&
response_code() == net::HTTP_FORBIDDEN;
}
private:
int response_code() const {
if (url_loader().ResponseInfo() && url_loader().ResponseInfo()->headers) {
return url_loader().ResponseInfo()->headers->response_code();
}
return 0;
}
std::string const gaia_id_;
std::unique_ptr<::network::SimpleURLLoader> pending_request_;
......@@ -134,9 +158,31 @@ void KaleidoscopeService::GetCollections(
request_.reset();
}
// If this is a test then return early.
if (collections_for_testing_.has_value()) {
std::move(callback).Run(*collections_for_testing_);
// Check Media History if we have any cached kaleidoscope data.
media_history::MediaHistoryKeyedService::Get(profile_)->GetKaleidoscopeData(
gaia_id,
base::BindOnce(&KaleidoscopeService::OnGotCachedData,
weak_ptr_factory_.GetWeakPtr(), std::move(credentials),
gaia_id, request, std::move(callback)));
}
void KaleidoscopeService::SetCollectionsForTesting(
const std::string& collections) {
media_history::MediaHistoryKeyedService::Get(profile_)->SetKaleidoscopeData(
media::mojom::GetCollectionsResponse::New(
collections, media::mojom::GetCollectionsResult::kSuccess),
"");
}
void KaleidoscopeService::OnGotCachedData(
media::mojom::CredentialsPtr credentials,
const std::string& gaia_id,
const std::string& request,
GetCollectionsCallback callback,
media::mojom::GetCollectionsResponsePtr cached) {
// If we got cached data then return that.
if (cached) {
std::move(callback).Run(std::move(cached));
return;
}
......@@ -149,28 +195,37 @@ void KaleidoscopeService::GetCollections(
std::move(credentials), gaia_id, request,
GetURLLoaderFactoryForFetcher(),
base::BindOnce(&KaleidoscopeService::OnURLFetchComplete,
base::Unretained(this)));
base::Unretained(this), gaia_id));
}
}
void KaleidoscopeService::SetCollectionsForTesting(
const std::string& collections) {
collections_for_testing_ = collections;
}
void KaleidoscopeService::OnURLFetchComplete(
const std::string& gaia_id,
std::unique_ptr<std::string> data) {
request_.reset();
auto response = media::mojom::GetCollectionsResponse::New();
if (request_->not_available()) {
response->result = media::mojom::GetCollectionsResult::kNotAvailable;
} else if (request_->has_failed()) {
response->result = media::mojom::GetCollectionsResult::kFailed;
} else {
response->result = media::mojom::GetCollectionsResult::kSuccess;
response->response = *data;
}
for (auto& callback : pending_callbacks_) {
if (!data) {
std::move(callback).Run("");
} else {
std::move(callback).Run(*data);
}
std::move(callback).Run(response.Clone());
}
pending_callbacks_.clear();
request_.reset();
// If the request did not fail then we should save it in the cache so we avoid
// hitting the server later. If the response was that Kaleidoscope is not
// available to the user then that is cacheable too.
if (response->result != media::mojom::GetCollectionsResult::kFailed) {
media_history::MediaHistoryKeyedService::Get(profile_)->SetKaleidoscopeData(
response.Clone(), gaia_id);
}
}
scoped_refptr<::network::SharedURLLoaderFactory>
......
......@@ -32,7 +32,8 @@ class KaleidoscopeService : public KeyedService {
// Returns the instance attached to the given |profile|.
static KaleidoscopeService* Get(Profile* profile);
using GetCollectionsCallback = base::OnceCallback<void(const std::string&)>;
using GetCollectionsCallback =
base::OnceCallback<void(media::mojom::GetCollectionsResponsePtr)>;
void GetCollections(media::mojom::CredentialsPtr credentials,
const std::string& gaia_id,
const std::string& request,
......@@ -43,7 +44,14 @@ class KaleidoscopeService : public KeyedService {
private:
friend class KaleidoscopeServiceTest;
void OnURLFetchComplete(std::unique_ptr<std::string> data);
void OnGotCachedData(media::mojom::CredentialsPtr credentials,
const std::string& gaia_id,
const std::string& request,
GetCollectionsCallback callback,
media::mojom::GetCollectionsResponsePtr cached);
void OnURLFetchComplete(const std::string& gaia_id,
std::unique_ptr<std::string> data);
scoped_refptr<::network::SharedURLLoaderFactory>
GetURLLoaderFactoryForFetcher();
......@@ -57,7 +65,7 @@ class KaleidoscopeService : public KeyedService {
std::vector<GetCollectionsCallback> pending_callbacks_;
base::Optional<std::string> collections_for_testing_;
base::WeakPtrFactory<KaleidoscopeService> weak_ptr_factory_{this};
};
} // namespace kaleidoscope
......
......@@ -103,30 +103,122 @@ TEST_F(KaleidoscopeServiceTest, Success) {
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](const std::string& result) { EXPECT_EQ(kTestData, result); }));
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_EQ(kTestData, result->response);
EXPECT_EQ(media::mojom::GetCollectionsResult::kSuccess,
result->result);
}));
WaitForRequest();
ASSERT_TRUE(RespondToFetch(kTestData));
// If we call again then we should hit the cache.
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_EQ(kTestData, result->response);
EXPECT_EQ(media::mojom::GetCollectionsResult::kSuccess,
result->result);
}));
task_environment()->RunUntilIdle();
EXPECT_TRUE(url_loader_factory()->pending_requests()->empty());
// If we change the GAIA id then we should trigger a refetch.
GetService()->GetCollections(
CreateCredentials(), "1234", "abcd",
base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_EQ(kTestData, result->response);
EXPECT_EQ(media::mojom::GetCollectionsResult::kSuccess,
result->result);
}));
task_environment()->RunUntilIdle();
EXPECT_FALSE(url_loader_factory()->pending_requests()->empty());
}
TEST_F(KaleidoscopeServiceTest, ServerFail_Forbidden) {
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_TRUE(result->response.empty());
EXPECT_EQ(media::mojom::GetCollectionsResult::kNotAvailable,
result->result);
}));
WaitForRequest();
ASSERT_TRUE(RespondToFetch("", net::HTTP_FORBIDDEN));
// If we call again then we should hit the cache. HTTP Forbidden is special
// cased because this indicates the user cannot access Kaleidoscope.
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_TRUE(result->response.empty());
EXPECT_EQ(media::mojom::GetCollectionsResult::kNotAvailable,
result->result);
}));
task_environment()->RunUntilIdle();
EXPECT_TRUE(url_loader_factory()->pending_requests()->empty());
}
TEST_F(KaleidoscopeServiceTest, ServerFail) {
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](const std::string& result) { EXPECT_TRUE(result.empty()); }));
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_TRUE(result->response.empty());
EXPECT_EQ(media::mojom::GetCollectionsResult::kFailed,
result->result);
}));
WaitForRequest();
ASSERT_TRUE(RespondToFetch("", net::HTTP_BAD_REQUEST));
// If we call again then we should not hit the cache.
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_TRUE(result->response.empty());
EXPECT_EQ(media::mojom::GetCollectionsResult::kFailed,
result->result);
}));
task_environment()->RunUntilIdle();
EXPECT_FALSE(url_loader_factory()->pending_requests()->empty());
}
TEST_F(KaleidoscopeServiceTest, NetworkFail) {
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](const std::string& result) { EXPECT_TRUE(result.empty()); }));
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_TRUE(result->response.empty());
EXPECT_EQ(media::mojom::GetCollectionsResult::kFailed,
result->result);
}));
WaitForRequest();
ASSERT_TRUE(RespondToFetch("", net::HTTP_OK, net::ERR_UNEXPECTED));
// If we call again then we should not hit the cache.
GetService()->GetCollections(
CreateCredentials(), "123", "abcd",
base::BindLambdaForTesting(
[&](media::mojom::GetCollectionsResponsePtr result) {
EXPECT_TRUE(result->response.empty());
EXPECT_EQ(media::mojom::GetCollectionsResult::kFailed,
result->result);
}));
task_environment()->RunUntilIdle();
EXPECT_FALSE(url_loader_factory()->pending_requests()->empty());
}
} // namespace kaleidoscope
......@@ -88,6 +88,27 @@ interface KaleidoscopeDataProvider {
SendFeedback();
// Gets the collections from the backend to be displayed. Takes a string that
// contains the request to be sent to the server.
GetCollections(string request) => (string response);
// contains the request to be sent to the server. The request is the
// GetCollectionsRequest proto here: go/ks-media-proto.
GetCollections(string request) => (GetCollectionsResponse response);
};
enum GetCollectionsResult {
// The request was successful.
kSuccess,
// The request failed.
kFailed,
// Kaleidoscope is not available to the user.
kNotAvailable,
};
struct GetCollectionsResponse {
// Contains the response from the server. The response is the
// GetCollectionsResponse proto here: go/ks-media-proto.
string response;
// Contains the result of wether the request was successful or not.
GetCollectionsResult result;
};
......@@ -57,6 +57,7 @@ TEST_F('MediaHistoryStatsWebUIBrowserTest', 'MAYBE_All', function() {
assertDeepEquals(
[
['kaleidoscopeData', '0'],
['mediaFeed', '0'],
['mediaFeedItem', '0'],
['mediaImage', '0'],
......
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