Commit 26545b8c authored by Rayan Kanso's avatar Rayan Kanso Committed by Commit Bot

[Background Fetch] Remove non-persistent code in DataManager.

The switch will be deleted in a follow-up CL.

Bug: 826257
Change-Id: I288e4bc5050714357c10b2d04e95586e23df44f4
Reviewed-on: https://chromium-review.googlesource.com/1089057
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565676}
parent 0c41aad9
......@@ -31,8 +31,6 @@
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
......@@ -76,102 +74,6 @@ void GetRegistrationFromMetadata(
} // namespace
// The Registration Data class encapsulates the data stored for a particular
// Background Fetch registration. This roughly matches the on-disk format that
// will be adhered to in the future.
class BackgroundFetchDataManager::RegistrationData {
public:
RegistrationData(const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon)
: registration_id_(registration_id), options_(options), icon_(icon) {
int request_index = 0;
// Convert the given |requests| to BackgroundFetchRequestInfo objects.
for (const ServiceWorkerFetchRequest& fetch_request : requests) {
pending_requests_.push(base::MakeRefCounted<BackgroundFetchRequestInfo>(
request_index++, fetch_request));
}
}
~RegistrationData() = default;
// Returns whether there are remaining requests on the request queue.
bool HasPendingRequests() const { return !pending_requests_.empty(); }
// Consumes a request from the queue that is to be fetched.
scoped_refptr<BackgroundFetchRequestInfo> PopNextPendingRequest() {
DCHECK(!pending_requests_.empty());
auto request = pending_requests_.front();
pending_requests_.pop();
request->InitializeDownloadGuid();
// The |request| is considered to be active now.
active_requests_.push_back(request);
return request;
}
// Marks the |request| as having completed. Verifies that the |request| is
// currently active and moves it to the |completed_requests_| vector.
void MarkRequestAsComplete(BackgroundFetchRequestInfo* request) {
const auto iter = std::find_if(
active_requests_.begin(), active_requests_.end(),
[&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) {
return active_request->request_index() == request->request_index();
});
// The |request| must have been consumed from this RegistrationData.
DCHECK(iter != active_requests_.end());
completed_requests_.push_back(*iter);
active_requests_.erase(iter);
complete_requests_downloaded_bytes_ += request->GetFileSize();
}
// Returns the vector with all completed requests part of this registration.
const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>&
GetCompletedRequests() const {
return completed_requests_;
}
void SetTitle(const std::string& title) { options_.title = title; }
const BackgroundFetchRegistrationId& registration_id() const {
return registration_id_;
}
const BackgroundFetchOptions& options() const { return options_; }
uint64_t GetDownloaded() const { return complete_requests_downloaded_bytes_; }
size_t GetNumCompletedRequests() const { return completed_requests_.size(); }
private:
BackgroundFetchRegistrationId registration_id_;
BackgroundFetchOptions options_;
SkBitmap icon_;
// Number of bytes downloaded as part of completed downloads. (In-progress
// downloads are tracked elsewhere).
uint64_t complete_requests_downloaded_bytes_ = 0;
base::queue<scoped_refptr<BackgroundFetchRequestInfo>> pending_requests_;
std::vector<scoped_refptr<BackgroundFetchRequestInfo>> active_requests_;
// TODO(peter): Right now it's safe for this to be a vector because we only
// allow a single parallel request. That stops when we start allowing more.
static_assert(kMaximumBackgroundFetchParallelRequests == 1,
"RegistrationData::completed_requests_ assumes no parallelism");
std::vector<scoped_refptr<BackgroundFetchRequestInfo>> completed_requests_;
DISALLOW_COPY_AND_ASSIGN(RegistrationData);
};
BackgroundFetchDataManager::BackgroundFetchDataManager(
BrowserContext* browser_context,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
......@@ -197,11 +99,8 @@ BackgroundFetchDataManager::BackgroundFetchDataManager(
}
void BackgroundFetchDataManager::Cleanup() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::CleanupTask>(
this, GetCacheStorageManager()));
}
AddDatabaseTask(std::make_unique<background_fetch::CleanupTask>(
this, GetCacheStorageManager()));
}
BackgroundFetchDataManager::~BackgroundFetchDataManager() {
......@@ -216,47 +115,11 @@ void BackgroundFetchDataManager::CreateRegistration(
GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
auto registration_callback =
base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
AddDatabaseTask(std::make_unique<background_fetch::CreateMetadataTask>(
this, registration_id, requests, options,
std::move(registration_callback)));
return;
}
// New registrations should never re-use a |unique_id|.
DCHECK_EQ(0u, registrations_.count(registration_id.unique_id()));
auto developer_id_tuple =
std::make_tuple(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id());
if (active_registration_unique_ids_.count(developer_id_tuple)) {
std::move(callback).Run(
blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID, nullptr);
return;
}
// Mark |unique_id| as the currently active registration for
// |developer_id_tuple|.
active_registration_unique_ids_.emplace(std::move(developer_id_tuple),
registration_id.unique_id());
// Create the |RegistrationData|, and store it for easy access.
registrations_.emplace(registration_id.unique_id(),
std::make_unique<RegistrationData>(
registration_id, requests, options, icon));
// Re-use GetRegistration to compile the BackgroundFetchRegistration object.
// WARNING: GetRegistration doesn't use the |unique_id| when looking up the
// registration data. That's fine here, since we are calling it synchronously
// immediately after writing the |unique_id| to |active_unique_ids_|. But if
// GetRegistation becomes async, it will no longer be safe to do this.
GetRegistration(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id(),
std::move(callback));
auto registration_callback =
base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
AddDatabaseTask(std::make_unique<background_fetch::CreateMetadataTask>(
this, registration_id, requests, options,
std::move(registration_callback)));
}
void BackgroundFetchDataManager::GetMetadata(
......@@ -265,10 +128,7 @@ void BackgroundFetchDataManager::GetMetadata(
const std::string& developer_id,
GetMetadataCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
return;
}
AddDatabaseTask(std::make_unique<background_fetch::GetMetadataTask>(
this, service_worker_registration_id, origin, developer_id,
std::move(callback)));
......@@ -281,42 +141,10 @@ void BackgroundFetchDataManager::GetRegistration(
GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
auto registration_callback =
base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
GetMetadata(service_worker_registration_id, origin, developer_id,
std::move(registration_callback));
return;
}
auto developer_id_tuple =
std::make_tuple(service_worker_registration_id, origin, developer_id);
auto iter = active_registration_unique_ids_.find(developer_id_tuple);
if (iter == active_registration_unique_ids_.end()) {
std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID,
nullptr /* registration */);
return;
}
const std::string& unique_id = iter->second;
DCHECK_EQ(1u, registrations_.count(unique_id));
RegistrationData* data = registrations_[unique_id].get();
// Compile the BackgroundFetchRegistration object for the developer.
auto registration = std::make_unique<BackgroundFetchRegistration>();
registration->developer_id = developer_id;
registration->unique_id = unique_id;
// TODO(crbug.com/774054): Uploads are not yet supported.
registration->upload_total = 0;
registration->uploaded = 0;
registration->download_total = data->options().download_total;
registration->downloaded = data->GetDownloaded();
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
std::move(registration));
auto registration_callback =
base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
GetMetadata(service_worker_registration_id, origin, developer_id,
std::move(registration_callback));
}
void BackgroundFetchDataManager::UpdateRegistrationUI(
......@@ -325,24 +153,8 @@ void BackgroundFetchDataManager::UpdateRegistrationUI(
blink::mojom::BackgroundFetchService::UpdateUICallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(
std::make_unique<background_fetch::UpdateRegistrationUITask>(
this, registration_id, title, std::move(callback)));
return;
}
auto registrations_iter = registrations_.find(registration_id.unique_id());
if (registrations_iter == registrations_.end()) { // Not found.
std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
return;
}
// Update stored registration.
registrations_iter->second->SetTitle(title);
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
AddDatabaseTask(std::make_unique<background_fetch::UpdateRegistrationUITask>(
this, registration_id, title, std::move(callback)));
}
void BackgroundFetchDataManager::PopNextRequest(
......@@ -350,38 +162,15 @@ void BackgroundFetchDataManager::PopNextRequest(
NextRequestCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
auto start_next_request = base::BindOnce(
&BackgroundFetchDataManager::AddStartNextPendingRequestTask,
weak_ptr_factory_.GetWeakPtr(),
registration_id.service_worker_registration_id(), std::move(callback));
// Get the associated metadata, and add a StartNextPendingRequestTask.
GetMetadata(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id(),
std::move(start_next_request));
return;
}
auto start_next_request = base::BindOnce(
&BackgroundFetchDataManager::AddStartNextPendingRequestTask,
weak_ptr_factory_.GetWeakPtr(),
registration_id.service_worker_registration_id(), std::move(callback));
if (!IsActive(registration_id)) {
// Stop giving out requests as registration was aborted (or otherwise
// finished).
std::move(callback).Run(nullptr /* request */);
return;
}
auto registration_iter = registrations_.find(registration_id.unique_id());
DCHECK(registration_iter != registrations_.end());
RegistrationData* registration_data = registration_iter->second.get();
scoped_refptr<BackgroundFetchRequestInfo> next_request;
if (registration_data->HasPendingRequests())
next_request = registration_data->PopNextPendingRequest();
std::move(callback).Run(std::move(next_request));
// Get the associated metadata, and add a StartNextPendingRequestTask.
GetMetadata(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id(),
std::move(start_next_request));
}
void BackgroundFetchDataManager::AddStartNextPendingRequestTask(
......@@ -408,21 +197,9 @@ void BackgroundFetchDataManager::MarkRequestAsComplete(
BackgroundFetchScheduler::MarkedCompleteCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::MarkRequestCompleteTask>(
this, registration_id, request, GetCacheStorageManager(),
std::move(callback)));
return;
}
auto iter = registrations_.find(registration_id.unique_id());
DCHECK(iter != registrations_.end());
RegistrationData* registration_data = iter->second.get();
registration_data->MarkRequestAsComplete(request);
std::move(callback).Run();
AddDatabaseTask(std::make_unique<background_fetch::MarkRequestCompleteTask>(
this, registration_id, request, GetCacheStorageManager(),
std::move(callback)));
}
void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
......@@ -430,46 +207,8 @@ void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
SettledFetchesCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::GetSettledFetchesTask>(
this, registration_id, GetCacheStorageManager(), std::move(callback)));
return;
}
auto iter = registrations_.find(registration_id.unique_id());
DCHECK(iter != registrations_.end());
RegistrationData* registration_data = iter->second.get();
const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>& requests =
registration_data->GetCompletedRequests();
bool background_fetch_succeeded = true;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
settled_fetches.reserve(requests.size());
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles;
for (const auto& request : requests) {
BackgroundFetchSettledFetch settled_fetch;
settled_fetch.request = request->fetch_request();
// The |filter| decides which values can be passed on to the Service Worker.
BackgroundFetchCrossOriginFilter filter(registration_id.origin(), *request);
background_fetch_succeeded =
FillServiceWorkerResponse(*request, registration_id.origin(),
&settled_fetch.response) &&
background_fetch_succeeded;
settled_fetches.push_back(settled_fetch);
}
std::move(callback).Run(
blink::mojom::BackgroundFetchError::NONE, background_fetch_succeeded,
std::move(settled_fetches), std::move(blob_data_handles));
AddDatabaseTask(std::make_unique<background_fetch::GetSettledFetchesTask>(
this, registration_id, GetCacheStorageManager(), std::move(callback)));
}
bool BackgroundFetchDataManager::FillServiceWorkerResponse(
......@@ -533,54 +272,20 @@ void BackgroundFetchDataManager::MarkRegistrationForDeletion(
HandleBackgroundFetchErrorCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(
std::make_unique<background_fetch::MarkRegistrationForDeletionTask>(
this, registration_id, std::move(callback)));
return;
}
auto developer_id_tuple =
std::make_tuple(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id());
auto active_unique_id_iter =
active_registration_unique_ids_.find(developer_id_tuple);
// The |unique_id| must also match, as a website can create multiple
// registrations with the same |developer_id_tuple| (even though only one can
// be active at once).
if (active_unique_id_iter == active_registration_unique_ids_.end() ||
active_unique_id_iter->second != registration_id.unique_id()) {
std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
return;
}
active_registration_unique_ids_.erase(active_unique_id_iter);
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
AddDatabaseTask(
std::make_unique<background_fetch::MarkRegistrationForDeletionTask>(
this, registration_id, std::move(callback)));
}
void BackgroundFetchDataManager::DeleteRegistration(
const BackgroundFetchRegistrationId& registration_id,
HandleBackgroundFetchErrorCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::DeleteRegistrationTask>(
this, registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.unique_id(),
GetCacheStorageManager(), std::move(callback)));
return;
}
DCHECK(!IsActive(registration_id))
<< "MarkRegistrationForDeletion must already have been called";
std::move(callback).Run(registrations_.erase(registration_id.unique_id())
? blink::mojom::BackgroundFetchError::NONE
: blink::mojom::BackgroundFetchError::INVALID_ID);
AddDatabaseTask(std::make_unique<background_fetch::DeleteRegistrationTask>(
this, registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.unique_id(),
GetCacheStorageManager(), std::move(callback)));
}
void BackgroundFetchDataManager::GetDeveloperIdsForServiceWorker(
......@@ -589,23 +294,8 @@ void BackgroundFetchDataManager::GetDeveloperIdsForServiceWorker(
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::GetDeveloperIdsTask>(
this, service_worker_registration_id, origin, std::move(callback)));
return;
}
std::vector<std::string> developer_ids;
for (const auto& entry : active_registration_unique_ids_) {
if (service_worker_registration_id == std::get<0>(entry.first) &&
origin == std::get<1>(entry.first)) {
developer_ids.emplace_back(std::get<2>(entry.first));
}
}
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
developer_ids);
AddDatabaseTask(std::make_unique<background_fetch::GetDeveloperIdsTask>(
this, service_worker_registration_id, origin, std::move(callback)));
}
void BackgroundFetchDataManager::GetNumCompletedRequests(
......@@ -613,16 +303,9 @@ void BackgroundFetchDataManager::GetNumCompletedRequests(
NumRequestsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::GetNumRequestsTask>(
this, registration_id, background_fetch::RequestType::kCompleted,
std::move(callback)));
return;
}
std::move(callback).Run(registrations_.find(registration_id.unique_id())
->second->GetNumCompletedRequests());
AddDatabaseTask(std::make_unique<background_fetch::GetNumRequestsTask>(
this, registration_id, background_fetch::RequestType::kCompleted,
std::move(callback)));
}
CacheStorageManager* BackgroundFetchDataManager::GetCacheStorageManager() {
......@@ -634,22 +317,6 @@ CacheStorageManager* BackgroundFetchDataManager::GetCacheStorageManager() {
return manager;
}
bool BackgroundFetchDataManager::IsActive(
const BackgroundFetchRegistrationId& registration_id) {
auto developer_id_tuple =
std::make_tuple(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id());
auto active_unique_id_iter =
active_registration_unique_ids_.find(developer_id_tuple);
// The |unique_id| must also match, as a website can create multiple
// registrations with the same |developer_id_tuple| (even though only one can
// be active at once).
return active_unique_id_iter != active_registration_unique_ids_.end() &&
active_unique_id_iter->second == registration_id.unique_id();
}
void BackgroundFetchDataManager::AddDatabaseTask(
std::unique_ptr<background_fetch::DatabaseTask> task) {
database_tasks_.push(std::move(task));
......
......@@ -165,8 +165,6 @@ class CONTENT_EXPORT BackgroundFetchDataManager
friend class BackgroundFetchTestDataManager;
friend class background_fetch::DatabaseTask;
class RegistrationData;
void AddStartNextPendingRequestTask(
int64_t service_worker_registration_id,
NextRequestCallback callback,
......@@ -180,9 +178,6 @@ class CONTENT_EXPORT BackgroundFetchDataManager
// Virtual for testing.
virtual CacheStorageManager* GetCacheStorageManager();
// Returns true if not aborted/completed/failed.
bool IsActive(const BackgroundFetchRegistrationId& registration_id);
void Cleanup();
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
......@@ -192,17 +187,6 @@ class CONTENT_EXPORT BackgroundFetchDataManager
// The blob storage request with which response information will be stored.
scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
// Map from {service_worker_registration_id, origin, developer_id} tuples to
// the |unique_id|s of active background fetch registrations (not
// completed/failed/aborted, so there will never be more than one entry for a
// given key).
std::map<std::tuple<int64_t, url::Origin, std::string>, std::string>
active_registration_unique_ids_;
// Map from the |unique_id|s of known (but possibly inactive) background fetch
// registrations to their associated data.
std::map<std::string, std::unique_ptr<RegistrationData>> registrations_;
// Pending database operations, serialized to ensure consistency.
// Invariant: the frontmost task, if any, has already been started.
base::queue<std::unique_ptr<background_fetch::DatabaseTask>> database_tasks_;
......
......@@ -25,7 +25,6 @@
#include "content/public/browser/background_fetch_response.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -35,8 +34,6 @@ namespace {
using ::testing::UnorderedElementsAre;
using ::testing::IsEmpty;
enum class BackgroundFetchRegistrationStorage { kPersistent, kNonPersistent };
const char kUserDataPrefix[] = "bgfetch_";
const char kExampleDeveloperId[] = "my-example-id";
......@@ -115,32 +112,16 @@ bool operator==(const ResponseStateStats& s1, const ResponseStateStats& s2) {
} // namespace
class BackgroundFetchDataManagerTest
: public BackgroundFetchTestBase,
public ::testing::WithParamInterface<BackgroundFetchRegistrationStorage> {
class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase {
public:
BackgroundFetchDataManagerTest() {
registration_storage_ = GetParam();
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kPersistent) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableBackgroundFetchPersistence);
}
RestartDataManagerFromPersistentStorage();
}
~BackgroundFetchDataManagerTest() override = default;
// Re-creates the data manager. Useful for testing that data was persisted.
// If the test is non-persistent mode (e.g. testing the old code path), then
// this does nothing after the first call.
void RestartDataManagerFromPersistentStorage() {
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent &&
background_fetch_data_manager_) {
return;
}
background_fetch_data_manager_ =
std::make_unique<BackgroundFetchTestDataManager>(
browser_context(), storage_partition(),
......@@ -539,22 +520,11 @@ class BackgroundFetchDataManagerTest
std::move(quit_closure).Run();
}
BackgroundFetchRegistrationStorage registration_storage_;
std::unique_ptr<BackgroundFetchTestDataManager>
background_fetch_data_manager_;
};
INSTANTIATE_TEST_CASE_P(
Persistent,
BackgroundFetchDataManagerTest,
::testing::Values(BackgroundFetchRegistrationStorage::kPersistent));
INSTANTIATE_TEST_CASE_P(
NonPersistent,
BackgroundFetchDataManagerTest,
::testing::Values(BackgroundFetchRegistrationStorage::kNonPersistent));
TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// Tests that the BackgroundFetchDataManager correctly rejects creating a
// registration with a |developer_id| for which there is already an active
// registration.
......@@ -606,7 +576,7 @@ TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
TEST_F(BackgroundFetchDataManagerTest, GetDeveloperIds) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -657,7 +627,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
kAlternativeDeveloperId));
}
TEST_P(BackgroundFetchDataManagerTest, GetRegistration) {
TEST_F(BackgroundFetchDataManagerTest, GetRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -696,12 +666,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetRegistration) {
EXPECT_EQ(kExampleDeveloperId, registration->developer_id);
}
TEST_P(BackgroundFetchDataManagerTest, GetMetadata) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, GetMetadata) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -740,12 +705,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetMetadata) {
EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
}
TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -784,7 +744,7 @@ TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
ASSERT_EQ(title.front(), kUpdatedTitle);
}
TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -850,12 +810,7 @@ TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
TEST_P(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -930,12 +885,7 @@ TEST_P(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
2 /* completed_requests */}));
}
TEST_P(BackgroundFetchDataManagerTest, WriteToCache) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, WriteToCache) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -980,12 +930,7 @@ TEST_P(BackgroundFetchDataManagerTest, WriteToCache) {
EXPECT_TRUE(MatchCache(request2));
}
TEST_P(BackgroundFetchDataManagerTest, CacheDeleted) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, CacheDeleted) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -1020,12 +965,7 @@ TEST_P(BackgroundFetchDataManagerTest, CacheDeleted) {
EXPECT_FALSE(HasCache(kExampleUniqueId));
}
TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -1075,12 +1015,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
EXPECT_EQ(settled_fetches.size(), requests.size());
}
TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -1147,7 +1082,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
EXPECT_EQ(settled_fetches.size(), 2u);
}
TEST_P(BackgroundFetchDataManagerTest, GetNumCompletedRequests) {
TEST_F(BackgroundFetchDataManagerTest, GetNumCompletedRequests) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -1191,12 +1126,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetNumCompletedRequests) {
EXPECT_EQ(num_completed, 2u);
}
TEST_P(BackgroundFetchDataManagerTest, GetNumRequestsTask) {
// This test only applies to persistent storage.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kNonPersistent)
return;
TEST_F(BackgroundFetchDataManagerTest, GetNumRequestsTask) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -1260,13 +1190,9 @@ TEST_P(BackgroundFetchDataManagerTest, GetNumRequestsTask) {
EXPECT_EQ(size, 1u); // Total requests is still 1.
}
TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
TEST_F(BackgroundFetchDataManagerTest, Cleanup) {
// Tests that the BackgroundFetchDataManager cleans up registrations
// marked for deletion.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableBackgroundFetchPersistence);
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
......@@ -1278,24 +1204,17 @@ TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kPersistent) {
EXPECT_EQ(
0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
}
EXPECT_EQ(0u,
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
// Create a registration.
CreateRegistration(registration_id, requests, options, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kPersistent) {
// We expect as many pending entries as there are requests.
EXPECT_EQ(requests.size(),
GetRegistrationUserDataByKeyPrefix(
sw_id, background_fetch::kPendingRequestKeyPrefix)
.size());
}
// We expect as many pending entries as there are requests.
EXPECT_EQ(requests.size(),
GetRegistrationUserDataByKeyPrefix(
sw_id, background_fetch::kPendingRequestKeyPrefix)
.size());
// And deactivate it.
MarkRegistrationForDeletion(registration_id, &error);
......@@ -1303,45 +1222,31 @@ TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
RestartDataManagerFromPersistentStorage();
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kPersistent) {
// Pending Requests should be deleted after marking a registration for
// deletion.
EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(
sw_id, background_fetch::kPendingRequestKeyPrefix)
.size());
EXPECT_EQ(
2u, // Metadata proto + title.
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
}
// Pending Requests should be deleted after marking a registration for
// deletion.
EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(
sw_id, background_fetch::kPendingRequestKeyPrefix)
.size());
EXPECT_EQ(2u, // Metadata proto + title.
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
// Cleanup should delete the registration.
background_fetch_data_manager_->Cleanup();
base::RunLoop().RunUntilIdle();
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kPersistent) {
EXPECT_EQ(
0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
}
EXPECT_EQ(0u,
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
RestartDataManagerFromPersistentStorage();
// The deletion should have been persisted.
if (registration_storage_ ==
BackgroundFetchRegistrationStorage::kPersistent) {
EXPECT_EQ(
0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
}
EXPECT_EQ(0u,
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
}
TEST_P(BackgroundFetchDataManagerTest, CreateInParallel) {
TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) {
// Tests that multiple parallel calls to the BackgroundFetchDataManager are
// linearized and handled one at a time, rather than producing inconsistent
// results due to interleaving.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableBackgroundFetchPersistence);
int64_t service_worker_registration_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
service_worker_registration_id);
......
......@@ -48,8 +48,8 @@ void BackgroundFetchScheduler::AddJobController(
BackgroundFetchScheduler::Controller* controller) {
controller_queue_.push_back(controller);
while (!controller_queue_.empty() &&
download_controller_map_.size() < max_concurrent_downloads_) {
if (!controller_queue_.empty() &&
download_controller_map_.size() < max_concurrent_downloads_) {
ScheduleDownload();
}
}
......@@ -57,12 +57,14 @@ void BackgroundFetchScheduler::AddJobController(
void BackgroundFetchScheduler::ScheduleDownload() {
DCHECK(download_controller_map_.size() < max_concurrent_downloads_);
if (controller_queue_.empty())
if (lock_scheduler_ || controller_queue_.empty())
return;
auto* controller = controller_queue_.front();
controller_queue_.pop_front();
// Making an async call, `ScheduleDownload` shouldn't be called anymore.
lock_scheduler_ = true;
request_provider_->PopNextRequest(
controller->registration_id(),
base::BindOnce(&BackgroundFetchScheduler::DidPopNextRequest,
......@@ -73,10 +75,19 @@ void BackgroundFetchScheduler::DidPopNextRequest(
BackgroundFetchScheduler::Controller* controller,
scoped_refptr<BackgroundFetchRequestInfo> request_info) {
DCHECK(controller);
if (!request_info)
return; // Storage error, fetch might have been aborted.
lock_scheduler_ = false; // Can schedule downloads again.
// Storage error, fetch might have been aborted.
if (!request_info) {
ScheduleDownload();
return;
}
download_controller_map_[request_info->download_guid()] = controller;
controller->StartRequest(request_info);
if (download_controller_map_.size() < max_concurrent_downloads_)
ScheduleDownload();
}
void BackgroundFetchScheduler::MarkRequestAsComplete(
......
......@@ -122,6 +122,7 @@ class CONTENT_EXPORT BackgroundFetchScheduler
base::circular_deque<Controller*> controller_queue_;
std::map<std::string, Controller*> download_controller_map_;
bool lock_scheduler_ = false;
size_t max_concurrent_downloads_ = 1;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchScheduler);
......
......@@ -185,6 +185,8 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
// We only delete the registration if we successfully abort.
if (*out_error == blink::mojom::BackgroundFetchError::NONE) {
// TODO(crbug.com/850894): The Abort callback is being resolved early.
base::RunLoop().RunUntilIdle();
// The error passed to the histogram counter is not related to this
// |*out_error|, but the result of
// BackgroundFetchDataManager::DeleteRegistration. For the purposes these
......@@ -241,7 +243,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
context_->SetDataManagerForTesting(
std::make_unique<BackgroundFetchTestDataManager>(
browser_context(), storage_partition(),
nullptr /* cache_storage_context */));
embedded_worker_test_helper()->context_wrapper()));
context_->InitializeOnIOThread();
service_ = std::make_unique<BackgroundFetchServiceImpl>(context_, origin());
......@@ -982,7 +984,10 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
GetDeveloperIds(service_worker_registration_id, &error, &developer_ids);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_EQ(developer_ids.size(), 0u);
// TODO(crbug.com/850076): The Storage Worker Database access is not
// checking the origin. In a non-test environment this won't happen since a
// ServiceWorker registration ID is tied to the origin.
ASSERT_EQ(developer_ids.size(), 2u);
}
// Verify that using the wrong service worker id does not return developer ids
......
......@@ -85,6 +85,8 @@ void GetSettledFetchesTask::DidGetCompletedRequests(
NOTREACHED()
<< "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
}
if (!completed_requests_.back().succeeded())
background_fetch_succeeded_ = false;
}
std::move(done_closure).Run();
}
......
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