blob: 00909fcf73084c4b02fd4c608e552e5f3dc6dc18 [file] [log] [blame] [edit]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "storage/browser/quota/quota_manager_proxy.h"
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/time/time.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "components/services/storage/public/cpp/constants.h"
#include "components/services/storage/public/mojom/quota_client.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "storage/browser/quota/quota_client_type.h"
#include "storage/browser/quota/quota_manager_impl.h"
#include "storage/browser/quota/quota_override_handle.h"
#include "storage/browser/quota/storage_directory_util.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
using ::blink::StorageKey;
namespace storage {
// This object signals the given `WaitableEvent` when it goes out of scope.
class ScopedWaitableEvent {
public:
explicit ScopedWaitableEvent(base::WaitableEvent& event) : event_(&event) {}
ScopedWaitableEvent(ScopedWaitableEvent&& other) {
event_ = std::exchange(other.event_, nullptr);
}
~ScopedWaitableEvent() {
if (event_) {
event_->Signal();
}
}
ScopedWaitableEvent(const ScopedWaitableEvent& other) = delete;
ScopedWaitableEvent& operator=(const ScopedWaitableEvent& other) = delete;
private:
raw_ptr<base::WaitableEvent> event_;
};
QuotaManagerProxy::QuotaManagerProxy(
QuotaManagerImpl* quota_manager_impl,
scoped_refptr<base::SequencedTaskRunner> quota_manager_impl_task_runner,
const base::FilePath& profile_path)
: quota_manager_impl_(quota_manager_impl),
quota_manager_impl_task_runner_(
std::move(quota_manager_impl_task_runner)),
profile_path_(profile_path) {
DCHECK(quota_manager_impl_task_runner_.get());
DETACH_FROM_SEQUENCE(quota_manager_impl_sequence_checker_);
}
base::FilePath QuotaManagerProxy::GetBucketPath(const BucketLocator& bucket) {
return CreateBucketPath(profile_path_, bucket);
}
base::FilePath QuotaManagerProxy::GetClientBucketPath(
const BucketLocator& bucket,
QuotaClientType client_type) {
return CreateClientBucketPath(profile_path_, bucket, client_type);
}
void QuotaManagerProxy::RegisterClient(
mojo::PendingRemote<mojom::QuotaClient> client,
QuotaClientType client_type) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::RegisterClient, this,
std::move(client), client_type));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->RegisterClient(std::move(client), client_type);
}
}
void QuotaManagerProxy::BindInternalsHandler(
mojo::PendingReceiver<mojom::QuotaInternalsHandler> receiver) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::BindInternalsHandler,
this, std::move(receiver)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->BindInternalsHandler(std::move(receiver));
}
}
void QuotaManagerProxy::UpdateOrCreateBucket(
const BucketInitParams& bucket_params,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::UpdateOrCreateBucket, this,
bucket_params, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->UpdateOrCreateBucket(bucket_params, std::move(respond));
}
QuotaErrorOr<BucketInfo> QuotaManagerProxy::GetOrCreateBucketSync(
const BucketInitParams& params) {
// Ensure that the task runner we want is free and can be blocked on.
DCHECK(!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence());
QuotaErrorOr<BucketInfo> bucket = base::unexpected(QuotaError::kUnknownError);
base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::WILL_BLOCK);
// Asynchronously call UpdateOrCreateBucket and block until it completes.
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
[](const scoped_refptr<QuotaManagerProxy>& self,
const BucketInitParams& params, ScopedWaitableEvent waiter,
QuotaErrorOr<BucketInfo>* sync_bucket) {
DCHECK_CALLED_ON_VALID_SEQUENCE(
self->quota_manager_impl_sequence_checker_);
// If the database is still bootstrapping, return rather than
// risking deadlock.
if (!self->quota_manager_impl_ ||
self->quota_manager_impl_->is_bootstrapping_database_) {
return;
}
// Otherwise, return the bucket value and resolve the waiter.
self->quota_manager_impl_->UpdateOrCreateBucket(
params, base::BindOnce(
[](ScopedWaitableEvent waiter,
QuotaErrorOr<BucketInfo>* sync_bucket,
QuotaErrorOr<BucketInfo> result_bucket) {
*sync_bucket = std::move(result_bucket);
},
std::move(waiter), sync_bucket));
},
base::WrapRefCounted(this), params, ScopedWaitableEvent(waiter),
&bucket));
waiter.Wait();
return bucket;
}
void QuotaManagerProxy::CreateBucketForTesting(
const StorageKey& storage_key,
const std::string& bucket_name,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::CreateBucketForTesting, this,
storage_key, bucket_name,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->CreateBucketForTesting( // IN-TEST
storage_key, bucket_name, std::move(respond));
}
void QuotaManagerProxy::GetBucketByNameUnsafe(
const StorageKey& storage_key,
const std::string& bucket_name,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetBucketByNameUnsafe, this,
storage_key, bucket_name,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->GetBucketByNameUnsafe( // IN-TEST
storage_key, bucket_name, std::move(respond));
}
void QuotaManagerProxy::GetBucketsForStorageKey(
const blink::StorageKey& storage_key,
bool delete_expired,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetBucketsForStorageKey, this,
storage_key, delete_expired,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->GetBucketsForStorageKey(storage_key, std::move(respond),
delete_expired);
}
void QuotaManagerProxy::GetBucketById(
const BucketId& bucket_id,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetBucketById, this, bucket_id,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->GetBucketById(bucket_id, std::move(respond));
}
void QuotaManagerProxy::DeleteBucket(
const StorageKey& storage_key,
const std::string& bucket_name,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(blink::mojom::QuotaStatusCode)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::DeleteBucket, this, storage_key,
bucket_name, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(blink::mojom::QuotaStatusCode::kUnknown);
return;
}
quota_manager_impl_->FindAndDeleteBucketData(storage_key, bucket_name,
std::move(respond));
}
void QuotaManagerProxy::UpdateBucketExpiration(
BucketId bucket,
const base::Time& expiration,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::UpdateBucketExpiration, this, bucket,
expiration, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->UpdateBucketExpiration(bucket, expiration,
std::move(respond));
}
void QuotaManagerProxy::UpdateBucketPersistence(
BucketId bucket,
bool persistent,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::UpdateBucketPersistence, this,
bucket, persistent, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->UpdateBucketPersistence(bucket, persistent,
std::move(respond));
}
void QuotaManagerProxy::NotifyBucketAccessed(const BucketLocator& bucket,
base::Time access_time) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::NotifyBucketAccessed,
this, bucket, access_time));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->NotifyBucketAccessed(bucket, access_time);
}
}
void QuotaManagerProxy::NotifyBucketModified(
QuotaClientType client_id,
const BucketLocator& bucket,
std::optional<int64_t> delta,
base::Time modification_time,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceClosure callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::NotifyBucketModified, this,
client_id, bucket, delta, modification_time,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto manager_callback =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(manager_callback).Run();
return;
}
quota_manager_impl_->NotifyBucketModified(
client_id, bucket, delta, modification_time, std::move(manager_callback));
}
void QuotaManagerProxy::OnClientWriteFailed(const StorageKey& storage_key) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::OnClientWriteFailed, this,
storage_key));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->OnClientWriteFailed(storage_key);
}
}
void QuotaManagerProxy::SetUsageCacheEnabled(QuotaClientType client_id,
const StorageKey& storage_key,
bool enabled) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::SetUsageCacheEnabled,
this, client_id, storage_key, enabled));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->SetUsageCacheEnabled(client_id, storage_key, enabled);
}
}
void QuotaManagerProxy::GetUsageAndQuota(
const StorageKey& storage_key,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
UsageAndQuotaCallback callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetUsageAndQuota, this, storage_key,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0);
return;
}
quota_manager_impl_->GetUsageAndQuota(storage_key, std::move(respond));
}
void QuotaManagerProxy::GetBucketUsageAndReportedQuota(
BucketId bucket,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
UsageAndQuotaCallback callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetBucketUsageAndReportedQuota, this,
bucket, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0);
return;
}
quota_manager_impl_->GetBucketUsageAndReportedQuota(bucket,
std::move(respond));
}
void QuotaManagerProxy::GetBucketSpaceRemaining(
const BucketLocator& bucket,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<int64_t>)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::GetBucketSpaceRemaining,
this, bucket, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(base::unexpected(QuotaError::kUnknownError));
return;
}
quota_manager_impl_->GetBucketSpaceRemaining(bucket, std::move(respond));
}
void QuotaManagerProxy::IsStorageUnlimited(
const StorageKey& storage_key,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(bool)> callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::IsStorageUnlimited, this,
storage_key, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
bool is_storage_unlimited =
quota_manager_impl_ ? quota_manager_impl_->IsStorageUnlimited(storage_key)
: false;
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
std::move(respond).Run(is_storage_unlimited);
}
void QuotaManagerProxy::GetStorageKeyUsageWithBreakdown(
const blink::StorageKey& storage_key,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
UsageWithBreakdownCallback callback) {
CHECK(callback_task_runner);
CHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetStorageKeyUsageWithBreakdown,
this, storage_key, std::move(callback_task_runner),
std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
if (!quota_manager_impl_) {
std::move(respond).Run(0, nullptr);
return;
}
quota_manager_impl_->GetStorageKeyUsageWithBreakdown(storage_key,
std::move(respond));
}
std::unique_ptr<QuotaOverrideHandle>
QuotaManagerProxy::GetQuotaOverrideHandle() {
return std::make_unique<QuotaOverrideHandle>(this);
}
void QuotaManagerProxy::OverrideQuotaForStorageKey(
int handle_id,
const StorageKey& storage_key,
std::optional<int64_t> quota_size,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceClosure callback) {
DCHECK(callback_task_runner);
DCHECK(callback);
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::OverrideQuotaForStorageKey, this,
handle_id, storage_key, quota_size,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->OverrideQuotaForStorageKey(handle_id, storage_key,
quota_size);
}
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
std::move(respond).Run();
}
void QuotaManagerProxy::WithdrawOverridesForHandle(int handle_id) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::WithdrawOverridesForHandle, this,
handle_id));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->WithdrawOverridesForHandle(handle_id);
}
}
void QuotaManagerProxy::GetOverrideHandleId(
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(int)> callback) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetOverrideHandleId, this,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
int handle_id =
quota_manager_impl_ ? quota_manager_impl_->GetOverrideHandleId() : 0;
auto respond =
base::BindPostTask(std::move(callback_task_runner), std::move(callback));
std::move(respond).Run(handle_id);
}
QuotaManagerProxy::~QuotaManagerProxy() = default;
void QuotaManagerProxy::InvalidateQuotaManagerImpl(
base::PassKey<QuotaManagerImpl>) {
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
DCHECK(quota_manager_impl_) << __func__ << " called multiple times";
quota_manager_impl_ = nullptr;
}
void QuotaManagerProxy::AddObserver(
mojo::PendingRemote<storage::mojom::QuotaManagerObserver> observer) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::AddObserver, this,
std::move(observer)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (!quota_manager_impl_) {
return;
}
quota_manager_impl_->AddObserver(std::move(observer));
}
} // namespace storage