blob: a5b3e771ed19e6cc4acca6b50abb2c8897494bc8 [file] [log] [blame]
// 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 "third_party/blink/renderer/modules/buckets/storage_bucket_manager.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_bucket_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/navigator_base.h"
#include "third_party/blink/renderer/modules/buckets/storage_bucket.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
namespace {
mojom::blink::BucketPoliciesPtr ToMojoBucketPolicies(
const StorageBucketOptions* options) {
auto policies = mojom::blink::BucketPolicies::New();
policies->persisted = options->persisted();
policies->title = (options->hasTitle() && !options->title().IsEmpty())
? options->title()
: "";
policies->quota = options->hasQuotaNonNull()
? options->quotaNonNull()
: mojom::blink::kNoQuotaPolicyValue;
if (options->durability() == "strict") {
policies->durability = mojom::blink::BucketDurability::kStrict;
} else {
policies->durability = mojom::blink::BucketDurability::kRelaxed;
}
if (options->hasExpiresNonNull())
policies->expires = base::Time::FromJavaTime(options->expiresNonNull());
return policies;
}
} // namespace
const char StorageBucketManager::kSupplementName[] = "StorageBucketManager";
StorageBucketManager::StorageBucketManager(NavigatorBase& navigator,
ExecutionContext* context)
: Supplement<NavigatorBase>(navigator),
ExecutionContextClient(context),
manager_remote_(context) {
context->GetBrowserInterfaceBroker().GetInterface(
manager_remote_.BindNewPipeAndPassReceiver(
context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
DCHECK(manager_remote_.is_bound());
}
StorageBucketManager* StorageBucketManager::storageBuckets(
ScriptState* script_state,
NavigatorBase& navigator,
ExceptionState& exception_state) {
auto* supplement =
Supplement<NavigatorBase>::From<StorageBucketManager>(navigator);
if (!supplement) {
auto* context = ExecutionContext::From(script_state);
supplement = MakeGarbageCollected<StorageBucketManager>(navigator, context);
Supplement<NavigatorBase>::ProvideTo(navigator, supplement);
}
return supplement;
}
ScriptPromise StorageBucketManager::open(ScriptState* script_state,
const String& name,
const StorageBucketOptions* options,
ExceptionState& exception_state) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
mojom::blink::BucketPoliciesPtr bucket_policies =
ToMojoBucketPolicies(options);
manager_remote_->OpenBucket(
name, std::move(bucket_policies),
WTF::Bind(&StorageBucketManager::DidOpen, WrapPersistent(this),
WrapPersistent(resolver)));
return promise;
}
ScriptPromise StorageBucketManager::keys(ScriptState* script_state,
ExceptionState& exception_state) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
manager_remote_->Keys(WTF::Bind(&StorageBucketManager::DidGetKeys,
WrapPersistent(this),
WrapPersistent(resolver)));
return promise;
}
ScriptPromise StorageBucketManager::Delete(ScriptState* script_state,
const String& name,
ExceptionState& exception_state) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
manager_remote_->DeleteBucket(
name, WTF::Bind(&StorageBucketManager::DidDelete, WrapPersistent(this),
WrapPersistent(resolver)));
return promise;
}
void StorageBucketManager::DidOpen(
ScriptPromiseResolver* resolver,
mojo::PendingRemote<mojom::blink::BucketHost> bucket_remote) {
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
ScriptState::Scope scope(script_state);
if (!bucket_remote) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError,
"Unknown error occured while creating a bucket."));
return;
}
resolver->Resolve(MakeGarbageCollected<StorageBucket>(
GetExecutionContext(), std::move(bucket_remote)));
}
void StorageBucketManager::DidGetKeys(ScriptPromiseResolver* resolver,
const Vector<String>& keys,
bool success) {
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
ScriptState::Scope scope(script_state);
if (!success) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError,
"Unknown error occured while retrieving bucket names."));
return;
}
resolver->Resolve(keys);
}
void StorageBucketManager::DidDelete(ScriptPromiseResolver* resolver,
bool success) {
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
ScriptState::Scope scope(script_state);
if (!success) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError,
"Unknown error occured while deleting a bucket."));
return;
}
resolver->Resolve();
}
void StorageBucketManager::Trace(Visitor* visitor) const {
visitor->Trace(manager_remote_);
ScriptWrappable::Trace(visitor);
Supplement<NavigatorBase>::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
} // namespace blink