blob: eed1a9794ba7e8a24cf193714bcd8a0ce79a9711 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/device/usb/usb_interface_detach_allowlist.h"
#include <algorithm>
namespace device {
namespace {
using ::device::mojom::kUsbCommClass;
constexpr uint8_t kUsbCdcSubClassAcm = 2;
constexpr uint8_t kUsbCdcProtoNone = 0;
constexpr uint8_t kUsbCdcProtoAtV25ter = 1;
constexpr uint8_t kUsbCdcProtoAtPcca101 = 2;
constexpr uint8_t kUsbCdcProtoAtPcca101Wake = 3;
constexpr uint8_t kUsbCdcProtoAtGsm = 4;
constexpr uint8_t kUsbCdcProtoAt3G = 5;
constexpr uint8_t kUsbCdcProtoAtCdma = 6;
} // namespace
UsbInterfaceDetachAllowlist::UsbInterfaceDetachAllowlist()
: UsbInterfaceDetachAllowlist({
// CDC/ACM (communication) devices
{/*driver_name=*/"cdc_acm",
/*protocols=without any protocol set or with AT-command sets*/
{
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoNone},
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoAtV25ter},
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoAtPcca101},
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoAtPcca101Wake},
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoAtGsm},
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoAt3G},
{kUsbCommClass, kUsbCdcSubClassAcm, kUsbCdcProtoAtCdma},
}},
// Printers
{/*driver_name=*/"usblp", /*protocols=ALL*/ {}},
// FTDI serial devices
{/*driver_name=*/"ftdi_sio", /*protocols=ALL*/ {}},
}) {}
UsbInterfaceDetachAllowlist::UsbInterfaceDetachAllowlist(
std::vector<Entry> entries)
: entries_(std::move(entries)) {}
UsbInterfaceDetachAllowlist::~UsbInterfaceDetachAllowlist() = default;
// static
const UsbInterfaceDetachAllowlist& UsbInterfaceDetachAllowlist::Get() {
static base::NoDestructor<UsbInterfaceDetachAllowlist> instance;
return *instance;
}
bool UsbInterfaceDetachAllowlist::CanDetach(
std::string_view driver_name,
const mojom::UsbAlternateInterfaceInfo& interface_info) const {
return std::ranges::any_of(entries_, [&](const Entry& rule) {
if (rule.driver_name != driver_name) {
return false;
}
if (rule.protocols.empty()) {
return true;
}
return std::ranges::any_of(rule.protocols, [&](const Protocol& protocol) {
return protocol.class_code == interface_info.class_code &&
protocol.subclass_code == interface_info.subclass_code &&
protocol.protocol_code == interface_info.protocol_code;
});
});
}
UsbInterfaceDetachAllowlist::Entry::Entry(
const std::string& driver_name,
const std::vector<Protocol>& protocols)
: driver_name(driver_name), protocols(protocols) {}
UsbInterfaceDetachAllowlist::Entry::Entry(
const UsbInterfaceDetachAllowlist::Entry& other) = default;
UsbInterfaceDetachAllowlist::Entry::~Entry() = default;
} // namespace device