// services/device/public/mojom/usb_device.mojom.cc is auto generated by mojom_bindings_generator.py, do not edit

// Copyright 2013 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.

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif

#include "services/device/public/mojom/usb_device.mojom.h"

#include <math.h>
#include <stdint.h>
#include <utility>

#include "base/debug/alias.h"
#include "base/hash/md5_constexpr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "mojo/public/cpp/bindings/lib/generated_code_util.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
#include "mojo/public/cpp/bindings/lib/proxy_to_responder.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/mojo_buildflags.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"

#include "services/device/public/mojom/usb_device.mojom-params-data.h"
#include "services/device/public/mojom/usb_device.mojom-shared-message-ids.h"

#include "services/device/public/mojom/usb_device.mojom-import-headers.h"
#include "services/device/public/mojom/usb_device.mojom-test-utils.h"


#ifndef SERVICES_DEVICE_PUBLIC_MOJOM_USB_DEVICE_MOJOM_JUMBO_H_
#define SERVICES_DEVICE_PUBLIC_MOJOM_USB_DEVICE_MOJOM_JUMBO_H_
#endif



namespace device {
namespace mojom {
const char UsbControlTransferParams::kSecurityKeyAOAModel[] = "12eba9f901039b36";
UsbEndpointInfo::UsbEndpointInfo()
    : endpoint_number(),
      direction(),
      type(),
      packet_size(),
      synchronization_type(),
      usage_type(),
      polling_interval(),
      extra_data() {}

UsbEndpointInfo::UsbEndpointInfo(
    uint8_t endpoint_number_in,
    UsbTransferDirection direction_in,
    UsbTransferType type_in,
    uint32_t packet_size_in,
    UsbSynchronizationType synchronization_type_in,
    UsbUsageType usage_type_in,
    uint8_t polling_interval_in,
    std::vector<uint8_t> extra_data_in)
    : endpoint_number(std::move(endpoint_number_in)),
      direction(std::move(direction_in)),
      type(std::move(type_in)),
      packet_size(std::move(packet_size_in)),
      synchronization_type(std::move(synchronization_type_in)),
      usage_type(std::move(usage_type_in)),
      polling_interval(std::move(polling_interval_in)),
      extra_data(std::move(extra_data_in)) {}

UsbEndpointInfo::~UsbEndpointInfo() = default;

void UsbEndpointInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "endpoint_number"), this->endpoint_number,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "direction"), this->direction,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbTransferDirection>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "type"), this->type,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbTransferType>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "packet_size"), this->packet_size,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "synchronization_type"), this->synchronization_type,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbSynchronizationType>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "usage_type"), this->usage_type,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbUsageType>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "polling_interval"), this->polling_interval,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "extra_data"), this->extra_data,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const std::vector<uint8_t>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbEndpointInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
UsbAlternateInterfaceInfo::UsbAlternateInterfaceInfo()
    : alternate_setting(),
      class_code(),
      subclass_code(),
      protocol_code(),
      interface_name(),
      endpoints(),
      extra_data() {}

UsbAlternateInterfaceInfo::UsbAlternateInterfaceInfo(
    uint8_t alternate_setting_in,
    uint8_t class_code_in,
    uint8_t subclass_code_in,
    uint8_t protocol_code_in,
    const absl::optional<::std::u16string>& interface_name_in,
    std::vector<UsbEndpointInfoPtr> endpoints_in,
    std::vector<uint8_t> extra_data_in)
    : alternate_setting(std::move(alternate_setting_in)),
      class_code(std::move(class_code_in)),
      subclass_code(std::move(subclass_code_in)),
      protocol_code(std::move(protocol_code_in)),
      interface_name(std::move(interface_name_in)),
      endpoints(std::move(endpoints_in)),
      extra_data(std::move(extra_data_in)) {}

UsbAlternateInterfaceInfo::~UsbAlternateInterfaceInfo() = default;

void UsbAlternateInterfaceInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "alternate_setting"), this->alternate_setting,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "class_code"), this->class_code,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "subclass_code"), this->subclass_code,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "protocol_code"), this->protocol_code,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "interface_name"), this->interface_name,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const absl::optional<::std::u16string>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "endpoints"), this->endpoints,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type std::vector<UsbEndpointInfoPtr>>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "extra_data"), this->extra_data,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const std::vector<uint8_t>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbAlternateInterfaceInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
UsbInterfaceInfo::UsbInterfaceInfo()
    : interface_number(),
      first_interface(),
      alternates() {}

UsbInterfaceInfo::UsbInterfaceInfo(
    uint8_t interface_number_in,
    uint8_t first_interface_in,
    std::vector<UsbAlternateInterfaceInfoPtr> alternates_in)
    : interface_number(std::move(interface_number_in)),
      first_interface(std::move(first_interface_in)),
      alternates(std::move(alternates_in)) {}

UsbInterfaceInfo::~UsbInterfaceInfo() = default;

void UsbInterfaceInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "interface_number"), this->interface_number,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "first_interface"), this->first_interface,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "alternates"), this->alternates,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type std::vector<UsbAlternateInterfaceInfoPtr>>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbInterfaceInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
UsbConfigurationInfo::UsbConfigurationInfo()
    : configuration_value(),
      configuration_name(),
      self_powered(),
      remote_wakeup(),
      maximum_power(),
      interfaces(),
      extra_data() {}

UsbConfigurationInfo::UsbConfigurationInfo(
    uint8_t configuration_value_in,
    const absl::optional<::std::u16string>& configuration_name_in,
    bool self_powered_in,
    bool remote_wakeup_in,
    uint8_t maximum_power_in,
    std::vector<UsbInterfaceInfoPtr> interfaces_in,
    std::vector<uint8_t> extra_data_in)
    : configuration_value(std::move(configuration_value_in)),
      configuration_name(std::move(configuration_name_in)),
      self_powered(std::move(self_powered_in)),
      remote_wakeup(std::move(remote_wakeup_in)),
      maximum_power(std::move(maximum_power_in)),
      interfaces(std::move(interfaces_in)),
      extra_data(std::move(extra_data_in)) {}

UsbConfigurationInfo::~UsbConfigurationInfo() = default;

void UsbConfigurationInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "configuration_value"), this->configuration_value,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "configuration_name"), this->configuration_name,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const absl::optional<::std::u16string>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "self_powered"), this->self_powered,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "remote_wakeup"), this->remote_wakeup,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "maximum_power"), this->maximum_power,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "interfaces"), this->interfaces,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type std::vector<UsbInterfaceInfoPtr>>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "extra_data"), this->extra_data,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const std::vector<uint8_t>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbConfigurationInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
UsbDeviceInfo::UsbDeviceInfo()
    : guid(),
      usb_version_major(),
      usb_version_minor(),
      usb_version_subminor(),
      class_code(),
      subclass_code(),
      protocol_code(),
      bus_number(),
      port_number(),
      vendor_id(),
      product_id(),
      device_version_major(),
      device_version_minor(),
      device_version_subminor(),
      manufacturer_name(),
      product_name(),
      serial_number(),
      webusb_landing_page(),
      active_configuration(),
      configurations() {}

UsbDeviceInfo::UsbDeviceInfo(
    const std::string& guid_in,
    uint8_t usb_version_major_in,
    uint8_t usb_version_minor_in,
    uint8_t usb_version_subminor_in,
    uint8_t class_code_in,
    uint8_t subclass_code_in,
    uint8_t protocol_code_in,
    uint32_t bus_number_in,
    uint32_t port_number_in,
    uint16_t vendor_id_in,
    uint16_t product_id_in,
    uint8_t device_version_major_in,
    uint8_t device_version_minor_in,
    uint8_t device_version_subminor_in,
    const absl::optional<::std::u16string>& manufacturer_name_in,
    const absl::optional<::std::u16string>& product_name_in,
    const absl::optional<::std::u16string>& serial_number_in,
    const absl::optional<::GURL>& webusb_landing_page_in,
    uint8_t active_configuration_in,
    std::vector<UsbConfigurationInfoPtr> configurations_in)
    : guid(std::move(guid_in)),
      usb_version_major(std::move(usb_version_major_in)),
      usb_version_minor(std::move(usb_version_minor_in)),
      usb_version_subminor(std::move(usb_version_subminor_in)),
      class_code(std::move(class_code_in)),
      subclass_code(std::move(subclass_code_in)),
      protocol_code(std::move(protocol_code_in)),
      bus_number(std::move(bus_number_in)),
      port_number(std::move(port_number_in)),
      vendor_id(std::move(vendor_id_in)),
      product_id(std::move(product_id_in)),
      device_version_major(std::move(device_version_major_in)),
      device_version_minor(std::move(device_version_minor_in)),
      device_version_subminor(std::move(device_version_subminor_in)),
      manufacturer_name(std::move(manufacturer_name_in)),
      product_name(std::move(product_name_in)),
      serial_number(std::move(serial_number_in)),
      webusb_landing_page(std::move(webusb_landing_page_in)),
      active_configuration(std::move(active_configuration_in)),
      configurations(std::move(configurations_in)) {}

UsbDeviceInfo::~UsbDeviceInfo() = default;

void UsbDeviceInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "guid"), this->guid,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const std::string&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "usb_version_major"), this->usb_version_major,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "usb_version_minor"), this->usb_version_minor,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "usb_version_subminor"), this->usb_version_subminor,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "class_code"), this->class_code,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "subclass_code"), this->subclass_code,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "protocol_code"), this->protocol_code,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "bus_number"), this->bus_number,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "port_number"), this->port_number,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "vendor_id"), this->vendor_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint16_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "product_id"), this->product_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint16_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "device_version_major"), this->device_version_major,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "device_version_minor"), this->device_version_minor,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "device_version_subminor"), this->device_version_subminor,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "manufacturer_name"), this->manufacturer_name,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const absl::optional<::std::u16string>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "product_name"), this->product_name,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const absl::optional<::std::u16string>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "serial_number"), this->serial_number,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const absl::optional<::std::u16string>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "webusb_landing_page"), this->webusb_landing_page,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const absl::optional<::GURL>&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "active_configuration"), this->active_configuration,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "configurations"), this->configurations,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type std::vector<UsbConfigurationInfoPtr>>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbDeviceInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
UsbControlTransferParams::UsbControlTransferParams()
    : type(),
      recipient(),
      request(),
      value(),
      index() {}

UsbControlTransferParams::UsbControlTransferParams(
    UsbControlTransferType type_in,
    UsbControlTransferRecipient recipient_in,
    uint8_t request_in,
    uint16_t value_in,
    uint16_t index_in)
    : type(std::move(type_in)),
      recipient(std::move(recipient_in)),
      request(std::move(request_in)),
      value(std::move(value_in)),
      index(std::move(index_in)) {}

UsbControlTransferParams::~UsbControlTransferParams() = default;
size_t UsbControlTransferParams::Hash(size_t seed) const {
  seed = mojo::internal::Hash(seed, this->type);
  seed = mojo::internal::Hash(seed, this->recipient);
  seed = mojo::internal::Hash(seed, this->request);
  seed = mojo::internal::Hash(seed, this->value);
  seed = mojo::internal::Hash(seed, this->index);
  return seed;
}

void UsbControlTransferParams::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "type"), this->type,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbControlTransferType>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "recipient"), this->recipient,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbControlTransferRecipient>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "request"), this->request,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint8_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "value"), this->value,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint16_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "index"), this->index,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint16_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbControlTransferParams::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
UsbIsochronousPacket::UsbIsochronousPacket()
    : length(),
      transferred_length(),
      status() {}

UsbIsochronousPacket::UsbIsochronousPacket(
    uint32_t length_in,
    uint32_t transferred_length_in,
    UsbTransferStatus status_in)
    : length(std::move(length_in)),
      transferred_length(std::move(transferred_length_in)),
      status(std::move(status_in)) {}

UsbIsochronousPacket::~UsbIsochronousPacket() = default;
size_t UsbIsochronousPacket::Hash(size_t seed) const {
  seed = mojo::internal::Hash(seed, this->length);
  seed = mojo::internal::Hash(seed, this->transferred_length);
  seed = mojo::internal::Hash(seed, this->status);
  return seed;
}

void UsbIsochronousPacket::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "length"), this->length,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "transferred_length"), this->transferred_length,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "status"), this->status,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type UsbTransferStatus>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool UsbIsochronousPacket::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
const char UsbDevice::Name_[] = "device.mojom.UsbDevice";

std::pair<uint32_t, const void*> UsbDevice::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kUsbDevice_Open_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::Open");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::Open_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_Close_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::Close");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::Close_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_SetConfiguration_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::SetConfiguration");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::SetConfiguration_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_ClaimInterface_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::ClaimInterface");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::ClaimInterface_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_ReleaseInterface_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::ReleaseInterface");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::ReleaseInterface_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_SetInterfaceAlternateSetting_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::SetInterfaceAlternateSetting");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::SetInterfaceAlternateSetting_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_Reset_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::Reset");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::Reset_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_ClearHalt_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::ClearHalt");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::ClearHalt_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_ControlTransferIn_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::ControlTransferIn");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::ControlTransferIn_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_ControlTransferOut_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::ControlTransferOut");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::ControlTransferOut_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_GenericTransferIn_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::GenericTransferIn");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::GenericTransferIn_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_GenericTransferOut_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::GenericTransferOut");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::GenericTransferOut_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_IsochronousTransferIn_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::IsochronousTransferIn");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::IsochronousTransferIn_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDevice_IsochronousTransferOut_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDevice::IsochronousTransferOut");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDevice::IsochronousTransferOut_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* UsbDevice::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kUsbDevice_Open_Name:
            return "Receive device::mojom::UsbDevice::Open";
      case internal::kUsbDevice_Close_Name:
            return "Receive device::mojom::UsbDevice::Close";
      case internal::kUsbDevice_SetConfiguration_Name:
            return "Receive device::mojom::UsbDevice::SetConfiguration";
      case internal::kUsbDevice_ClaimInterface_Name:
            return "Receive device::mojom::UsbDevice::ClaimInterface";
      case internal::kUsbDevice_ReleaseInterface_Name:
            return "Receive device::mojom::UsbDevice::ReleaseInterface";
      case internal::kUsbDevice_SetInterfaceAlternateSetting_Name:
            return "Receive device::mojom::UsbDevice::SetInterfaceAlternateSetting";
      case internal::kUsbDevice_Reset_Name:
            return "Receive device::mojom::UsbDevice::Reset";
      case internal::kUsbDevice_ClearHalt_Name:
            return "Receive device::mojom::UsbDevice::ClearHalt";
      case internal::kUsbDevice_ControlTransferIn_Name:
            return "Receive device::mojom::UsbDevice::ControlTransferIn";
      case internal::kUsbDevice_ControlTransferOut_Name:
            return "Receive device::mojom::UsbDevice::ControlTransferOut";
      case internal::kUsbDevice_GenericTransferIn_Name:
            return "Receive device::mojom::UsbDevice::GenericTransferIn";
      case internal::kUsbDevice_GenericTransferOut_Name:
            return "Receive device::mojom::UsbDevice::GenericTransferOut";
      case internal::kUsbDevice_IsochronousTransferIn_Name:
            return "Receive device::mojom::UsbDevice::IsochronousTransferIn";
      case internal::kUsbDevice_IsochronousTransferOut_Name:
            return "Receive device::mojom::UsbDevice::IsochronousTransferOut";
    }
  } else {
    switch (message.name()) {
      case internal::kUsbDevice_Open_Name:
            return "Receive reply device::mojom::UsbDevice::Open";
      case internal::kUsbDevice_Close_Name:
            return "Receive reply device::mojom::UsbDevice::Close";
      case internal::kUsbDevice_SetConfiguration_Name:
            return "Receive reply device::mojom::UsbDevice::SetConfiguration";
      case internal::kUsbDevice_ClaimInterface_Name:
            return "Receive reply device::mojom::UsbDevice::ClaimInterface";
      case internal::kUsbDevice_ReleaseInterface_Name:
            return "Receive reply device::mojom::UsbDevice::ReleaseInterface";
      case internal::kUsbDevice_SetInterfaceAlternateSetting_Name:
            return "Receive reply device::mojom::UsbDevice::SetInterfaceAlternateSetting";
      case internal::kUsbDevice_Reset_Name:
            return "Receive reply device::mojom::UsbDevice::Reset";
      case internal::kUsbDevice_ClearHalt_Name:
            return "Receive reply device::mojom::UsbDevice::ClearHalt";
      case internal::kUsbDevice_ControlTransferIn_Name:
            return "Receive reply device::mojom::UsbDevice::ControlTransferIn";
      case internal::kUsbDevice_ControlTransferOut_Name:
            return "Receive reply device::mojom::UsbDevice::ControlTransferOut";
      case internal::kUsbDevice_GenericTransferIn_Name:
            return "Receive reply device::mojom::UsbDevice::GenericTransferIn";
      case internal::kUsbDevice_GenericTransferOut_Name:
            return "Receive reply device::mojom::UsbDevice::GenericTransferOut";
      case internal::kUsbDevice_IsochronousTransferIn_Name:
            return "Receive reply device::mojom::UsbDevice::IsochronousTransferIn";
      case internal::kUsbDevice_IsochronousTransferOut_Name:
            return "Receive reply device::mojom::UsbDevice::IsochronousTransferOut";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
void UsbDevice::Open_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::Close_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::SetConfiguration_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::ClaimInterface_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::ReleaseInterface_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::SetInterfaceAlternateSetting_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::Reset_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::ClearHalt_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::ControlTransferIn_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::ControlTransferOut_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::GenericTransferIn_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::GenericTransferOut_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::IsochronousTransferIn_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDevice::IsochronousTransferOut_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
# endif // !BUILDFLAG(IS_FUCHSIA)

class UsbDevice_Open_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_Open_ForwardToCallback(
      UsbDevice::OpenCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_Open_ForwardToCallback(const UsbDevice_Open_ForwardToCallback&) = delete;
  UsbDevice_Open_ForwardToCallback& operator=(const UsbDevice_Open_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::OpenCallback callback_;
};

class UsbDevice_Close_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_Close_ForwardToCallback(
      UsbDevice::CloseCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_Close_ForwardToCallback(const UsbDevice_Close_ForwardToCallback&) = delete;
  UsbDevice_Close_ForwardToCallback& operator=(const UsbDevice_Close_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::CloseCallback callback_;
};

class UsbDevice_SetConfiguration_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_SetConfiguration_ForwardToCallback(
      UsbDevice::SetConfigurationCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_SetConfiguration_ForwardToCallback(const UsbDevice_SetConfiguration_ForwardToCallback&) = delete;
  UsbDevice_SetConfiguration_ForwardToCallback& operator=(const UsbDevice_SetConfiguration_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::SetConfigurationCallback callback_;
};

class UsbDevice_ClaimInterface_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_ClaimInterface_ForwardToCallback(
      UsbDevice::ClaimInterfaceCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_ClaimInterface_ForwardToCallback(const UsbDevice_ClaimInterface_ForwardToCallback&) = delete;
  UsbDevice_ClaimInterface_ForwardToCallback& operator=(const UsbDevice_ClaimInterface_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::ClaimInterfaceCallback callback_;
};

class UsbDevice_ReleaseInterface_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_ReleaseInterface_ForwardToCallback(
      UsbDevice::ReleaseInterfaceCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_ReleaseInterface_ForwardToCallback(const UsbDevice_ReleaseInterface_ForwardToCallback&) = delete;
  UsbDevice_ReleaseInterface_ForwardToCallback& operator=(const UsbDevice_ReleaseInterface_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::ReleaseInterfaceCallback callback_;
};

class UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback(
      UsbDevice::SetInterfaceAlternateSettingCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback(const UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback&) = delete;
  UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback& operator=(const UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::SetInterfaceAlternateSettingCallback callback_;
};

class UsbDevice_Reset_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_Reset_ForwardToCallback(
      UsbDevice::ResetCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_Reset_ForwardToCallback(const UsbDevice_Reset_ForwardToCallback&) = delete;
  UsbDevice_Reset_ForwardToCallback& operator=(const UsbDevice_Reset_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::ResetCallback callback_;
};

class UsbDevice_ClearHalt_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_ClearHalt_ForwardToCallback(
      UsbDevice::ClearHaltCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_ClearHalt_ForwardToCallback(const UsbDevice_ClearHalt_ForwardToCallback&) = delete;
  UsbDevice_ClearHalt_ForwardToCallback& operator=(const UsbDevice_ClearHalt_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::ClearHaltCallback callback_;
};

class UsbDevice_ControlTransferIn_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_ControlTransferIn_ForwardToCallback(
      UsbDevice::ControlTransferInCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_ControlTransferIn_ForwardToCallback(const UsbDevice_ControlTransferIn_ForwardToCallback&) = delete;
  UsbDevice_ControlTransferIn_ForwardToCallback& operator=(const UsbDevice_ControlTransferIn_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::ControlTransferInCallback callback_;
};

class UsbDevice_ControlTransferOut_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_ControlTransferOut_ForwardToCallback(
      UsbDevice::ControlTransferOutCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_ControlTransferOut_ForwardToCallback(const UsbDevice_ControlTransferOut_ForwardToCallback&) = delete;
  UsbDevice_ControlTransferOut_ForwardToCallback& operator=(const UsbDevice_ControlTransferOut_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::ControlTransferOutCallback callback_;
};

class UsbDevice_GenericTransferIn_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_GenericTransferIn_ForwardToCallback(
      UsbDevice::GenericTransferInCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_GenericTransferIn_ForwardToCallback(const UsbDevice_GenericTransferIn_ForwardToCallback&) = delete;
  UsbDevice_GenericTransferIn_ForwardToCallback& operator=(const UsbDevice_GenericTransferIn_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::GenericTransferInCallback callback_;
};

class UsbDevice_GenericTransferOut_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_GenericTransferOut_ForwardToCallback(
      UsbDevice::GenericTransferOutCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_GenericTransferOut_ForwardToCallback(const UsbDevice_GenericTransferOut_ForwardToCallback&) = delete;
  UsbDevice_GenericTransferOut_ForwardToCallback& operator=(const UsbDevice_GenericTransferOut_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::GenericTransferOutCallback callback_;
};

class UsbDevice_IsochronousTransferIn_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_IsochronousTransferIn_ForwardToCallback(
      UsbDevice::IsochronousTransferInCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_IsochronousTransferIn_ForwardToCallback(const UsbDevice_IsochronousTransferIn_ForwardToCallback&) = delete;
  UsbDevice_IsochronousTransferIn_ForwardToCallback& operator=(const UsbDevice_IsochronousTransferIn_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::IsochronousTransferInCallback callback_;
};

class UsbDevice_IsochronousTransferOut_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  UsbDevice_IsochronousTransferOut_ForwardToCallback(
      UsbDevice::IsochronousTransferOutCallback callback
      ) : callback_(std::move(callback)) {
  }

  UsbDevice_IsochronousTransferOut_ForwardToCallback(const UsbDevice_IsochronousTransferOut_ForwardToCallback&) = delete;
  UsbDevice_IsochronousTransferOut_ForwardToCallback& operator=(const UsbDevice_IsochronousTransferOut_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  UsbDevice::IsochronousTransferOutCallback callback_;
};

UsbDeviceProxy::UsbDeviceProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void UsbDeviceProxy::Open(
    OpenCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::UsbDevice::Open");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_Open_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_Open_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("Open");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_Open_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::Close(
    CloseCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::UsbDevice::Close");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_Close_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_Close_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("Close");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_Close_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::SetConfiguration(
    uint8_t in_value, SetConfigurationCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::SetConfiguration", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("value"), in_value,
                        "<value of type uint8_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_SetConfiguration_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_SetConfiguration_Params_Data> params(
          message);
  params.Allocate();
  params->value = in_value;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("SetConfiguration");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_SetConfiguration_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::ClaimInterface(
    uint8_t in_interface_number, ClaimInterfaceCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::ClaimInterface", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("interface_number"), in_interface_number,
                        "<value of type uint8_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ClaimInterface_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ClaimInterface_Params_Data> params(
          message);
  params.Allocate();
  params->interface_number = in_interface_number;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ClaimInterface");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_ClaimInterface_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::ReleaseInterface(
    uint8_t in_interface_number, ReleaseInterfaceCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::ReleaseInterface", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("interface_number"), in_interface_number,
                        "<value of type uint8_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ReleaseInterface_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ReleaseInterface_Params_Data> params(
          message);
  params.Allocate();
  params->interface_number = in_interface_number;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ReleaseInterface");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_ReleaseInterface_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::SetInterfaceAlternateSetting(
    uint8_t in_interface_number, uint8_t in_alternate_setting, SetInterfaceAlternateSettingCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::SetInterfaceAlternateSetting", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("interface_number"), in_interface_number,
                        "<value of type uint8_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("alternate_setting"), in_alternate_setting,
                        "<value of type uint8_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_SetInterfaceAlternateSetting_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_SetInterfaceAlternateSetting_Params_Data> params(
          message);
  params.Allocate();
  params->interface_number = in_interface_number;
  params->alternate_setting = in_alternate_setting;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("SetInterfaceAlternateSetting");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::Reset(
    ResetCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::UsbDevice::Reset");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_Reset_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_Reset_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("Reset");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_Reset_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::ClearHalt(
    UsbTransferDirection in_direction, uint8_t in_endpoint_number, ClearHaltCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::ClearHalt", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("direction"), in_direction,
                        "<value of type UsbTransferDirection>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("endpoint_number"), in_endpoint_number,
                        "<value of type uint8_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ClearHalt_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ClearHalt_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbTransferDirection>(
      in_direction, &params->direction);
  params->endpoint_number = in_endpoint_number;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ClearHalt");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_ClearHalt_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::ControlTransferIn(
    UsbControlTransferParamsPtr in_params, uint32_t in_length, uint32_t in_timeout, ControlTransferInCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::ControlTransferIn", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("params"), in_params,
                        "<value of type UsbControlTransferParamsPtr>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("length"), in_length,
                        "<value of type uint32_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("timeout"), in_timeout,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ControlTransferIn_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ControlTransferIn_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->params)::BaseType> params_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::UsbControlTransferParamsDataView>(
      in_params, params_fragment);
  params->params.Set(
      params_fragment.is_null() ? nullptr : params_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->params.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null params in UsbDevice.ControlTransferIn request");
  params->length = in_length;
  params->timeout = in_timeout;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ControlTransferIn");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_ControlTransferIn_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::ControlTransferOut(
    UsbControlTransferParamsPtr in_params, ::base::span<const ::uint8_t> in_data, uint32_t in_timeout, ControlTransferOutCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::ControlTransferOut", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("params"), in_params,
                        "<value of type UsbControlTransferParamsPtr>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("data"), in_data,
                        "<value of type ::base::span<const ::uint8_t>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("timeout"), in_timeout,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ControlTransferOut_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ControlTransferOut_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->params)::BaseType> params_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::UsbControlTransferParamsDataView>(
      in_params, params_fragment);
  params->params.Set(
      params_fragment.is_null() ? nullptr : params_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->params.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null params in UsbDevice.ControlTransferOut request");
  mojo::internal::MessageFragment<
      typename decltype(params->data)::BaseType> data_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::ReadOnlyBufferDataView>(
      in_data, data_fragment);
  params->data.Set(
      data_fragment.is_null() ? nullptr : data_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->data.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null data in UsbDevice.ControlTransferOut request");
  params->timeout = in_timeout;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ControlTransferOut");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_ControlTransferOut_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::GenericTransferIn(
    uint8_t in_endpoint_number, uint32_t in_length, uint32_t in_timeout, GenericTransferInCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::GenericTransferIn", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("endpoint_number"), in_endpoint_number,
                        "<value of type uint8_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("length"), in_length,
                        "<value of type uint32_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("timeout"), in_timeout,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_GenericTransferIn_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_GenericTransferIn_Params_Data> params(
          message);
  params.Allocate();
  params->endpoint_number = in_endpoint_number;
  params->length = in_length;
  params->timeout = in_timeout;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("GenericTransferIn");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_GenericTransferIn_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::GenericTransferOut(
    uint8_t in_endpoint_number, ::base::span<const ::uint8_t> in_data, uint32_t in_timeout, GenericTransferOutCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::GenericTransferOut", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("endpoint_number"), in_endpoint_number,
                        "<value of type uint8_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("data"), in_data,
                        "<value of type ::base::span<const ::uint8_t>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("timeout"), in_timeout,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_GenericTransferOut_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_GenericTransferOut_Params_Data> params(
          message);
  params.Allocate();
  params->endpoint_number = in_endpoint_number;
  mojo::internal::MessageFragment<
      typename decltype(params->data)::BaseType> data_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::ReadOnlyBufferDataView>(
      in_data, data_fragment);
  params->data.Set(
      data_fragment.is_null() ? nullptr : data_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->data.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null data in UsbDevice.GenericTransferOut request");
  params->timeout = in_timeout;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("GenericTransferOut");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_GenericTransferOut_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::IsochronousTransferIn(
    uint8_t in_endpoint_number, const std::vector<uint32_t>& in_packet_lengths, uint32_t in_timeout, IsochronousTransferInCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::IsochronousTransferIn", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("endpoint_number"), in_endpoint_number,
                        "<value of type uint8_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("packet_lengths"), in_packet_lengths,
                        "<value of type const std::vector<uint32_t>&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("timeout"), in_timeout,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_IsochronousTransferIn_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_IsochronousTransferIn_Params_Data> params(
          message);
  params.Allocate();
  params->endpoint_number = in_endpoint_number;
  mojo::internal::MessageFragment<
      typename decltype(params->packet_lengths)::BaseType>
      packet_lengths_fragment(params.message());
  const mojo::internal::ContainerValidateParams packet_lengths_validate_params(
      0, false, nullptr);
  mojo::internal::Serialize<mojo::ArrayDataView<uint32_t>>(
      in_packet_lengths, packet_lengths_fragment, &packet_lengths_validate_params);
  params->packet_lengths.Set(
      packet_lengths_fragment.is_null() ? nullptr : packet_lengths_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->packet_lengths.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null packet_lengths in UsbDevice.IsochronousTransferIn request");
  params->timeout = in_timeout;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("IsochronousTransferIn");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_IsochronousTransferIn_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void UsbDeviceProxy::IsochronousTransferOut(
    uint8_t in_endpoint_number, ::base::span<const ::uint8_t> in_data, const std::vector<uint32_t>& in_packet_lengths, uint32_t in_timeout, IsochronousTransferOutCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::UsbDevice::IsochronousTransferOut", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("endpoint_number"), in_endpoint_number,
                        "<value of type uint8_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("data"), in_data,
                        "<value of type ::base::span<const ::uint8_t>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("packet_lengths"), in_packet_lengths,
                        "<value of type const std::vector<uint32_t>&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("timeout"), in_timeout,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_IsochronousTransferOut_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_IsochronousTransferOut_Params_Data> params(
          message);
  params.Allocate();
  params->endpoint_number = in_endpoint_number;
  mojo::internal::MessageFragment<
      typename decltype(params->data)::BaseType> data_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::ReadOnlyBufferDataView>(
      in_data, data_fragment);
  params->data.Set(
      data_fragment.is_null() ? nullptr : data_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->data.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null data in UsbDevice.IsochronousTransferOut request");
  mojo::internal::MessageFragment<
      typename decltype(params->packet_lengths)::BaseType>
      packet_lengths_fragment(params.message());
  const mojo::internal::ContainerValidateParams packet_lengths_validate_params(
      0, false, nullptr);
  mojo::internal::Serialize<mojo::ArrayDataView<uint32_t>>(
      in_packet_lengths, packet_lengths_fragment, &packet_lengths_validate_params);
  params->packet_lengths.Set(
      packet_lengths_fragment.is_null() ? nullptr : packet_lengths_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->packet_lengths.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null packet_lengths in UsbDevice.IsochronousTransferOut request");
  params->timeout = in_timeout;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("IsochronousTransferOut");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new UsbDevice_IsochronousTransferOut_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
class UsbDevice_Open_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::OpenCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_Open_ProxyToResponder> proxy(
        new UsbDevice_Open_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_Open_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_Open_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_Open_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::OpenCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      UsbOpenDeviceError in_error);
};

bool UsbDevice_Open_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_Open_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_Open_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbOpenDeviceError p_error{};
  UsbDevice_Open_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadError(&p_error))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 0, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_error));
  return true;
}

void UsbDevice_Open_ProxyToResponder::Run(
    UsbOpenDeviceError in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::Open", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type UsbOpenDeviceError>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_Open_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_Open_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbOpenDeviceError>(
      in_error, &params->error);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("Open");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_Close_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::CloseCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_Close_ProxyToResponder> proxy(
        new UsbDevice_Close_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_Close_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_Close_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_Close_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::CloseCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      );
};

bool UsbDevice_Close_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_Close_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_Close_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbDevice_Close_ResponseParamsDataView input_data_view(params, message);
  
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 1, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run();
  return true;
}

void UsbDevice_Close_ProxyToResponder::Run(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send reply device::mojom::UsbDevice::Close");
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_Close_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_Close_ResponseParams_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("Close");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_SetConfiguration_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::SetConfigurationCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_SetConfiguration_ProxyToResponder> proxy(
        new UsbDevice_SetConfiguration_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_SetConfiguration_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_SetConfiguration_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_SetConfiguration_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::SetConfigurationCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool UsbDevice_SetConfiguration_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_SetConfiguration_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_SetConfiguration_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  UsbDevice_SetConfiguration_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 2, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void UsbDevice_SetConfiguration_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::SetConfiguration", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_SetConfiguration_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_SetConfiguration_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("SetConfiguration");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_ClaimInterface_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::ClaimInterfaceCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_ClaimInterface_ProxyToResponder> proxy(
        new UsbDevice_ClaimInterface_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_ClaimInterface_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_ClaimInterface_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_ClaimInterface_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::ClaimInterfaceCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      UsbClaimInterfaceResult in_result);
};

bool UsbDevice_ClaimInterface_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_ClaimInterface_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_ClaimInterface_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbClaimInterfaceResult p_result{};
  UsbDevice_ClaimInterface_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadResult(&p_result))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 3, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_result));
  return true;
}

void UsbDevice_ClaimInterface_ProxyToResponder::Run(
    UsbClaimInterfaceResult in_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::ClaimInterface", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), in_result,
                        "<value of type UsbClaimInterfaceResult>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ClaimInterface_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ClaimInterface_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbClaimInterfaceResult>(
      in_result, &params->result);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ClaimInterface");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_ReleaseInterface_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::ReleaseInterfaceCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_ReleaseInterface_ProxyToResponder> proxy(
        new UsbDevice_ReleaseInterface_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_ReleaseInterface_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_ReleaseInterface_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_ReleaseInterface_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::ReleaseInterfaceCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool UsbDevice_ReleaseInterface_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_ReleaseInterface_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_ReleaseInterface_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  UsbDevice_ReleaseInterface_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 4, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void UsbDevice_ReleaseInterface_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::ReleaseInterface", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ReleaseInterface_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ReleaseInterface_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ReleaseInterface");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::SetInterfaceAlternateSettingCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder> proxy(
        new UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::SetInterfaceAlternateSettingCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool UsbDevice_SetInterfaceAlternateSetting_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_SetInterfaceAlternateSetting_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_SetInterfaceAlternateSetting_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  UsbDevice_SetInterfaceAlternateSetting_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 5, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::SetInterfaceAlternateSetting", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_SetInterfaceAlternateSetting_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_SetInterfaceAlternateSetting_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("SetInterfaceAlternateSetting");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_Reset_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::ResetCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_Reset_ProxyToResponder> proxy(
        new UsbDevice_Reset_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_Reset_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_Reset_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_Reset_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::ResetCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool UsbDevice_Reset_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_Reset_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_Reset_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  UsbDevice_Reset_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 6, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void UsbDevice_Reset_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::Reset", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_Reset_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_Reset_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("Reset");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_ClearHalt_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::ClearHaltCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_ClearHalt_ProxyToResponder> proxy(
        new UsbDevice_ClearHalt_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_ClearHalt_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_ClearHalt_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_ClearHalt_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::ClearHaltCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool UsbDevice_ClearHalt_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_ClearHalt_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_ClearHalt_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  UsbDevice_ClearHalt_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 7, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void UsbDevice_ClearHalt_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::ClearHalt", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ClearHalt_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ClearHalt_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ClearHalt");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_ControlTransferIn_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::ControlTransferInCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_ControlTransferIn_ProxyToResponder> proxy(
        new UsbDevice_ControlTransferIn_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_ControlTransferIn_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_ControlTransferIn_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_ControlTransferIn_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::ControlTransferInCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      UsbTransferStatus in_status, ::base::span<const ::uint8_t> in_data);
};

bool UsbDevice_ControlTransferIn_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_ControlTransferIn_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_ControlTransferIn_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbTransferStatus p_status{};
  ::base::span<const ::uint8_t> p_data{};
  UsbDevice_ControlTransferIn_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadStatus(&p_status))
    success = false;
  if (success && !input_data_view.ReadData(&p_data))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 8, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_status), 
std::move(p_data));
  return true;
}

void UsbDevice_ControlTransferIn_ProxyToResponder::Run(
    UsbTransferStatus in_status, ::base::span<const ::uint8_t> in_data) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::ControlTransferIn", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("status"), in_status,
                        "<value of type UsbTransferStatus>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("data"), in_data,
                        "<value of type ::base::span<const ::uint8_t>>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ControlTransferIn_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ControlTransferIn_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbTransferStatus>(
      in_status, &params->status);
  mojo::internal::MessageFragment<
      typename decltype(params->data)::BaseType> data_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::ReadOnlyBufferDataView>(
      in_data, data_fragment);
  params->data.Set(
      data_fragment.is_null() ? nullptr : data_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->data.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null data in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ControlTransferIn");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_ControlTransferOut_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::ControlTransferOutCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_ControlTransferOut_ProxyToResponder> proxy(
        new UsbDevice_ControlTransferOut_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_ControlTransferOut_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_ControlTransferOut_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_ControlTransferOut_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::ControlTransferOutCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      UsbTransferStatus in_status);
};

bool UsbDevice_ControlTransferOut_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_ControlTransferOut_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_ControlTransferOut_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbTransferStatus p_status{};
  UsbDevice_ControlTransferOut_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadStatus(&p_status))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 9, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_status));
  return true;
}

void UsbDevice_ControlTransferOut_ProxyToResponder::Run(
    UsbTransferStatus in_status) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::ControlTransferOut", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("status"), in_status,
                        "<value of type UsbTransferStatus>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_ControlTransferOut_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_ControlTransferOut_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbTransferStatus>(
      in_status, &params->status);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("ControlTransferOut");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_GenericTransferIn_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::GenericTransferInCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_GenericTransferIn_ProxyToResponder> proxy(
        new UsbDevice_GenericTransferIn_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_GenericTransferIn_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_GenericTransferIn_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_GenericTransferIn_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::GenericTransferInCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      UsbTransferStatus in_status, ::base::span<const ::uint8_t> in_data);
};

bool UsbDevice_GenericTransferIn_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_GenericTransferIn_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_GenericTransferIn_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbTransferStatus p_status{};
  ::base::span<const ::uint8_t> p_data{};
  UsbDevice_GenericTransferIn_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadStatus(&p_status))
    success = false;
  if (success && !input_data_view.ReadData(&p_data))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 10, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_status), 
std::move(p_data));
  return true;
}

void UsbDevice_GenericTransferIn_ProxyToResponder::Run(
    UsbTransferStatus in_status, ::base::span<const ::uint8_t> in_data) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::GenericTransferIn", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("status"), in_status,
                        "<value of type UsbTransferStatus>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("data"), in_data,
                        "<value of type ::base::span<const ::uint8_t>>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_GenericTransferIn_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_GenericTransferIn_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbTransferStatus>(
      in_status, &params->status);
  mojo::internal::MessageFragment<
      typename decltype(params->data)::BaseType> data_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::ReadOnlyBufferDataView>(
      in_data, data_fragment);
  params->data.Set(
      data_fragment.is_null() ? nullptr : data_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->data.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null data in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("GenericTransferIn");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_GenericTransferOut_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::GenericTransferOutCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_GenericTransferOut_ProxyToResponder> proxy(
        new UsbDevice_GenericTransferOut_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_GenericTransferOut_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_GenericTransferOut_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_GenericTransferOut_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::GenericTransferOutCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      UsbTransferStatus in_status);
};

bool UsbDevice_GenericTransferOut_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_GenericTransferOut_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_GenericTransferOut_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  UsbTransferStatus p_status{};
  UsbDevice_GenericTransferOut_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadStatus(&p_status))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 11, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_status));
  return true;
}

void UsbDevice_GenericTransferOut_ProxyToResponder::Run(
    UsbTransferStatus in_status) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::GenericTransferOut", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("status"), in_status,
                        "<value of type UsbTransferStatus>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_GenericTransferOut_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_GenericTransferOut_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::UsbTransferStatus>(
      in_status, &params->status);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("GenericTransferOut");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_IsochronousTransferIn_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::IsochronousTransferInCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_IsochronousTransferIn_ProxyToResponder> proxy(
        new UsbDevice_IsochronousTransferIn_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_IsochronousTransferIn_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_IsochronousTransferIn_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_IsochronousTransferIn_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::IsochronousTransferInCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      ::base::span<const ::uint8_t> in_data, std::vector<UsbIsochronousPacketPtr> in_packets);
};

bool UsbDevice_IsochronousTransferIn_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_IsochronousTransferIn_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_IsochronousTransferIn_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  ::base::span<const ::uint8_t> p_data{};
  std::vector<UsbIsochronousPacketPtr> p_packets{};
  UsbDevice_IsochronousTransferIn_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadData(&p_data))
    success = false;
  if (success && !input_data_view.ReadPackets(&p_packets))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 12, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_data), 
std::move(p_packets));
  return true;
}

void UsbDevice_IsochronousTransferIn_ProxyToResponder::Run(
    ::base::span<const ::uint8_t> in_data, std::vector<UsbIsochronousPacketPtr> in_packets) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::IsochronousTransferIn", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("data"), in_data,
                        "<value of type ::base::span<const ::uint8_t>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("packets"), in_packets,
                        "<value of type std::vector<UsbIsochronousPacketPtr>>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_IsochronousTransferIn_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_IsochronousTransferIn_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->data)::BaseType> data_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::ReadOnlyBufferDataView>(
      in_data, data_fragment);
  params->data.Set(
      data_fragment.is_null() ? nullptr : data_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->data.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null data in ");
  mojo::internal::MessageFragment<
      typename decltype(params->packets)::BaseType>
      packets_fragment(params.message());
  const mojo::internal::ContainerValidateParams packets_validate_params(
      0, false, nullptr);
  mojo::internal::Serialize<mojo::ArrayDataView<::device::mojom::UsbIsochronousPacketDataView>>(
      in_packets, packets_fragment, &packets_validate_params);
  params->packets.Set(
      packets_fragment.is_null() ? nullptr : packets_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->packets.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null packets in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("IsochronousTransferIn");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class UsbDevice_IsochronousTransferOut_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static UsbDevice::IsochronousTransferOutCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<UsbDevice_IsochronousTransferOut_ProxyToResponder> proxy(
        new UsbDevice_IsochronousTransferOut_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&UsbDevice_IsochronousTransferOut_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~UsbDevice_IsochronousTransferOut_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  UsbDevice_IsochronousTransferOut_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "UsbDevice::IsochronousTransferOutCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      std::vector<UsbIsochronousPacketPtr> in_packets);
};

bool UsbDevice_IsochronousTransferOut_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::UsbDevice_IsochronousTransferOut_ResponseParams_Data* params =
      reinterpret_cast<
          internal::UsbDevice_IsochronousTransferOut_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  std::vector<UsbIsochronousPacketPtr> p_packets{};
  UsbDevice_IsochronousTransferOut_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadPackets(&p_packets))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        UsbDevice::Name_, 13, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_packets));
  return true;
}

void UsbDevice_IsochronousTransferOut_ProxyToResponder::Run(
    std::vector<UsbIsochronousPacketPtr> in_packets) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::UsbDevice::IsochronousTransferOut", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("packets"), in_packets,
                        "<value of type std::vector<UsbIsochronousPacketPtr>>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDevice_IsochronousTransferOut_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDevice_IsochronousTransferOut_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->packets)::BaseType>
      packets_fragment(params.message());
  const mojo::internal::ContainerValidateParams packets_validate_params(
      0, false, nullptr);
  mojo::internal::Serialize<mojo::ArrayDataView<::device::mojom::UsbIsochronousPacketDataView>>(
      in_packets, packets_fragment, &packets_validate_params);
  params->packets.Set(
      packets_fragment.is_null() ? nullptr : packets_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->packets.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null packets in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDevice::Name_);
  message.set_method_name("IsochronousTransferOut");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}

// static
bool UsbDeviceStubDispatch::Accept(
    UsbDevice* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kUsbDevice_Open_Name: {
      break;
    }
    case internal::kUsbDevice_Close_Name: {
      break;
    }
    case internal::kUsbDevice_SetConfiguration_Name: {
      break;
    }
    case internal::kUsbDevice_ClaimInterface_Name: {
      break;
    }
    case internal::kUsbDevice_ReleaseInterface_Name: {
      break;
    }
    case internal::kUsbDevice_SetInterfaceAlternateSetting_Name: {
      break;
    }
    case internal::kUsbDevice_Reset_Name: {
      break;
    }
    case internal::kUsbDevice_ClearHalt_Name: {
      break;
    }
    case internal::kUsbDevice_ControlTransferIn_Name: {
      break;
    }
    case internal::kUsbDevice_ControlTransferOut_Name: {
      break;
    }
    case internal::kUsbDevice_GenericTransferIn_Name: {
      break;
    }
    case internal::kUsbDevice_GenericTransferOut_Name: {
      break;
    }
    case internal::kUsbDevice_IsochronousTransferIn_Name: {
      break;
    }
    case internal::kUsbDevice_IsochronousTransferOut_Name: {
      break;
    }
  }
  return false;
}

// static
bool UsbDeviceStubDispatch::AcceptWithResponder(
    UsbDevice* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (message->header()->name) {
    case internal::kUsbDevice_Open_Name: {

      internal::UsbDevice_Open_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_Open_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      UsbDevice_Open_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 0, false);
        return false;
      }
      UsbDevice::OpenCallback callback =
          UsbDevice_Open_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Open(std::move(callback));
      return true;
    }
    case internal::kUsbDevice_Close_Name: {

      internal::UsbDevice_Close_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_Close_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      UsbDevice_Close_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 1, false);
        return false;
      }
      UsbDevice::CloseCallback callback =
          UsbDevice_Close_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Close(std::move(callback));
      return true;
    }
    case internal::kUsbDevice_SetConfiguration_Name: {

      internal::UsbDevice_SetConfiguration_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_SetConfiguration_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_value{};
      UsbDevice_SetConfiguration_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_value = input_data_view.value();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 2, false);
        return false;
      }
      UsbDevice::SetConfigurationCallback callback =
          UsbDevice_SetConfiguration_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetConfiguration(
std::move(p_value), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_ClaimInterface_Name: {

      internal::UsbDevice_ClaimInterface_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_ClaimInterface_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_interface_number{};
      UsbDevice_ClaimInterface_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_interface_number = input_data_view.interface_number();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 3, false);
        return false;
      }
      UsbDevice::ClaimInterfaceCallback callback =
          UsbDevice_ClaimInterface_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ClaimInterface(
std::move(p_interface_number), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_ReleaseInterface_Name: {

      internal::UsbDevice_ReleaseInterface_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_ReleaseInterface_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_interface_number{};
      UsbDevice_ReleaseInterface_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_interface_number = input_data_view.interface_number();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 4, false);
        return false;
      }
      UsbDevice::ReleaseInterfaceCallback callback =
          UsbDevice_ReleaseInterface_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ReleaseInterface(
std::move(p_interface_number), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_SetInterfaceAlternateSetting_Name: {

      internal::UsbDevice_SetInterfaceAlternateSetting_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_SetInterfaceAlternateSetting_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_interface_number{};
      uint8_t p_alternate_setting{};
      UsbDevice_SetInterfaceAlternateSetting_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_interface_number = input_data_view.interface_number();
      if (success)
        p_alternate_setting = input_data_view.alternate_setting();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 5, false);
        return false;
      }
      UsbDevice::SetInterfaceAlternateSettingCallback callback =
          UsbDevice_SetInterfaceAlternateSetting_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetInterfaceAlternateSetting(
std::move(p_interface_number), 
std::move(p_alternate_setting), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_Reset_Name: {

      internal::UsbDevice_Reset_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_Reset_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      UsbDevice_Reset_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 6, false);
        return false;
      }
      UsbDevice::ResetCallback callback =
          UsbDevice_Reset_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Reset(std::move(callback));
      return true;
    }
    case internal::kUsbDevice_ClearHalt_Name: {

      internal::UsbDevice_ClearHalt_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_ClearHalt_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      UsbTransferDirection p_direction{};
      uint8_t p_endpoint_number{};
      UsbDevice_ClearHalt_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadDirection(&p_direction))
        success = false;
      if (success)
        p_endpoint_number = input_data_view.endpoint_number();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 7, false);
        return false;
      }
      UsbDevice::ClearHaltCallback callback =
          UsbDevice_ClearHalt_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ClearHalt(
std::move(p_direction), 
std::move(p_endpoint_number), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_ControlTransferIn_Name: {

      internal::UsbDevice_ControlTransferIn_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_ControlTransferIn_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      UsbControlTransferParamsPtr p_params{};
      uint32_t p_length{};
      uint32_t p_timeout{};
      UsbDevice_ControlTransferIn_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadParams(&p_params))
        success = false;
      if (success)
        p_length = input_data_view.length();
      if (success)
        p_timeout = input_data_view.timeout();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 8, false);
        return false;
      }
      UsbDevice::ControlTransferInCallback callback =
          UsbDevice_ControlTransferIn_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ControlTransferIn(
std::move(p_params), 
std::move(p_length), 
std::move(p_timeout), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_ControlTransferOut_Name: {

      internal::UsbDevice_ControlTransferOut_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_ControlTransferOut_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      UsbControlTransferParamsPtr p_params{};
      ::base::span<const ::uint8_t> p_data{};
      uint32_t p_timeout{};
      UsbDevice_ControlTransferOut_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadParams(&p_params))
        success = false;
      if (success && !input_data_view.ReadData(&p_data))
        success = false;
      if (success)
        p_timeout = input_data_view.timeout();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 9, false);
        return false;
      }
      UsbDevice::ControlTransferOutCallback callback =
          UsbDevice_ControlTransferOut_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ControlTransferOut(
std::move(p_params), 
std::move(p_data), 
std::move(p_timeout), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_GenericTransferIn_Name: {

      internal::UsbDevice_GenericTransferIn_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_GenericTransferIn_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_endpoint_number{};
      uint32_t p_length{};
      uint32_t p_timeout{};
      UsbDevice_GenericTransferIn_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_endpoint_number = input_data_view.endpoint_number();
      if (success)
        p_length = input_data_view.length();
      if (success)
        p_timeout = input_data_view.timeout();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 10, false);
        return false;
      }
      UsbDevice::GenericTransferInCallback callback =
          UsbDevice_GenericTransferIn_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GenericTransferIn(
std::move(p_endpoint_number), 
std::move(p_length), 
std::move(p_timeout), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_GenericTransferOut_Name: {

      internal::UsbDevice_GenericTransferOut_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_GenericTransferOut_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_endpoint_number{};
      ::base::span<const ::uint8_t> p_data{};
      uint32_t p_timeout{};
      UsbDevice_GenericTransferOut_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_endpoint_number = input_data_view.endpoint_number();
      if (success && !input_data_view.ReadData(&p_data))
        success = false;
      if (success)
        p_timeout = input_data_view.timeout();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 11, false);
        return false;
      }
      UsbDevice::GenericTransferOutCallback callback =
          UsbDevice_GenericTransferOut_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GenericTransferOut(
std::move(p_endpoint_number), 
std::move(p_data), 
std::move(p_timeout), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_IsochronousTransferIn_Name: {

      internal::UsbDevice_IsochronousTransferIn_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_IsochronousTransferIn_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_endpoint_number{};
      std::vector<uint32_t> p_packet_lengths{};
      uint32_t p_timeout{};
      UsbDevice_IsochronousTransferIn_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_endpoint_number = input_data_view.endpoint_number();
      if (success && !input_data_view.ReadPacketLengths(&p_packet_lengths))
        success = false;
      if (success)
        p_timeout = input_data_view.timeout();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 12, false);
        return false;
      }
      UsbDevice::IsochronousTransferInCallback callback =
          UsbDevice_IsochronousTransferIn_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->IsochronousTransferIn(
std::move(p_endpoint_number), 
std::move(p_packet_lengths), 
std::move(p_timeout), std::move(callback));
      return true;
    }
    case internal::kUsbDevice_IsochronousTransferOut_Name: {

      internal::UsbDevice_IsochronousTransferOut_Params_Data* params =
          reinterpret_cast<
              internal::UsbDevice_IsochronousTransferOut_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint8_t p_endpoint_number{};
      ::base::span<const ::uint8_t> p_data{};
      std::vector<uint32_t> p_packet_lengths{};
      uint32_t p_timeout{};
      UsbDevice_IsochronousTransferOut_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_endpoint_number = input_data_view.endpoint_number();
      if (success && !input_data_view.ReadData(&p_data))
        success = false;
      if (success && !input_data_view.ReadPacketLengths(&p_packet_lengths))
        success = false;
      if (success)
        p_timeout = input_data_view.timeout();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDevice::Name_, 13, false);
        return false;
      }
      UsbDevice::IsochronousTransferOutCallback callback =
          UsbDevice_IsochronousTransferOut_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->IsochronousTransferOut(
std::move(p_endpoint_number), 
std::move(p_data), 
std::move(p_packet_lengths), 
std::move(p_timeout), std::move(callback));
      return true;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kUsbDeviceValidationInfo[] = {
    {&internal::UsbDevice_Open_Params_Data::Validate,
     &internal::UsbDevice_Open_ResponseParams_Data::Validate},
    {&internal::UsbDevice_Close_Params_Data::Validate,
     &internal::UsbDevice_Close_ResponseParams_Data::Validate},
    {&internal::UsbDevice_SetConfiguration_Params_Data::Validate,
     &internal::UsbDevice_SetConfiguration_ResponseParams_Data::Validate},
    {&internal::UsbDevice_ClaimInterface_Params_Data::Validate,
     &internal::UsbDevice_ClaimInterface_ResponseParams_Data::Validate},
    {&internal::UsbDevice_ReleaseInterface_Params_Data::Validate,
     &internal::UsbDevice_ReleaseInterface_ResponseParams_Data::Validate},
    {&internal::UsbDevice_SetInterfaceAlternateSetting_Params_Data::Validate,
     &internal::UsbDevice_SetInterfaceAlternateSetting_ResponseParams_Data::Validate},
    {&internal::UsbDevice_Reset_Params_Data::Validate,
     &internal::UsbDevice_Reset_ResponseParams_Data::Validate},
    {&internal::UsbDevice_ClearHalt_Params_Data::Validate,
     &internal::UsbDevice_ClearHalt_ResponseParams_Data::Validate},
    {&internal::UsbDevice_ControlTransferIn_Params_Data::Validate,
     &internal::UsbDevice_ControlTransferIn_ResponseParams_Data::Validate},
    {&internal::UsbDevice_ControlTransferOut_Params_Data::Validate,
     &internal::UsbDevice_ControlTransferOut_ResponseParams_Data::Validate},
    {&internal::UsbDevice_GenericTransferIn_Params_Data::Validate,
     &internal::UsbDevice_GenericTransferIn_ResponseParams_Data::Validate},
    {&internal::UsbDevice_GenericTransferOut_Params_Data::Validate,
     &internal::UsbDevice_GenericTransferOut_ResponseParams_Data::Validate},
    {&internal::UsbDevice_IsochronousTransferIn_Params_Data::Validate,
     &internal::UsbDevice_IsochronousTransferIn_ResponseParams_Data::Validate},
    {&internal::UsbDevice_IsochronousTransferOut_Params_Data::Validate,
     &internal::UsbDevice_IsochronousTransferOut_ResponseParams_Data::Validate},
};

bool UsbDeviceRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::UsbDevice::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kUsbDeviceValidationInfo);
}

bool UsbDeviceResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::UsbDevice::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kUsbDeviceValidationInfo);
}
const char UsbDeviceClient::Name_[] = "device.mojom.UsbDeviceClient";

std::pair<uint32_t, const void*> UsbDeviceClient::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kUsbDeviceClient_OnDeviceOpened_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDeviceClient::OnDeviceOpened");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDeviceClient::OnDeviceOpened_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kUsbDeviceClient_OnDeviceClosed_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::UsbDeviceClient::OnDeviceClosed");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&UsbDeviceClient::OnDeviceClosed_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* UsbDeviceClient::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kUsbDeviceClient_OnDeviceOpened_Name:
            return "Receive device::mojom::UsbDeviceClient::OnDeviceOpened";
      case internal::kUsbDeviceClient_OnDeviceClosed_Name:
            return "Receive device::mojom::UsbDeviceClient::OnDeviceClosed";
    }
  } else {
    switch (message.name()) {
      case internal::kUsbDeviceClient_OnDeviceOpened_Name:
            return "Receive reply device::mojom::UsbDeviceClient::OnDeviceOpened";
      case internal::kUsbDeviceClient_OnDeviceClosed_Name:
            return "Receive reply device::mojom::UsbDeviceClient::OnDeviceClosed";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
void UsbDeviceClient::OnDeviceOpened_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void UsbDeviceClient::OnDeviceClosed_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
# endif // !BUILDFLAG(IS_FUCHSIA)

UsbDeviceClientProxy::UsbDeviceClientProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void UsbDeviceClientProxy::OnDeviceOpened(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::UsbDeviceClient::OnDeviceOpened");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDeviceClient_OnDeviceOpened_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDeviceClient_OnDeviceOpened_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDeviceClient::Name_);
  message.set_method_name("OnDeviceOpened");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void UsbDeviceClientProxy::OnDeviceClosed(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::UsbDeviceClient::OnDeviceClosed");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kUsbDeviceClient_OnDeviceClosed_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::UsbDeviceClient_OnDeviceClosed_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(UsbDeviceClient::Name_);
  message.set_method_name("OnDeviceClosed");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

// static
bool UsbDeviceClientStubDispatch::Accept(
    UsbDeviceClient* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kUsbDeviceClient_OnDeviceOpened_Name: {

      DCHECK(message->is_serialized());
      internal::UsbDeviceClient_OnDeviceOpened_Params_Data* params =
          reinterpret_cast<internal::UsbDeviceClient_OnDeviceOpened_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      UsbDeviceClient_OnDeviceOpened_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDeviceClient::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnDeviceOpened();
      return true;
    }
    case internal::kUsbDeviceClient_OnDeviceClosed_Name: {

      DCHECK(message->is_serialized());
      internal::UsbDeviceClient_OnDeviceClosed_Params_Data* params =
          reinterpret_cast<internal::UsbDeviceClient_OnDeviceClosed_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      UsbDeviceClient_OnDeviceClosed_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            UsbDeviceClient::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnDeviceClosed();
      return true;
    }
  }
  return false;
}

// static
bool UsbDeviceClientStubDispatch::AcceptWithResponder(
    UsbDeviceClient* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (message->header()->name) {
    case internal::kUsbDeviceClient_OnDeviceOpened_Name: {
      break;
    }
    case internal::kUsbDeviceClient_OnDeviceClosed_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kUsbDeviceClientValidationInfo[] = {
    {&internal::UsbDeviceClient_OnDeviceOpened_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::UsbDeviceClient_OnDeviceClosed_Params_Data::Validate,
     nullptr /* no response */},
};

bool UsbDeviceClientRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::UsbDeviceClient::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kUsbDeviceClientValidationInfo);
}



}  // namespace mojom
}  // namespace device


namespace mojo {


// static
bool StructTraits<::device::mojom::UsbEndpointInfo::DataView, ::device::mojom::UsbEndpointInfoPtr>::Read(
    ::device::mojom::UsbEndpointInfo::DataView input,
    ::device::mojom::UsbEndpointInfoPtr* output) {
  bool success = true;
  ::device::mojom::UsbEndpointInfoPtr result(::device::mojom::UsbEndpointInfo::New());
  
      if (success)
        result->endpoint_number = input.endpoint_number();
      if (success && !input.ReadDirection(&result->direction))
        success = false;
      if (success && !input.ReadType(&result->type))
        success = false;
      if (success)
        result->packet_size = input.packet_size();
      if (success && !input.ReadSynchronizationType(&result->synchronization_type))
        success = false;
      if (success && !input.ReadUsageType(&result->usage_type))
        success = false;
      if (success)
        result->polling_interval = input.polling_interval();
      if (success && !input.ReadExtraData(&result->extra_data))
        success = false;
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::UsbAlternateInterfaceInfo::DataView, ::device::mojom::UsbAlternateInterfaceInfoPtr>::Read(
    ::device::mojom::UsbAlternateInterfaceInfo::DataView input,
    ::device::mojom::UsbAlternateInterfaceInfoPtr* output) {
  bool success = true;
  ::device::mojom::UsbAlternateInterfaceInfoPtr result(::device::mojom::UsbAlternateInterfaceInfo::New());
  
      if (success)
        result->alternate_setting = input.alternate_setting();
      if (success)
        result->class_code = input.class_code();
      if (success)
        result->subclass_code = input.subclass_code();
      if (success)
        result->protocol_code = input.protocol_code();
      if (success && !input.ReadInterfaceName(&result->interface_name))
        success = false;
      if (success && !input.ReadEndpoints(&result->endpoints))
        success = false;
      if (success && !input.ReadExtraData(&result->extra_data))
        success = false;
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::UsbInterfaceInfo::DataView, ::device::mojom::UsbInterfaceInfoPtr>::Read(
    ::device::mojom::UsbInterfaceInfo::DataView input,
    ::device::mojom::UsbInterfaceInfoPtr* output) {
  bool success = true;
  ::device::mojom::UsbInterfaceInfoPtr result(::device::mojom::UsbInterfaceInfo::New());
  
      if (success)
        result->interface_number = input.interface_number();
      if (success)
        result->first_interface = input.first_interface();
      if (success && !input.ReadAlternates(&result->alternates))
        success = false;
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::UsbConfigurationInfo::DataView, ::device::mojom::UsbConfigurationInfoPtr>::Read(
    ::device::mojom::UsbConfigurationInfo::DataView input,
    ::device::mojom::UsbConfigurationInfoPtr* output) {
  bool success = true;
  ::device::mojom::UsbConfigurationInfoPtr result(::device::mojom::UsbConfigurationInfo::New());
  
      if (success)
        result->configuration_value = input.configuration_value();
      if (success && !input.ReadConfigurationName(&result->configuration_name))
        success = false;
      if (success)
        result->self_powered = input.self_powered();
      if (success)
        result->remote_wakeup = input.remote_wakeup();
      if (success)
        result->maximum_power = input.maximum_power();
      if (success && !input.ReadInterfaces(&result->interfaces))
        success = false;
      if (success && !input.ReadExtraData(&result->extra_data))
        success = false;
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::UsbDeviceInfo::DataView, ::device::mojom::UsbDeviceInfoPtr>::Read(
    ::device::mojom::UsbDeviceInfo::DataView input,
    ::device::mojom::UsbDeviceInfoPtr* output) {
  bool success = true;
  ::device::mojom::UsbDeviceInfoPtr result(::device::mojom::UsbDeviceInfo::New());
  
      if (success && !input.ReadGuid(&result->guid))
        success = false;
      if (success)
        result->usb_version_major = input.usb_version_major();
      if (success)
        result->usb_version_minor = input.usb_version_minor();
      if (success)
        result->usb_version_subminor = input.usb_version_subminor();
      if (success)
        result->class_code = input.class_code();
      if (success)
        result->subclass_code = input.subclass_code();
      if (success)
        result->protocol_code = input.protocol_code();
      if (success)
        result->bus_number = input.bus_number();
      if (success)
        result->port_number = input.port_number();
      if (success)
        result->vendor_id = input.vendor_id();
      if (success)
        result->product_id = input.product_id();
      if (success)
        result->device_version_major = input.device_version_major();
      if (success)
        result->device_version_minor = input.device_version_minor();
      if (success)
        result->device_version_subminor = input.device_version_subminor();
      if (success && !input.ReadManufacturerName(&result->manufacturer_name))
        success = false;
      if (success && !input.ReadProductName(&result->product_name))
        success = false;
      if (success && !input.ReadSerialNumber(&result->serial_number))
        success = false;
      if (success && !input.ReadWebusbLandingPage(&result->webusb_landing_page))
        success = false;
      if (success)
        result->active_configuration = input.active_configuration();
      if (success && !input.ReadConfigurations(&result->configurations))
        success = false;
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::UsbControlTransferParams::DataView, ::device::mojom::UsbControlTransferParamsPtr>::Read(
    ::device::mojom::UsbControlTransferParams::DataView input,
    ::device::mojom::UsbControlTransferParamsPtr* output) {
  bool success = true;
  ::device::mojom::UsbControlTransferParamsPtr result(::device::mojom::UsbControlTransferParams::New());
  
      if (success && !input.ReadType(&result->type))
        success = false;
      if (success && !input.ReadRecipient(&result->recipient))
        success = false;
      if (success)
        result->request = input.request();
      if (success)
        result->value = input.value();
      if (success)
        result->index = input.index();
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::UsbIsochronousPacket::DataView, ::device::mojom::UsbIsochronousPacketPtr>::Read(
    ::device::mojom::UsbIsochronousPacket::DataView input,
    ::device::mojom::UsbIsochronousPacketPtr* output) {
  bool success = true;
  ::device::mojom::UsbIsochronousPacketPtr result(::device::mojom::UsbIsochronousPacket::New());
  
      if (success)
        result->length = input.length();
      if (success)
        result->transferred_length = input.transferred_length();
      if (success && !input.ReadStatus(&result->status))
        success = false;
  *output = std::move(result);
  return success;
}

}  // namespace mojo


// Symbols declared in the -test-utils.h header are defined here instead of a
// separate .cc file to save compile time.


namespace device {
namespace mojom {


void UsbDeviceInterceptorForTesting::Open(OpenCallback callback) {
  GetForwardingInterface()->Open(std::move(callback));
}
void UsbDeviceInterceptorForTesting::Close(CloseCallback callback) {
  GetForwardingInterface()->Close(std::move(callback));
}
void UsbDeviceInterceptorForTesting::SetConfiguration(uint8_t value, SetConfigurationCallback callback) {
  GetForwardingInterface()->SetConfiguration(std::move(value), std::move(callback));
}
void UsbDeviceInterceptorForTesting::ClaimInterface(uint8_t interface_number, ClaimInterfaceCallback callback) {
  GetForwardingInterface()->ClaimInterface(std::move(interface_number), std::move(callback));
}
void UsbDeviceInterceptorForTesting::ReleaseInterface(uint8_t interface_number, ReleaseInterfaceCallback callback) {
  GetForwardingInterface()->ReleaseInterface(std::move(interface_number), std::move(callback));
}
void UsbDeviceInterceptorForTesting::SetInterfaceAlternateSetting(uint8_t interface_number, uint8_t alternate_setting, SetInterfaceAlternateSettingCallback callback) {
  GetForwardingInterface()->SetInterfaceAlternateSetting(std::move(interface_number), std::move(alternate_setting), std::move(callback));
}
void UsbDeviceInterceptorForTesting::Reset(ResetCallback callback) {
  GetForwardingInterface()->Reset(std::move(callback));
}
void UsbDeviceInterceptorForTesting::ClearHalt(UsbTransferDirection direction, uint8_t endpoint_number, ClearHaltCallback callback) {
  GetForwardingInterface()->ClearHalt(std::move(direction), std::move(endpoint_number), std::move(callback));
}
void UsbDeviceInterceptorForTesting::ControlTransferIn(UsbControlTransferParamsPtr params, uint32_t length, uint32_t timeout, ControlTransferInCallback callback) {
  GetForwardingInterface()->ControlTransferIn(std::move(params), std::move(length), std::move(timeout), std::move(callback));
}
void UsbDeviceInterceptorForTesting::ControlTransferOut(UsbControlTransferParamsPtr params, ::base::span<const ::uint8_t> data, uint32_t timeout, ControlTransferOutCallback callback) {
  GetForwardingInterface()->ControlTransferOut(std::move(params), std::move(data), std::move(timeout), std::move(callback));
}
void UsbDeviceInterceptorForTesting::GenericTransferIn(uint8_t endpoint_number, uint32_t length, uint32_t timeout, GenericTransferInCallback callback) {
  GetForwardingInterface()->GenericTransferIn(std::move(endpoint_number), std::move(length), std::move(timeout), std::move(callback));
}
void UsbDeviceInterceptorForTesting::GenericTransferOut(uint8_t endpoint_number, ::base::span<const ::uint8_t> data, uint32_t timeout, GenericTransferOutCallback callback) {
  GetForwardingInterface()->GenericTransferOut(std::move(endpoint_number), std::move(data), std::move(timeout), std::move(callback));
}
void UsbDeviceInterceptorForTesting::IsochronousTransferIn(uint8_t endpoint_number, const std::vector<uint32_t>& packet_lengths, uint32_t timeout, IsochronousTransferInCallback callback) {
  GetForwardingInterface()->IsochronousTransferIn(std::move(endpoint_number), std::move(packet_lengths), std::move(timeout), std::move(callback));
}
void UsbDeviceInterceptorForTesting::IsochronousTransferOut(uint8_t endpoint_number, ::base::span<const ::uint8_t> data, const std::vector<uint32_t>& packet_lengths, uint32_t timeout, IsochronousTransferOutCallback callback) {
  GetForwardingInterface()->IsochronousTransferOut(std::move(endpoint_number), std::move(data), std::move(packet_lengths), std::move(timeout), std::move(callback));
}
UsbDeviceAsyncWaiter::UsbDeviceAsyncWaiter(
    UsbDevice* proxy) : proxy_(proxy) {}

UsbDeviceAsyncWaiter::~UsbDeviceAsyncWaiter() = default;

void UsbDeviceAsyncWaiter::Open(
    UsbOpenDeviceError* out_error) {
  base::RunLoop loop;
  proxy_->Open(
      base::BindOnce(
          [](base::RunLoop* loop,
             UsbOpenDeviceError* out_error
,
             UsbOpenDeviceError error) {*out_error = std::move(error);
            loop->Quit();
          },
          &loop,
          out_error));
  loop.Run();
}
void UsbDeviceAsyncWaiter::Close(
    ) {
  base::RunLoop loop;
  proxy_->Close(
      base::BindOnce(
          [](base::RunLoop* loop) {
            loop->Quit();
          },
          &loop));
  loop.Run();
}
void UsbDeviceAsyncWaiter::SetConfiguration(
    uint8_t value, bool* out_success) {
  base::RunLoop loop;
  proxy_->SetConfiguration(std::move(value),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void UsbDeviceAsyncWaiter::ClaimInterface(
    uint8_t interface_number, UsbClaimInterfaceResult* out_result) {
  base::RunLoop loop;
  proxy_->ClaimInterface(std::move(interface_number),
      base::BindOnce(
          [](base::RunLoop* loop,
             UsbClaimInterfaceResult* out_result
,
             UsbClaimInterfaceResult result) {*out_result = std::move(result);
            loop->Quit();
          },
          &loop,
          out_result));
  loop.Run();
}
void UsbDeviceAsyncWaiter::ReleaseInterface(
    uint8_t interface_number, bool* out_success) {
  base::RunLoop loop;
  proxy_->ReleaseInterface(std::move(interface_number),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void UsbDeviceAsyncWaiter::SetInterfaceAlternateSetting(
    uint8_t interface_number, uint8_t alternate_setting, bool* out_success) {
  base::RunLoop loop;
  proxy_->SetInterfaceAlternateSetting(std::move(interface_number),std::move(alternate_setting),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void UsbDeviceAsyncWaiter::Reset(
    bool* out_success) {
  base::RunLoop loop;
  proxy_->Reset(
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void UsbDeviceAsyncWaiter::ClearHalt(
    UsbTransferDirection direction, uint8_t endpoint_number, bool* out_success) {
  base::RunLoop loop;
  proxy_->ClearHalt(std::move(direction),std::move(endpoint_number),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void UsbDeviceAsyncWaiter::ControlTransferIn(
    UsbControlTransferParamsPtr params, uint32_t length, uint32_t timeout, UsbTransferStatus* out_status, ::base::span<const ::uint8_t>* out_data) {
  base::RunLoop loop;
  proxy_->ControlTransferIn(std::move(params),std::move(length),std::move(timeout),
      base::BindOnce(
          [](base::RunLoop* loop,
             UsbTransferStatus* out_status
,
             ::base::span<const ::uint8_t>* out_data
,
             UsbTransferStatus status,
             ::base::span<const ::uint8_t> data) {*out_status = std::move(status);*out_data = std::move(data);
            loop->Quit();
          },
          &loop,
          out_status,
          out_data));
  loop.Run();
}
void UsbDeviceAsyncWaiter::ControlTransferOut(
    UsbControlTransferParamsPtr params, ::base::span<const ::uint8_t> data, uint32_t timeout, UsbTransferStatus* out_status) {
  base::RunLoop loop;
  proxy_->ControlTransferOut(std::move(params),std::move(data),std::move(timeout),
      base::BindOnce(
          [](base::RunLoop* loop,
             UsbTransferStatus* out_status
,
             UsbTransferStatus status) {*out_status = std::move(status);
            loop->Quit();
          },
          &loop,
          out_status));
  loop.Run();
}
void UsbDeviceAsyncWaiter::GenericTransferIn(
    uint8_t endpoint_number, uint32_t length, uint32_t timeout, UsbTransferStatus* out_status, ::base::span<const ::uint8_t>* out_data) {
  base::RunLoop loop;
  proxy_->GenericTransferIn(std::move(endpoint_number),std::move(length),std::move(timeout),
      base::BindOnce(
          [](base::RunLoop* loop,
             UsbTransferStatus* out_status
,
             ::base::span<const ::uint8_t>* out_data
,
             UsbTransferStatus status,
             ::base::span<const ::uint8_t> data) {*out_status = std::move(status);*out_data = std::move(data);
            loop->Quit();
          },
          &loop,
          out_status,
          out_data));
  loop.Run();
}
void UsbDeviceAsyncWaiter::GenericTransferOut(
    uint8_t endpoint_number, ::base::span<const ::uint8_t> data, uint32_t timeout, UsbTransferStatus* out_status) {
  base::RunLoop loop;
  proxy_->GenericTransferOut(std::move(endpoint_number),std::move(data),std::move(timeout),
      base::BindOnce(
          [](base::RunLoop* loop,
             UsbTransferStatus* out_status
,
             UsbTransferStatus status) {*out_status = std::move(status);
            loop->Quit();
          },
          &loop,
          out_status));
  loop.Run();
}
void UsbDeviceAsyncWaiter::IsochronousTransferIn(
    uint8_t endpoint_number, const std::vector<uint32_t>& packet_lengths, uint32_t timeout, ::base::span<const ::uint8_t>* out_data, std::vector<UsbIsochronousPacketPtr>* out_packets) {
  base::RunLoop loop;
  proxy_->IsochronousTransferIn(std::move(endpoint_number),std::move(packet_lengths),std::move(timeout),
      base::BindOnce(
          [](base::RunLoop* loop,
             ::base::span<const ::uint8_t>* out_data
,
             std::vector<UsbIsochronousPacketPtr>* out_packets
,
             ::base::span<const ::uint8_t> data,
             std::vector<UsbIsochronousPacketPtr> packets) {*out_data = std::move(data);*out_packets = std::move(packets);
            loop->Quit();
          },
          &loop,
          out_data,
          out_packets));
  loop.Run();
}
void UsbDeviceAsyncWaiter::IsochronousTransferOut(
    uint8_t endpoint_number, ::base::span<const ::uint8_t> data, const std::vector<uint32_t>& packet_lengths, uint32_t timeout, std::vector<UsbIsochronousPacketPtr>* out_packets) {
  base::RunLoop loop;
  proxy_->IsochronousTransferOut(std::move(endpoint_number),std::move(data),std::move(packet_lengths),std::move(timeout),
      base::BindOnce(
          [](base::RunLoop* loop,
             std::vector<UsbIsochronousPacketPtr>* out_packets
,
             std::vector<UsbIsochronousPacketPtr> packets) {*out_packets = std::move(packets);
            loop->Quit();
          },
          &loop,
          out_packets));
  loop.Run();
}



void UsbDeviceClientInterceptorForTesting::OnDeviceOpened() {
  GetForwardingInterface()->OnDeviceOpened();
}
void UsbDeviceClientInterceptorForTesting::OnDeviceClosed() {
  GetForwardingInterface()->OnDeviceClosed();
}
UsbDeviceClientAsyncWaiter::UsbDeviceClientAsyncWaiter(
    UsbDeviceClient* proxy) : proxy_(proxy) {}

UsbDeviceClientAsyncWaiter::~UsbDeviceClientAsyncWaiter() = default;






}  // namespace mojom
}  // namespace device


#if defined(__clang__)
#pragma clang diagnostic pop
#endif