blob: b39389847bd0bba3b74226b2edc82736eeabe452 [file] [log] [blame]
// Copyright 2014 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 "storage/browser/quota/quota_manager_proxy.h"
#include <stdint.h>
#include <memory>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.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.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 "third_party/blink/public/mojom/quota/quota_types.mojom.h"
#include "url/origin.h"
namespace storage {
QuotaManagerProxy::QuotaManagerProxy(
QuotaManagerImpl* quota_manager_impl,
scoped_refptr<base::SequencedTaskRunner> quota_manager_impl_task_runner)
: quota_manager_impl_(quota_manager_impl),
quota_manager_impl_task_runner_(
std::move(quota_manager_impl_task_runner)) {
DCHECK(quota_manager_impl_task_runner_.get());
DETACH_FROM_SEQUENCE(quota_manager_impl_sequence_checker_);
}
void QuotaManagerProxy::RegisterLegacyClient(
scoped_refptr<QuotaClient> client,
QuotaClientType client_type,
const std::vector<blink::mojom::StorageType>& storage_types) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::RegisterLegacyClient, this,
std::move(client), client_type, storage_types));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (!quota_manager_impl_) {
client->OnQuotaManagerDestroyed();
return;
}
quota_manager_impl_->RegisterLegacyClient(std::move(client), client_type,
storage_types);
}
void QuotaManagerProxy::RegisterClient(
mojo::PendingRemote<mojom::QuotaClient> client,
QuotaClientType client_type,
const std::vector<blink::mojom::StorageType>& storage_types) {
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, storage_types));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->RegisterClient(std::move(client), client_type,
storage_types);
}
}
void QuotaManagerProxy::NotifyStorageAccessed(const url::Origin& origin,
blink::mojom::StorageType type,
base::Time access_time) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::NotifyStorageAccessed,
this, origin, type, access_time));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_)
quota_manager_impl_->NotifyStorageAccessed(origin, type, access_time);
}
void QuotaManagerProxy::NotifyStorageModified(QuotaClientType client_id,
const url::Origin& origin,
blink::mojom::StorageType type,
int64_t delta,
base::Time modification_time) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::NotifyStorageModified, this,
client_id, origin, type, delta, modification_time));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_) {
quota_manager_impl_->NotifyStorageModified(client_id, origin, type, delta,
modification_time);
}
}
void QuotaManagerProxy::NotifyOriginInUse(const url::Origin& origin) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::NotifyOriginInUse, this, origin));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_)
quota_manager_impl_->NotifyOriginInUse(origin);
}
void QuotaManagerProxy::NotifyOriginNoLongerInUse(const url::Origin& origin) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::NotifyOriginNoLongerInUse,
this, origin));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_)
quota_manager_impl_->NotifyOriginNoLongerInUse(origin);
}
void QuotaManagerProxy::NotifyWriteFailed(const url::Origin& origin) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::NotifyWriteFailed, this, origin));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_)
quota_manager_impl_->NotifyWriteFailed(origin);
}
void QuotaManagerProxy::SetUsageCacheEnabled(QuotaClientType client_id,
const url::Origin& origin,
blink::mojom::StorageType type,
bool enabled) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::SetUsageCacheEnabled,
this, client_id, origin, type, enabled));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (quota_manager_impl_)
quota_manager_impl_->SetUsageCacheEnabled(client_id, origin, type, enabled);
}
namespace {
void DidGetUsageAndQuota(
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
QuotaManagerProxy::UsageAndQuotaCallback callback,
blink::mojom::QuotaStatusCode status,
int64_t usage,
int64_t quota) {
if (callback_task_runner->RunsTasksInCurrentSequence()) {
std::move(callback).Run(status, usage, quota);
return;
}
callback_task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), status, usage, quota));
}
} // namespace
void QuotaManagerProxy::GetUsageAndQuota(
const url::Origin& origin,
blink::mojom::StorageType type,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
UsageAndQuotaCallback callback) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::GetUsageAndQuota, this, origin, type,
std::move(callback_task_runner), std::move(callback)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
if (!quota_manager_impl_) {
DidGetUsageAndQuota(std::move(callback_task_runner), std::move(callback),
blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0);
return;
}
quota_manager_impl_->GetUsageAndQuota(
origin, type,
base::BindOnce(&DidGetUsageAndQuota, std::move(callback_task_runner),
std::move(callback)));
}
void QuotaManagerProxy::IsStorageUnlimited(
const url::Origin& origin,
blink::mojom::StorageType type,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(bool)> callback) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&QuotaManagerProxy::IsStorageUnlimited, this,
origin, type, 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(origin, type)
: false;
if (callback_task_runner->RunsTasksInCurrentSequence()) {
std::move(callback).Run(is_storage_unlimited);
return;
}
callback_task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), is_storage_unlimited));
}
std::unique_ptr<QuotaOverrideHandle>
QuotaManagerProxy::GetQuotaOverrideHandle() {
return std::make_unique<QuotaOverrideHandle>(this);
}
void QuotaManagerProxy::OverrideQuotaForOrigin(
int handle_id,
url::Origin origin,
base::Optional<int64_t> quota_size,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceClosure callback) {
if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
quota_manager_impl_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&QuotaManagerProxy::OverrideQuotaForOrigin, this,
handle_id, origin, 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_->OverrideQuotaForOrigin(handle_id, origin, quota_size);
if (callback_task_runner->RunsTasksInCurrentSequence()) {
std::move(callback).Run();
return;
}
callback_task_runner->PostTask(FROM_HERE, std::move(callback));
}
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;
if (callback_task_runner->RunsTasksInCurrentSequence()) {
std::move(callback).Run(handle_id);
return;
}
callback_task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), 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;
}
} // namespace storage