Move SpecialStoragePolicy from ServiceWorkerStorage to ServiceWorkerRegistry
(This is similar to crrev.com/c/1945940 but for ServiceWorkerStorage) ServiceWorkerStorage wouldn't be able to depend on SpecialStoragePolicy directly once it is moved to the Storage Service. This CL removes SpecialStoragePolicy dependency from ServiceWorkerStorage by doing the following: * Manage registered origins in ServiceWorkerRegistry. ServiceWorkerRegistry retrieves registered origins from storage at startup. * Add SpecialStoragePolicy::Observer which notifies policy changes to ServiceWorkerRegistry. * Add ServiceWorkerStorage::ApplyPolicyUpdates() which is called when policies change. This method will become a mojo method once ServiceWorkerStorage is encapsulated into a mojo interface. The above have an assumption to work properly: there won't be more than one embedder/browser which try to update policies. If there are two embedders/browser which update policies, an update may be lost. Bug: 1055677 Change-Id: I773e51da772e399c5fba40926045d6f2deb6908b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2087248 Commit-Queue: Kenichi Ishibashi <bashi@chromium.org> Reviewed-by: Kinuko Yasuda <kinuko@chromium.org> Reviewed-by: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Makoto Shimazu <shimazu@chromium.org> Reviewed-by: Ken Rockot <rockot@google.com> Cr-Commit-Position: refs/heads/master@{#749990}
This commit is contained in:

committed by
Commit Bot

parent
138e14205b
commit
a7b42d7fe6
@ -26,6 +26,12 @@ namespace content {
|
||||
|
||||
EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
|
||||
const base::FilePath& user_data_directory)
|
||||
: EmbeddedWorkerTestHelper(user_data_directory,
|
||||
/*special_storage_policy=*/nullptr) {}
|
||||
|
||||
EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
|
||||
const base::FilePath& user_data_directory,
|
||||
storage::SpecialStoragePolicy* special_storage_policy)
|
||||
: browser_context_(std::make_unique<TestBrowserContext>()),
|
||||
render_process_host_(
|
||||
std::make_unique<MockRenderProcessHost>(browser_context_.get())),
|
||||
@ -41,8 +47,9 @@ EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
|
||||
scoped_refptr<base::SequencedTaskRunner> database_task_runner =
|
||||
base::ThreadTaskRunnerHandle::Get();
|
||||
wrapper_->InitOnCoreThread(
|
||||
user_data_directory, std::move(database_task_runner), nullptr, nullptr,
|
||||
nullptr, url_loader_factory_getter_.get(),
|
||||
user_data_directory, std::move(database_task_runner),
|
||||
/*quota_manager_proxy=*/nullptr, special_storage_policy, nullptr,
|
||||
url_loader_factory_getter_.get(),
|
||||
blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled()
|
||||
? wrapper_
|
||||
->CreateNonNetworkPendingURLLoaderFactoryBundleForUpdateCheck(
|
||||
|
@ -74,6 +74,9 @@ class EmbeddedWorkerTestHelper {
|
||||
// If |user_data_directory| is empty, the context makes storage stuff in
|
||||
// memory.
|
||||
explicit EmbeddedWorkerTestHelper(const base::FilePath& user_data_directory);
|
||||
EmbeddedWorkerTestHelper(
|
||||
const base::FilePath& user_data_directory,
|
||||
storage::SpecialStoragePolicy* special_storage_policy);
|
||||
virtual ~EmbeddedWorkerTestHelper();
|
||||
|
||||
ServiceWorkerContextCore* context();
|
||||
|
@ -9,12 +9,18 @@
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "components/services/storage/public/mojom/local_storage_control.mojom.h"
|
||||
#include "content/browser/service_worker/service_worker_context_core.h"
|
||||
#include "content/browser/service_worker/service_worker_context_wrapper.h"
|
||||
#include "content/browser/service_worker/service_worker_info.h"
|
||||
#include "content/browser/service_worker/service_worker_registration.h"
|
||||
#include "content/browser/service_worker/service_worker_version.h"
|
||||
#include "content/common/service_worker/service_worker_utils.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "storage/browser/quota/special_storage_policy.h"
|
||||
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
|
||||
|
||||
namespace content {
|
||||
@ -75,6 +81,39 @@ void CompleteFindSoon(
|
||||
|
||||
} // namespace
|
||||
|
||||
// A helper class that runs on the IO thread to observe storage policy updates.
|
||||
class ServiceWorkerRegistry::StoragePolicyObserver
|
||||
: public storage::SpecialStoragePolicy::Observer {
|
||||
public:
|
||||
StoragePolicyObserver(
|
||||
base::WeakPtr<ServiceWorkerRegistry> owner,
|
||||
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy)
|
||||
: owner_(owner), special_storage_policy_(special_storage_policy) {
|
||||
DCHECK(special_storage_policy_);
|
||||
special_storage_policy_->AddObserver(this);
|
||||
}
|
||||
|
||||
StoragePolicyObserver(const StoragePolicyObserver&) = delete;
|
||||
StoragePolicyObserver& operator=(const StoragePolicyObserver&) = delete;
|
||||
|
||||
~StoragePolicyObserver() override {
|
||||
special_storage_policy_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
private:
|
||||
// storage::SpecialStoragePolicy::Observer:
|
||||
void OnPolicyChanged() override {
|
||||
ServiceWorkerContextWrapper::RunOrPostTaskOnCoreThread(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&ServiceWorkerRegistry::OnStoragePolicyChanged, owner_));
|
||||
}
|
||||
|
||||
// |owner_| is dereferenced on the core thread. This shouldn't be dereferenced
|
||||
// on the IO thread.
|
||||
base::WeakPtr<ServiceWorkerRegistry> owner_;
|
||||
const scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
|
||||
};
|
||||
|
||||
ServiceWorkerRegistry::ServiceWorkerRegistry(
|
||||
const base::FilePath& user_data_directory,
|
||||
ServiceWorkerContextCore* context,
|
||||
@ -84,19 +123,22 @@ ServiceWorkerRegistry::ServiceWorkerRegistry(
|
||||
: context_(context),
|
||||
storage_(ServiceWorkerStorage::Create(user_data_directory,
|
||||
std::move(database_task_runner),
|
||||
quota_manager_proxy,
|
||||
special_storage_policy)) {
|
||||
quota_manager_proxy)),
|
||||
special_storage_policy_(special_storage_policy) {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
DCHECK(context_);
|
||||
Start();
|
||||
}
|
||||
|
||||
ServiceWorkerRegistry::ServiceWorkerRegistry(
|
||||
ServiceWorkerContextCore* context,
|
||||
ServiceWorkerRegistry* old_registry)
|
||||
: context_(context),
|
||||
storage_(ServiceWorkerStorage::Create(old_registry->storage())) {
|
||||
storage_(ServiceWorkerStorage::Create(old_registry->storage())),
|
||||
special_storage_policy_(old_registry->special_storage_policy_) {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
DCHECK(context_);
|
||||
Start();
|
||||
}
|
||||
|
||||
ServiceWorkerRegistry::~ServiceWorkerRegistry() = default;
|
||||
@ -362,7 +404,7 @@ void ServiceWorkerRegistry::DeleteRegistration(
|
||||
storage()->DeleteRegistration(
|
||||
registration->id(), origin,
|
||||
base::BindOnce(&ServiceWorkerRegistry::DidDeleteRegistration,
|
||||
weak_factory_.GetWeakPtr(), registration->id(),
|
||||
weak_factory_.GetWeakPtr(), registration->id(), origin,
|
||||
std::move(callback)));
|
||||
|
||||
DCHECK(!base::Contains(uninstalling_registrations_, registration->id()));
|
||||
@ -685,6 +727,20 @@ void ServiceWorkerRegistry::DisableDeleteAndStartOverForTesting() {
|
||||
is_storage_disabled_ = true;
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistry::Start() {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
if (special_storage_policy_) {
|
||||
storage_policy_observer_ = base::SequenceBound<StoragePolicyObserver>(
|
||||
base::CreateSequencedTaskRunner(BrowserThread::IO),
|
||||
weak_factory_.GetWeakPtr(),
|
||||
base::WrapRefCounted(special_storage_policy_.get()));
|
||||
|
||||
storage()->GetRegisteredOrigins(
|
||||
base::BindOnce(&ServiceWorkerRegistry::DidGetRegisteredOriginsOnStartup,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
}
|
||||
|
||||
ServiceWorkerRegistration*
|
||||
ServiceWorkerRegistry::FindInstallingRegistrationForClientUrl(
|
||||
const GURL& client_url) {
|
||||
@ -1097,13 +1153,21 @@ void ServiceWorkerRegistry::DidStoreRegistration(
|
||||
}
|
||||
context_->NotifyRegistrationStored(stored_registration_id, stored_scope);
|
||||
|
||||
if (special_storage_policy_) {
|
||||
EnsureRegisteredOriginIsTracked(
|
||||
url::Origin::Create(stored_scope.GetOrigin()));
|
||||
OnStoragePolicyChanged();
|
||||
}
|
||||
|
||||
std::move(callback).Run(status);
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistry::DidDeleteRegistration(
|
||||
int64_t registration_id,
|
||||
const GURL& origin,
|
||||
StatusCallback callback,
|
||||
storage::mojom::ServiceWorkerDatabaseStatus database_status,
|
||||
ServiceWorkerStorage::OriginState origin_state,
|
||||
int64_t deleted_version_id,
|
||||
const std::vector<int64_t>& newly_purgeable_resources) {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
@ -1124,6 +1188,11 @@ void ServiceWorkerRegistry::DidDeleteRegistration(
|
||||
if (registration)
|
||||
registration->UnsetStored();
|
||||
|
||||
if (special_storage_policy_ &&
|
||||
origin_state == ServiceWorkerStorage::OriginState::kDelete) {
|
||||
tracked_origins_for_policy_update_.erase(url::Origin::Create(origin));
|
||||
}
|
||||
|
||||
std::move(callback).Run(status);
|
||||
}
|
||||
|
||||
@ -1256,4 +1325,48 @@ void ServiceWorkerRegistry::ScheduleDeleteAndStartOver() {
|
||||
DCHECK(is_storage_disabled_);
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistry::DidGetRegisteredOriginsOnStartup(
|
||||
std::vector<url::Origin> origins) {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
for (const auto& origin : origins)
|
||||
EnsureRegisteredOriginIsTracked(origin);
|
||||
OnStoragePolicyChanged();
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistry::EnsureRegisteredOriginIsTracked(
|
||||
const url::Origin& origin) {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
auto it = tracked_origins_for_policy_update_.find(origin);
|
||||
if (it == tracked_origins_for_policy_update_.end())
|
||||
tracked_origins_for_policy_update_[origin] = {};
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistry::OnStoragePolicyChanged() {
|
||||
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
|
||||
if (is_storage_disabled_)
|
||||
return;
|
||||
|
||||
std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates;
|
||||
for (auto& entry : tracked_origins_for_policy_update_) {
|
||||
const url::Origin& origin = entry.first;
|
||||
StorageOriginState& state = entry.second;
|
||||
state.should_purge_on_shutdown = ShouldPurgeOnShutdown(origin);
|
||||
if (state.should_purge_on_shutdown != state.will_purge_on_shutdown) {
|
||||
state.will_purge_on_shutdown = state.should_purge_on_shutdown;
|
||||
policy_updates.push_back(storage::mojom::LocalStoragePolicyUpdate::New(
|
||||
origin, state.should_purge_on_shutdown));
|
||||
}
|
||||
}
|
||||
|
||||
if (!policy_updates.empty())
|
||||
storage()->ApplyPolicyUpdates(std::move(policy_updates));
|
||||
}
|
||||
|
||||
bool ServiceWorkerRegistry::ShouldPurgeOnShutdown(const url::Origin& origin) {
|
||||
if (!special_storage_policy_)
|
||||
return false;
|
||||
return special_storage_policy_->IsStorageSessionOnly(origin.GetURL()) &&
|
||||
!special_storage_policy_->IsStorageProtected(origin.GetURL());
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
|
@ -28,6 +28,9 @@ namespace content {
|
||||
class ServiceWorkerContextCore;
|
||||
class ServiceWorkerVersion;
|
||||
|
||||
class ServiceWorkerRegistryTest;
|
||||
FORWARD_DECLARE_TEST(ServiceWorkerRegistryTest, StoragePolicyChange);
|
||||
|
||||
// This class manages in-memory representation of service worker registrations
|
||||
// (i.e., ServiceWorkerRegistration) including installing and uninstalling
|
||||
// registrations. The instance of this class is owned by
|
||||
@ -231,6 +234,11 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
|
||||
void DisableDeleteAndStartOverForTesting();
|
||||
|
||||
private:
|
||||
friend class ServiceWorkerRegistryTest;
|
||||
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerRegistryTest, StoragePolicyChange);
|
||||
|
||||
void Start();
|
||||
|
||||
ServiceWorkerRegistration* FindInstallingRegistrationForClientUrl(
|
||||
const GURL& client_url);
|
||||
ServiceWorkerRegistration* FindInstallingRegistrationForScope(
|
||||
@ -288,8 +296,10 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
|
||||
const std::vector<int64_t>& newly_purgeable_resources);
|
||||
void DidDeleteRegistration(
|
||||
int64_t registration_id,
|
||||
const GURL& origin,
|
||||
StatusCallback callback,
|
||||
storage::mojom::ServiceWorkerDatabaseStatus database_status,
|
||||
ServiceWorkerStorage::OriginState origin_state,
|
||||
int64_t deleted_version_id,
|
||||
const std::vector<int64_t>& newly_purgeable_resources);
|
||||
|
||||
@ -330,12 +340,32 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
|
||||
|
||||
void ScheduleDeleteAndStartOver();
|
||||
|
||||
// TODO(bashi): Consider introducing a helper class that handles the below.
|
||||
// These are almost the same as DOMStorageContextWrapper.
|
||||
void DidGetRegisteredOriginsOnStartup(std::vector<url::Origin> origins);
|
||||
void EnsureRegisteredOriginIsTracked(const url::Origin& origin);
|
||||
void OnStoragePolicyChanged();
|
||||
bool ShouldPurgeOnShutdown(const url::Origin& origin);
|
||||
|
||||
// The ServiceWorkerContextCore object must outlive this.
|
||||
ServiceWorkerContextCore* const context_;
|
||||
|
||||
std::unique_ptr<ServiceWorkerStorage> storage_;
|
||||
bool is_storage_disabled_ = false;
|
||||
|
||||
const scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
|
||||
class StoragePolicyObserver;
|
||||
base::SequenceBound<StoragePolicyObserver> storage_policy_observer_;
|
||||
|
||||
// TODO(bashi): Avoid duplication. Merge this with LocalStorageOriginState.
|
||||
struct StorageOriginState {
|
||||
bool should_purge_on_shutdown = false;
|
||||
bool will_purge_on_shutdown = false;
|
||||
};
|
||||
// IMPORTANT: Don't use this other than updating storage policies. This can
|
||||
// be out of sync with |registered_origins_| in ServiceWorkerStorage.
|
||||
std::map<url::Origin, StorageOriginState> tracked_origins_for_policy_update_;
|
||||
|
||||
// For finding registrations being installed or uninstalled.
|
||||
using RegistrationRefsById =
|
||||
std::map<int64_t, scoped_refptr<ServiceWorkerRegistration>>;
|
||||
|
@ -0,0 +1,96 @@
|
||||
// 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 "content/browser/service_worker/service_worker_registry.h"
|
||||
|
||||
#include "base/test/bind_test_util.h"
|
||||
#include "content/browser/service_worker/embedded_worker_test_helper.h"
|
||||
#include "content/browser/service_worker/service_worker_context_core.h"
|
||||
#include "content/browser/service_worker/service_worker_test_utils.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "content/public/test/test_browser_context.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "storage/browser/test/mock_special_storage_policy.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
class ServiceWorkerRegistryTest : public testing::Test {
|
||||
public:
|
||||
ServiceWorkerRegistryTest()
|
||||
: task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {}
|
||||
|
||||
void SetUp() override {
|
||||
CHECK(user_data_directory_.CreateUniqueTempDir());
|
||||
user_data_directory_path_ = user_data_directory_.GetPath();
|
||||
special_storage_policy_ =
|
||||
base::MakeRefCounted<storage::MockSpecialStoragePolicy>();
|
||||
helper_ = std::make_unique<EmbeddedWorkerTestHelper>(
|
||||
user_data_directory_path_, special_storage_policy_.get());
|
||||
registry()->storage()->LazyInitializeForTest();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
helper_.reset();
|
||||
disk_cache::FlushCacheThreadForTesting();
|
||||
content::RunAllTasksUntilIdle();
|
||||
}
|
||||
|
||||
ServiceWorkerContextCore* context() { return helper_->context(); }
|
||||
ServiceWorkerRegistry* registry() { return context()->registry(); }
|
||||
|
||||
storage::MockSpecialStoragePolicy* special_storage_policy() {
|
||||
return special_storage_policy_.get();
|
||||
}
|
||||
|
||||
blink::ServiceWorkerStatusCode StoreRegistration(
|
||||
scoped_refptr<ServiceWorkerRegistration> registration,
|
||||
scoped_refptr<ServiceWorkerVersion> version) {
|
||||
blink::ServiceWorkerStatusCode result;
|
||||
base::RunLoop loop;
|
||||
registry()->StoreRegistration(
|
||||
registration.get(), version.get(),
|
||||
base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status) {
|
||||
result = status;
|
||||
loop.Quit();
|
||||
}));
|
||||
loop.Run();
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
// |user_data_directory_| must be declared first to preserve destructor order.
|
||||
base::ScopedTempDir user_data_directory_;
|
||||
base::FilePath user_data_directory_path_;
|
||||
|
||||
BrowserTaskEnvironment task_environment_;
|
||||
scoped_refptr<storage::MockSpecialStoragePolicy> special_storage_policy_;
|
||||
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
|
||||
};
|
||||
|
||||
// Tests that storage policy changes are observed.
|
||||
TEST_F(ServiceWorkerRegistryTest, StoragePolicyChange) {
|
||||
const GURL kScope("http://www.example.com/scope/");
|
||||
const GURL kScriptUrl("http://www.example.com/script.js");
|
||||
const auto kOrigin(url::Origin::Create(kScope));
|
||||
|
||||
scoped_refptr<ServiceWorkerRegistration> registration =
|
||||
CreateServiceWorkerRegistrationAndVersion(context(), kScope, kScriptUrl,
|
||||
/*resource_id=*/1);
|
||||
|
||||
ASSERT_EQ(StoreRegistration(registration, registration->waiting_version()),
|
||||
blink::ServiceWorkerStatusCode::kOk);
|
||||
EXPECT_FALSE(registry()->ShouldPurgeOnShutdown(kOrigin));
|
||||
|
||||
{
|
||||
// Update storage policy to mark the origin should be purged on shutdown.
|
||||
special_storage_policy()->AddSessionOnly(kOrigin.GetURL());
|
||||
special_storage_policy()->NotifyPolicyChanged();
|
||||
base::RunLoop().RunUntilIdle();
|
||||
}
|
||||
|
||||
EXPECT_TRUE(registry()->ShouldPurgeOnShutdown(kOrigin));
|
||||
}
|
||||
|
||||
} // namespace content
|
@ -29,7 +29,6 @@
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "storage/browser/quota/quota_manager_proxy.h"
|
||||
#include "storage/browser/quota/special_storage_policy.h"
|
||||
#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
|
||||
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
|
||||
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
|
||||
@ -93,11 +92,10 @@ ServiceWorkerStorage::~ServiceWorkerStorage() {
|
||||
std::unique_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create(
|
||||
const base::FilePath& user_data_directory,
|
||||
scoped_refptr<base::SequencedTaskRunner> database_task_runner,
|
||||
storage::QuotaManagerProxy* quota_manager_proxy,
|
||||
storage::SpecialStoragePolicy* special_storage_policy) {
|
||||
storage::QuotaManagerProxy* quota_manager_proxy) {
|
||||
return base::WrapUnique(new ServiceWorkerStorage(
|
||||
user_data_directory, std::move(database_task_runner), quota_manager_proxy,
|
||||
special_storage_policy));
|
||||
user_data_directory, std::move(database_task_runner),
|
||||
quota_manager_proxy));
|
||||
}
|
||||
|
||||
// static
|
||||
@ -105,8 +103,29 @@ std::unique_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create(
|
||||
ServiceWorkerStorage* old_storage) {
|
||||
return base::WrapUnique(new ServiceWorkerStorage(
|
||||
old_storage->user_data_directory_, old_storage->database_task_runner_,
|
||||
old_storage->quota_manager_proxy_.get(),
|
||||
old_storage->special_storage_policy_.get()));
|
||||
old_storage->quota_manager_proxy_.get()));
|
||||
}
|
||||
|
||||
void ServiceWorkerStorage::GetRegisteredOrigins(
|
||||
GetRegisteredOriginsCallback callback) {
|
||||
switch (state_) {
|
||||
case STORAGE_STATE_DISABLED:
|
||||
std::move(callback).Run(/*origins=*/std::vector<url::Origin>());
|
||||
return;
|
||||
case STORAGE_STATE_INITIALIZING: // Fall-through.
|
||||
case STORAGE_STATE_UNINITIALIZED:
|
||||
LazyInitialize(base::BindOnce(&ServiceWorkerStorage::GetRegisteredOrigins,
|
||||
weak_factory_.GetWeakPtr(),
|
||||
std::move(callback)));
|
||||
return;
|
||||
case STORAGE_STATE_INITIALIZED:
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<url::Origin> origins;
|
||||
for (const auto& origin : registered_origins_)
|
||||
origins.push_back(url::Origin::Create(origin));
|
||||
std::move(callback).Run(std::move(origins));
|
||||
}
|
||||
|
||||
void ServiceWorkerStorage::FindRegistrationForClientUrl(
|
||||
@ -876,11 +895,21 @@ void ServiceWorkerStorage::PurgeResources(
|
||||
StartPurgingResources(resource_ids);
|
||||
}
|
||||
|
||||
void ServiceWorkerStorage::ApplyPolicyUpdates(
|
||||
std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates) {
|
||||
for (const auto& update : policy_updates) {
|
||||
GURL url = update->origin.GetURL();
|
||||
if (!update->purge_on_shutdown)
|
||||
origins_to_purge_on_shutdown_.erase(url);
|
||||
else
|
||||
origins_to_purge_on_shutdown_.insert(std::move(url));
|
||||
}
|
||||
}
|
||||
|
||||
ServiceWorkerStorage::ServiceWorkerStorage(
|
||||
const base::FilePath& user_data_directory,
|
||||
scoped_refptr<base::SequencedTaskRunner> database_task_runner,
|
||||
storage::QuotaManagerProxy* quota_manager_proxy,
|
||||
storage::SpecialStoragePolicy* special_storage_policy)
|
||||
storage::QuotaManagerProxy* quota_manager_proxy)
|
||||
: next_registration_id_(blink::mojom::kInvalidServiceWorkerRegistrationId),
|
||||
next_version_id_(blink::mojom::kInvalidServiceWorkerVersionId),
|
||||
next_resource_id_(blink::mojom::kInvalidServiceWorkerResourceId),
|
||||
@ -889,7 +918,6 @@ ServiceWorkerStorage::ServiceWorkerStorage(
|
||||
user_data_directory_(user_data_directory),
|
||||
database_task_runner_(std::move(database_task_runner)),
|
||||
quota_manager_proxy_(quota_manager_proxy),
|
||||
special_storage_policy_(special_storage_policy),
|
||||
is_purge_pending_(false),
|
||||
has_checked_for_stale_resources_(false) {
|
||||
database_.reset(new ServiceWorkerDatabase(GetDatabasePath()));
|
||||
@ -1026,7 +1054,7 @@ void ServiceWorkerStorage::DidDeleteRegistration(
|
||||
ServiceWorkerDatabase::Status status) {
|
||||
if (status != ServiceWorkerDatabase::Status::kOk) {
|
||||
std::move(params->callback)
|
||||
.Run(status, deleted_version.version_id,
|
||||
.Run(status, origin_state, deleted_version.version_id,
|
||||
deleted_version.newly_purgeable_resources);
|
||||
return;
|
||||
}
|
||||
@ -1044,7 +1072,8 @@ void ServiceWorkerStorage::DidDeleteRegistration(
|
||||
registered_origins_.erase(params->origin);
|
||||
|
||||
std::move(params->callback)
|
||||
.Run(ServiceWorkerDatabase::Status::kOk, deleted_version.version_id,
|
||||
.Run(ServiceWorkerDatabase::Status::kOk, origin_state,
|
||||
deleted_version.version_id,
|
||||
deleted_version.newly_purgeable_resources);
|
||||
}
|
||||
|
||||
@ -1205,25 +1234,9 @@ void ServiceWorkerStorage::DidCollectStaleResources(
|
||||
}
|
||||
|
||||
void ServiceWorkerStorage::ClearSessionOnlyOrigins() {
|
||||
// Can be null in tests.
|
||||
if (!special_storage_policy_)
|
||||
return;
|
||||
|
||||
if (!special_storage_policy_->HasSessionOnlyOrigins())
|
||||
return;
|
||||
|
||||
std::set<GURL> session_only_origins;
|
||||
for (const GURL& origin : registered_origins_) {
|
||||
if (!special_storage_policy_->IsStorageSessionOnly(origin))
|
||||
continue;
|
||||
if (special_storage_policy_->IsStorageProtected(origin))
|
||||
continue;
|
||||
session_only_origins.insert(origin);
|
||||
}
|
||||
|
||||
database_task_runner_->PostTask(
|
||||
FROM_HERE, base::BindOnce(&DeleteAllDataForOriginsFromDB, database_.get(),
|
||||
session_only_origins));
|
||||
origins_to_purge_on_shutdown_));
|
||||
}
|
||||
|
||||
int64_t ServiceWorkerStorage::NewRegistrationId() {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "components/services/storage/public/mojom/local_storage_control.mojom.h"
|
||||
#include "content/browser/service_worker/service_worker_database.h"
|
||||
#include "content/browser/service_worker/service_worker_metrics.h"
|
||||
#include "content/common/content_export.h"
|
||||
@ -32,7 +33,6 @@ class SequencedTaskRunner;
|
||||
|
||||
namespace storage {
|
||||
class QuotaManagerProxy;
|
||||
class SpecialStoragePolicy;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
@ -64,10 +64,19 @@ FORWARD_DECLARE_TEST(ServiceWorkerStorageTest, DisabledStorage);
|
||||
// See the toplevel description of ServiceWorkerRegistry.
|
||||
class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
public:
|
||||
enum class OriginState {
|
||||
// Registrations may exist at this origin. It cannot be deleted.
|
||||
kKeep,
|
||||
// No registrations exist at this origin. It can be deleted.
|
||||
kDelete
|
||||
};
|
||||
|
||||
using RegistrationList =
|
||||
std::vector<storage::mojom::ServiceWorkerRegistrationDataPtr>;
|
||||
using ResourceList =
|
||||
std::vector<storage::mojom::ServiceWorkerResourceRecordPtr>;
|
||||
using GetRegisteredOriginsCallback =
|
||||
base::OnceCallback<void(std::vector<url::Origin> callback)>;
|
||||
using FindRegistrationDataCallback = base::OnceCallback<void(
|
||||
storage::mojom::ServiceWorkerRegistrationDataPtr data,
|
||||
std::unique_ptr<ResourceList> resources,
|
||||
@ -85,6 +94,7 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
const std::vector<int64_t>& newly_purgeable_resources)>;
|
||||
using DeleteRegistrationCallback = base::OnceCallback<void(
|
||||
ServiceWorkerDatabase::Status status,
|
||||
OriginState origin_state,
|
||||
int64_t deleted_version_id,
|
||||
const std::vector<int64_t>& newly_purgeable_resources)>;
|
||||
|
||||
@ -111,13 +121,15 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
static std::unique_ptr<ServiceWorkerStorage> Create(
|
||||
const base::FilePath& user_data_directory,
|
||||
scoped_refptr<base::SequencedTaskRunner> database_task_runner,
|
||||
storage::QuotaManagerProxy* quota_manager_proxy,
|
||||
storage::SpecialStoragePolicy* special_storage_policy);
|
||||
storage::QuotaManagerProxy* quota_manager_proxy);
|
||||
|
||||
// Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
|
||||
static std::unique_ptr<ServiceWorkerStorage> Create(
|
||||
ServiceWorkerStorage* old_storage);
|
||||
|
||||
// Returns all origins which have service worker registrations.
|
||||
void GetRegisteredOrigins(GetRegisteredOriginsCallback callback);
|
||||
|
||||
// Reads stored registrations for |client_url| or |scope| or
|
||||
// |registration_id|. Returns ServiceWorkerDatabase::Status::kOk with
|
||||
// non-null RegistrationData and ResourceList if registration is found, or
|
||||
@ -289,6 +301,10 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
void PurgeResources(const std::vector<int64_t>& resource_ids);
|
||||
void PurgeResources(const std::set<int64_t>& resource_ids);
|
||||
|
||||
// Applies |policy_updates|.
|
||||
void ApplyPolicyUpdates(
|
||||
std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates);
|
||||
|
||||
void LazyInitializeForTest();
|
||||
|
||||
void SetPurgingCompleteCallbackForTest(base::OnceClosure callback);
|
||||
@ -335,13 +351,6 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
~DidDeleteRegistrationParams();
|
||||
};
|
||||
|
||||
enum class OriginState {
|
||||
// Registrations may exist at this origin. It cannot be deleted.
|
||||
kKeep,
|
||||
// No registrations exist at this origin. It can be deleted.
|
||||
kDelete
|
||||
};
|
||||
|
||||
using InitializeCallback =
|
||||
base::OnceCallback<void(std::unique_ptr<InitialData> data,
|
||||
ServiceWorkerDatabase::Status status)>;
|
||||
@ -364,8 +373,7 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
ServiceWorkerStorage(
|
||||
const base::FilePath& user_data_directory,
|
||||
scoped_refptr<base::SequencedTaskRunner> database_task_runner,
|
||||
storage::QuotaManagerProxy* quota_manager_proxy,
|
||||
storage::SpecialStoragePolicy* special_storage_policy);
|
||||
storage::QuotaManagerProxy* quota_manager_proxy);
|
||||
|
||||
base::FilePath GetDatabasePath();
|
||||
base::FilePath GetDiskCachePath();
|
||||
@ -515,6 +523,8 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
|
||||
// Origins having registations.
|
||||
std::set<GURL> registered_origins_;
|
||||
// The set of origins whose storage should be cleaned on shutdown.
|
||||
std::set<GURL> origins_to_purge_on_shutdown_;
|
||||
|
||||
// Pending database tasks waiting for initialization.
|
||||
std::vector<base::OnceClosure> pending_tasks_;
|
||||
@ -551,7 +561,6 @@ class CONTENT_EXPORT ServiceWorkerStorage {
|
||||
scoped_refptr<base::SequencedTaskRunner> database_task_runner_;
|
||||
|
||||
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
|
||||
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
|
||||
|
||||
std::unique_ptr<ServiceWorkerDiskCache> disk_cache_;
|
||||
|
||||
|
@ -1837,6 +1837,7 @@ test("content_unittests") {
|
||||
"../browser/service_worker/service_worker_process_manager_unittest.cc",
|
||||
"../browser/service_worker/service_worker_provider_host_unittest.cc",
|
||||
"../browser/service_worker/service_worker_registration_unittest.cc",
|
||||
"../browser/service_worker/service_worker_registry_unittest.cc",
|
||||
"../browser/service_worker/service_worker_request_handler_unittest.cc",
|
||||
"../browser/service_worker/service_worker_script_loader_factory_unittest.cc",
|
||||
"../browser/service_worker/service_worker_single_script_update_checker_unittest.cc",
|
||||
|
@ -62,6 +62,8 @@ class MockSpecialStoragePolicy : public SpecialStoragePolicy {
|
||||
|
||||
void NotifyCleared() { SpecialStoragePolicy::NotifyCleared(); }
|
||||
|
||||
void NotifyPolicyChanged() { SpecialStoragePolicy::NotifyPolicyChanged(); }
|
||||
|
||||
protected:
|
||||
~MockSpecialStoragePolicy() override;
|
||||
|
||||
|
Reference in New Issue
Block a user