blob: 8c520861407e9918d5bcc3a1363436ab5d2c4bdb [file] [log] [blame]
// Copyright 2019 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 "content/browser/hid/hid_service.h"
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/hid_chooser.h"
#include "content/public/browser/hid_delegate.h"
#include "content/public/browser/render_frame_host.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/message.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h"
namespace content {
HidService::HidService(RenderFrameHost* render_frame_host,
blink::mojom::HidServiceRequest request)
: FrameServiceBase(render_frame_host, std::move(request)) {}
HidService::~HidService() = default;
// static
void HidService::Create(RenderFrameHost* render_frame_host,
blink::mojom::HidServiceRequest request) {
DCHECK(render_frame_host);
if (!render_frame_host->IsFeatureEnabled(
blink::mojom::FeaturePolicyFeature::kHid)) {
mojo::ReportBadMessage("Feature policy blocks access to HID.");
return;
}
// Avoid creating the HidService if there is no HID delegate to provide the
// implementation.
if (!GetContentClient()->browser()->GetHidDelegate())
return;
// HidService owns itself. It will self-destruct when a mojo interface error
// occurs, the render frame host is deleted, or the render frame host
// navigates to a new document.
new HidService(render_frame_host, std::move(request));
}
void HidService::GetDevices(GetDevicesCallback callback) {
GetContentClient()
->browser()
->GetHidDelegate()
->GetHidManager(web_contents())
->GetDevices(base::BindOnce(&HidService::FinishGetDevices,
weak_factory_.GetWeakPtr(),
std::move(callback)));
}
void HidService::RequestDevice(
std::vector<blink::mojom::HidDeviceFilterPtr> filters,
RequestDeviceCallback callback) {
HidDelegate* delegate = GetContentClient()->browser()->GetHidDelegate();
if (!delegate->CanRequestDevicePermission(web_contents(), origin())) {
std::move(callback).Run(nullptr);
return;
}
chooser_ = delegate->RunChooser(
render_frame_host(), std::move(filters),
base::BindOnce(&HidService::FinishRequestDevice,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void HidService::Connect(
const std::string& device_guid,
mojo::PendingRemote<device::mojom::HidConnectionClient> client,
ConnectCallback callback) {
GetContentClient()
->browser()
->GetHidDelegate()
->GetHidManager(web_contents())
->Connect(
device_guid, std::move(client),
base::BindOnce(&HidService::FinishConnect, weak_factory_.GetWeakPtr(),
std::move(callback)));
}
void HidService::FinishGetDevices(
GetDevicesCallback callback,
std::vector<device::mojom::HidDeviceInfoPtr> devices) {
std::vector<device::mojom::HidDeviceInfoPtr> result;
HidDelegate* delegate = GetContentClient()->browser()->GetHidDelegate();
for (auto& device : devices) {
if (delegate->HasDevicePermission(web_contents(), origin(), *device))
result.push_back(std::move(device));
}
std::move(callback).Run(std::move(result));
}
void HidService::FinishRequestDevice(RequestDeviceCallback callback,
device::mojom::HidDeviceInfoPtr device) {
if (!device) {
std::move(callback).Run(nullptr);
return;
}
std::move(callback).Run(std::move(device));
}
void HidService::FinishConnect(ConnectCallback callback,
device::mojom::HidConnectionPtr connection) {
if (!connection) {
std::move(callback).Run(nullptr);
return;
}
std::move(callback).Run(std::move(connection));
}
} // namespace content