blob: cf28d21f178fe900ebf7a81d74cc54b40def40f3 [file] [log] [blame]
// 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 "third_party/blink/renderer/modules/credentialmanagement/credential_manager_proxy.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
CredentialManagerProxy::CredentialManagerProxy(LocalDOMWindow& window)
: Supplement<LocalDOMWindow>(window),
authenticator_(window.GetExecutionContext()),
credential_manager_(window.GetExecutionContext()),
webotp_service_(window.GetExecutionContext()),
spc_service_(window.GetExecutionContext()),
federated_auth_request_(window.GetExecutionContext()),
digital_identity_request_(window.GetExecutionContext()) {}
CredentialManagerProxy::~CredentialManagerProxy() = default;
mojom::blink::CredentialManager* CredentialManagerProxy::CredentialManager() {
if (!credential_manager_.is_bound()) {
LocalFrame* frame = GetSupplementable()->GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
credential_manager_.BindNewPipeAndPassReceiver(
frame->GetTaskRunner(TaskType::kUserInteraction)));
}
return credential_manager_.get();
}
mojom::blink::Authenticator* CredentialManagerProxy::Authenticator() {
if (!authenticator_.is_bound()) {
LocalFrame* frame = GetSupplementable()->GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
authenticator_.BindNewPipeAndPassReceiver(
frame->GetTaskRunner(TaskType::kUserInteraction)));
}
return authenticator_.get();
}
mojom::blink::WebOTPService* CredentialManagerProxy::WebOTPService() {
if (!webotp_service_.is_bound()) {
LocalFrame* frame = GetSupplementable()->GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
webotp_service_.BindNewPipeAndPassReceiver(
frame->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
return webotp_service_.get();
}
payments::mojom::blink::SecurePaymentConfirmationService*
CredentialManagerProxy::SecurePaymentConfirmationService() {
if (!spc_service_.is_bound()) {
LocalFrame* frame = GetSupplementable()->GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
spc_service_.BindNewPipeAndPassReceiver(
frame->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
return spc_service_.get();
}
template <typename Interface>
void CredentialManagerProxy::BindRemoteForFedCm(
HeapMojoRemote<Interface>& remote,
base::OnceClosure disconnect_closure) {
if (remote.is_bound())
return;
LocalFrame* frame = GetSupplementable()->GetFrame();
// TODO(kenrb): Work out whether kUserInteraction is the best task type
// here. It might be appropriate to create a new one.
frame->GetBrowserInterfaceBroker().GetInterface(
remote.BindNewPipeAndPassReceiver(
frame->GetTaskRunner(TaskType::kUserInteraction)));
remote.set_disconnect_handler(std::move(disconnect_closure));
}
mojom::blink::FederatedAuthRequest*
CredentialManagerProxy::FederatedAuthRequest() {
BindRemoteForFedCm(
federated_auth_request_,
BindOnce(&CredentialManagerProxy::OnFederatedAuthRequestConnectionError,
WrapWeakPersistent(this)));
return federated_auth_request_.get();
}
void CredentialManagerProxy::OnFederatedAuthRequestConnectionError() {
federated_auth_request_.reset();
// TODO(crbug.com/1275769): Cache the resolver and resolve the promise with an
// appropriate error message.
}
mojom::blink::DigitalIdentityRequest*
CredentialManagerProxy::DigitalIdentityRequest() {
BindRemoteForFedCm(
digital_identity_request_,
BindOnce(&CredentialManagerProxy::OnDigitalIdentityRequestConnectionError,
WrapWeakPersistent(this)));
return digital_identity_request_.get();
}
void CredentialManagerProxy::OnDigitalIdentityRequestConnectionError() {
digital_identity_request_.reset();
}
// TODO(crbug.com/1372275): Replace From(ScriptState*) with
// From(ExecutionContext*)
// static
CredentialManagerProxy* CredentialManagerProxy::From(
ScriptState* script_state) {
DCHECK(script_state->ContextIsValid());
LocalDOMWindow& window = *LocalDOMWindow::From(script_state);
return From(&window);
}
CredentialManagerProxy* CredentialManagerProxy::From(LocalDOMWindow* window) {
auto* supplement =
Supplement<LocalDOMWindow>::From<CredentialManagerProxy>(*window);
if (!supplement) {
supplement = MakeGarbageCollected<CredentialManagerProxy>(*window);
ProvideTo(*window, supplement);
}
return supplement;
}
// static
CredentialManagerProxy* CredentialManagerProxy::From(
ExecutionContext* execution_context) {
// Since the FedCM API cannot be used by workers, the execution context is
// always a window.
LocalDOMWindow& window = *To<LocalDOMWindow>(execution_context);
auto* supplement =
Supplement<LocalDOMWindow>::From<CredentialManagerProxy>(window);
if (!supplement) {
supplement = MakeGarbageCollected<CredentialManagerProxy>(window);
ProvideTo(window, supplement);
}
return supplement;
}
void CredentialManagerProxy::Trace(Visitor* visitor) const {
visitor->Trace(authenticator_);
visitor->Trace(credential_manager_);
visitor->Trace(webotp_service_);
visitor->Trace(spc_service_);
visitor->Trace(federated_auth_request_);
visitor->Trace(digital_identity_request_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
// static
const char CredentialManagerProxy::kSupplementName[] = "CredentialManagerProxy";
} // namespace blink