blob: cfafb0c5b3f56cfb2e5dee470816e840642e9f9e [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/smart_card/smart_card_service.h"
#include "content/browser/renderer_host/isolated_context_util.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/document_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/smart_card_delegate.h"
#include "services/device/public/mojom/smart_card.mojom.h"
#include "third_party/blink/public/common/features_generated.h"
namespace content {
namespace {
// Deletes the SmartCardService when the connected document is destroyed.
class DocumentHelper
: public content::DocumentService<blink::mojom::SmartCardService> {
public:
DocumentHelper(std::unique_ptr<SmartCardService> service,
RenderFrameHost& render_frame_host,
mojo::PendingReceiver<blink::mojom::SmartCardService> receiver)
: DocumentService(render_frame_host, std::move(receiver)),
service_(std::move(service)) {
DCHECK(service_);
}
~DocumentHelper() override = default;
// blink::mojom::SmartCardService:
void CreateContext(CreateContextCallback callback) override {
service_->CreateContext(std::move(callback));
}
private:
const std::unique_ptr<SmartCardService> service_;
};
} // namespace
SmartCardService::SmartCardService(
mojo::PendingRemote<device::mojom::SmartCardContextFactory> context_factory)
: context_factory_(std::move(context_factory)) {}
SmartCardService::~SmartCardService() {}
// static
void SmartCardService::Create(
RenderFrameHostImpl* render_frame_host,
mojo::PendingReceiver<blink::mojom::SmartCardService> receiver) {
BrowserContext* browser_context = render_frame_host->GetBrowserContext();
DCHECK(browser_context);
if (!base::FeatureList::IsEnabled(blink::features::kSmartCard)) {
mojo::ReportBadMessage("The SmartCard feature is disabled.");
return;
}
if (!render_frame_host->IsFeatureEnabled(
blink::mojom::PermissionsPolicyFeature::kSmartCard)) {
mojo::ReportBadMessage(
"Access to the feature \"smart-card\" is disallowed by permissions "
"policy.");
return;
}
if (!IsFrameSufficientlyIsolated(render_frame_host)) {
mojo::ReportBadMessage(
"Frame is not sufficiently isolated to use the Smart Card API.");
return;
}
SmartCardDelegate* delegate =
GetContentClient()->browser()->GetSmartCardDelegate(browser_context);
if (!delegate) {
mojo::ReportBadMessage("Browser has no Smart Card delegate.");
return;
}
// DocumentHelper observes the lifetime of the document connected to
// `render_frame_host` and destroys the SmartCardService when the Mojo
// connection is disconnected, RenderFrameHost is deleted, or the
// RenderFrameHost commits a cross-document navigation. It forwards its Mojo
// interface to SmartCardService.
new DocumentHelper(
std::make_unique<SmartCardService>(
delegate->GetSmartCardContextFactory(*browser_context)),
*render_frame_host, std::move(receiver));
}
void SmartCardService::CreateContext(CreateContextCallback callback) {
context_factory_->CreateContext(std::move(callback));
}
} // namespace content