| Index: content/browser/dom_storage/local_storage_context_mojo.cc
|
| diff --git a/content/browser/dom_storage/local_storage_context_mojo.cc b/content/browser/dom_storage/local_storage_context_mojo.cc
|
| index f4aca0ad42955b3665c6ce3b8b79e8a84189104a..2be6213f8ce2f40c4be1d0821cb30765217a20f4 100644
|
| --- a/content/browser/dom_storage/local_storage_context_mojo.cc
|
| +++ b/content/browser/dom_storage/local_storage_context_mojo.cc
|
| @@ -20,6 +20,7 @@
|
| #include "services/file/public/interfaces/constants.mojom.h"
|
| #include "services/service_manager/public/cpp/connector.h"
|
| #include "sql/connection.h"
|
| +#include "storage/browser/quota/special_storage_policy.h"
|
| #include "third_party/leveldatabase/env_chromium.h"
|
|
|
| namespace content {
|
| @@ -237,15 +238,15 @@ LocalStorageContextMojo::LocalStorageContextMojo(
|
| service_manager::Connector* connector,
|
| scoped_refptr<DOMStorageTaskRunner> task_runner,
|
| const base::FilePath& old_localstorage_path,
|
| - const base::FilePath& subdirectory)
|
| - : connector_(connector),
|
| + const base::FilePath& subdirectory,
|
| + scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy)
|
| + : connector_(connector ? connector->Clone() : nullptr),
|
| subdirectory_(subdirectory),
|
| + special_storage_policy_(std::move(special_storage_policy)),
|
| task_runner_(std::move(task_runner)),
|
| old_localstorage_path_(old_localstorage_path),
|
| weak_ptr_factory_(this) {}
|
|
|
| -LocalStorageContextMojo::~LocalStorageContextMojo() {}
|
| -
|
| void LocalStorageContextMojo::OpenLocalStorage(
|
| const url::Origin& origin,
|
| mojom::LevelDBWrapperRequest request) {
|
| @@ -299,6 +300,42 @@ void LocalStorageContextMojo::Flush() {
|
| it.second->level_db_wrapper()->ScheduleImmediateCommit();
|
| }
|
|
|
| +void LocalStorageContextMojo::ShutdownAndDelete() {
|
| + DCHECK_NE(connection_state_, CONNECTION_SHUTDOWN);
|
| +
|
| + // Nothing to do if no connection to the database was ever finished.
|
| + if (connection_state_ != CONNECTION_FINISHED) {
|
| + connection_state_ = CONNECTION_SHUTDOWN;
|
| + OnShutdownComplete(leveldb::mojom::DatabaseError::OK);
|
| + return;
|
| + }
|
| +
|
| + connection_state_ = CONNECTION_SHUTDOWN;
|
| +
|
| + // Flush any uncommitted data.
|
| + for (const auto& it : level_db_wrappers_)
|
| + it.second->level_db_wrapper()->ScheduleImmediateCommit();
|
| +
|
| + // Respect the content policy settings about what to
|
| + // keep and what to discard.
|
| + if (force_keep_session_state_) {
|
| + OnShutdownComplete(leveldb::mojom::DatabaseError::OK);
|
| + return; // Keep everything.
|
| + }
|
| +
|
| + bool has_session_only_origins =
|
| + special_storage_policy_.get() &&
|
| + special_storage_policy_->HasSessionOnlyOrigins();
|
| +
|
| + if (has_session_only_origins) {
|
| + RetrieveStorageUsage(
|
| + base::BindOnce(&LocalStorageContextMojo::OnGotStorageUsageForShutdown,
|
| + base::Unretained(this)));
|
| + } else {
|
| + OnShutdownComplete(leveldb::mojom::DatabaseError::OK);
|
| + }
|
| +}
|
| +
|
| void LocalStorageContextMojo::PurgeMemory() {
|
| for (const auto& it : level_db_wrappers_)
|
| it.second->level_db_wrapper()->PurgeMemory();
|
| @@ -327,7 +364,13 @@ std::vector<uint8_t> LocalStorageContextMojo::MigrateString(
|
| return result;
|
| }
|
|
|
| +LocalStorageContextMojo::~LocalStorageContextMojo() {
|
| + DCHECK_EQ(connection_state_, CONNECTION_SHUTDOWN);
|
| +}
|
| +
|
| void LocalStorageContextMojo::RunWhenConnected(base::OnceClosure callback) {
|
| + DCHECK_NE(connection_state_, CONNECTION_SHUTDOWN);
|
| +
|
| // If we don't have a filesystem_connection_, we'll need to establish one.
|
| if (connection_state_ == NO_CONNECTION) {
|
| connection_state_ = CONNECTION_IN_PROGRESS;
|
| @@ -609,4 +652,30 @@ void LocalStorageContextMojo::OnGotStorageUsageForDeletePhysicalOrigin(
|
| DeleteStorage(origin);
|
| }
|
|
|
| +void LocalStorageContextMojo::OnGotStorageUsageForShutdown(
|
| + std::vector<LocalStorageUsageInfo> usage) {
|
| + std::vector<leveldb::mojom::BatchedOperationPtr> operations;
|
| + for (const auto& info : usage) {
|
| + if (special_storage_policy_->IsStorageProtected(info.origin))
|
| + continue;
|
| + if (!special_storage_policy_->IsStorageSessionOnly(info.origin))
|
| + continue;
|
| +
|
| + AddDeleteOriginOperations(&operations, url::Origin(info.origin));
|
| + }
|
| +
|
| + if (!operations.empty()) {
|
| + database_->Write(std::move(operations),
|
| + base::Bind(&LocalStorageContextMojo::OnShutdownComplete,
|
| + base::Unretained(this)));
|
| + } else {
|
| + OnShutdownComplete(leveldb::mojom::DatabaseError::OK);
|
| + }
|
| +}
|
| +
|
| +void LocalStorageContextMojo::OnShutdownComplete(
|
| + leveldb::mojom::DatabaseError error) {
|
| + delete this;
|
| +}
|
| +
|
| } // namespace content
|
|
|