// services/video_capture/public/mojom/device.mojom-blink.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/video_capture/public/mojom/device.mojom-blink.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/video_capture/public/mojom/device.mojom-params-data.h"
#include "services/video_capture/public/mojom/device.mojom-shared-message-ids.h"

#include "services/video_capture/public/mojom/device.mojom-blink-import-headers.h"
#include "services/video_capture/public/mojom/device.mojom-blink-test-utils.h"
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"


#ifndef SERVICES_VIDEO_CAPTURE_PUBLIC_MOJOM_DEVICE_MOJOM_BLINK_JUMBO_H_
#define SERVICES_VIDEO_CAPTURE_PUBLIC_MOJOM_DEVICE_MOJOM_BLINK_JUMBO_H_
#endif



namespace video_capture {
namespace mojom {
namespace blink {
const char Device::Name_[] = "video_capture.mojom.Device";

std::pair<uint32_t, const void*> Device::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kDevice_Start_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::Start");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::Start_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_MaybeSuspend_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::MaybeSuspend");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::MaybeSuspend_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_Resume_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::Resume");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::Resume_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_GetPhotoState_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::GetPhotoState");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::GetPhotoState_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_SetPhotoOptions_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::SetPhotoOptions");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::SetPhotoOptions_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_TakePhoto_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::TakePhoto");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::TakePhoto_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_ProcessFeedback_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::ProcessFeedback");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::ProcessFeedback_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kDevice_RequestRefreshFrame_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::Device::RequestRefreshFrame");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Device::RequestRefreshFrame_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* Device::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::kDevice_Start_Name:
            return "Receive video_capture::mojom::Device::Start";
      case internal::kDevice_MaybeSuspend_Name:
            return "Receive video_capture::mojom::Device::MaybeSuspend";
      case internal::kDevice_Resume_Name:
            return "Receive video_capture::mojom::Device::Resume";
      case internal::kDevice_GetPhotoState_Name:
            return "Receive video_capture::mojom::Device::GetPhotoState";
      case internal::kDevice_SetPhotoOptions_Name:
            return "Receive video_capture::mojom::Device::SetPhotoOptions";
      case internal::kDevice_TakePhoto_Name:
            return "Receive video_capture::mojom::Device::TakePhoto";
      case internal::kDevice_ProcessFeedback_Name:
            return "Receive video_capture::mojom::Device::ProcessFeedback";
      case internal::kDevice_RequestRefreshFrame_Name:
            return "Receive video_capture::mojom::Device::RequestRefreshFrame";
    }
  } else {
    switch (message.name()) {
      case internal::kDevice_Start_Name:
            return "Receive reply video_capture::mojom::Device::Start";
      case internal::kDevice_MaybeSuspend_Name:
            return "Receive reply video_capture::mojom::Device::MaybeSuspend";
      case internal::kDevice_Resume_Name:
            return "Receive reply video_capture::mojom::Device::Resume";
      case internal::kDevice_GetPhotoState_Name:
            return "Receive reply video_capture::mojom::Device::GetPhotoState";
      case internal::kDevice_SetPhotoOptions_Name:
            return "Receive reply video_capture::mojom::Device::SetPhotoOptions";
      case internal::kDevice_TakePhoto_Name:
            return "Receive reply video_capture::mojom::Device::TakePhoto";
      case internal::kDevice_ProcessFeedback_Name:
            return "Receive reply video_capture::mojom::Device::ProcessFeedback";
      case internal::kDevice_RequestRefreshFrame_Name:
            return "Receive reply video_capture::mojom::Device::RequestRefreshFrame";
    }
  }
  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 Device::Start_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 Device::MaybeSuspend_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 Device::Resume_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 Device::GetPhotoState_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 Device::SetPhotoOptions_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 Device::TakePhoto_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 Device::ProcessFeedback_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 Device::RequestRefreshFrame_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 Device_GetPhotoState_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  Device_GetPhotoState_ForwardToCallback(
      Device::GetPhotoStateCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  Device::GetPhotoStateCallback callback_;
};

class Device_SetPhotoOptions_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  Device_SetPhotoOptions_ForwardToCallback(
      Device::SetPhotoOptionsCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  Device::SetPhotoOptionsCallback callback_;
};

class Device_TakePhoto_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  Device_TakePhoto_ForwardToCallback(
      Device::TakePhotoCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  Device::TakePhotoCallback callback_;
};

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

void DeviceProxy::Start(
    const ::media::VideoCaptureParams& in_requested_settings, ::mojo::PendingRemote<::video_capture::mojom::blink::VideoFrameHandler> in_handler) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::Device::Start", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("requested_settings"), in_requested_settings,
                        "<value of type const ::media::VideoCaptureParams&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("handler"), in_handler,
                        "<value of type ::mojo::PendingRemote<::video_capture::mojom::blink::VideoFrameHandler>>");
   });
#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::kDevice_Start_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_Start_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->requested_settings)::BaseType> requested_settings_fragment(
          params.message());
  mojo::internal::Serialize<::media::mojom::VideoCaptureParamsDataView>(
      in_requested_settings, requested_settings_fragment);
  params->requested_settings.Set(
      requested_settings_fragment.is_null() ? nullptr : requested_settings_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->requested_settings.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null requested_settings in Device.Start request");
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::video_capture::mojom::VideoFrameHandlerInterfaceBase>>(
      in_handler, &params->handler, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->handler),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid handler in Device.Start request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("Start");
#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 DeviceProxy::MaybeSuspend(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::Device::MaybeSuspend");
#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::kDevice_MaybeSuspend_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_MaybeSuspend_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("MaybeSuspend");
#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 DeviceProxy::Resume(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::Device::Resume");
#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::kDevice_Resume_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_Resume_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("Resume");
#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 DeviceProxy::GetPhotoState(
    GetPhotoStateCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::Device::GetPhotoState");
#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::kDevice_GetPhotoState_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_GetPhotoState_Params_Data> params(
          message);
  params.Allocate();

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

void DeviceProxy::SetPhotoOptions(
    ::media::mojom::blink::PhotoSettingsPtr in_settings, SetPhotoOptionsCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::Device::SetPhotoOptions", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("settings"), in_settings,
                        "<value of type ::media::mojom::blink::PhotoSettingsPtr>");
   });
#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::kDevice_SetPhotoOptions_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_SetPhotoOptions_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->settings)::BaseType> settings_fragment(
          params.message());
  mojo::internal::Serialize<::media::mojom::PhotoSettingsDataView>(
      in_settings, settings_fragment);
  params->settings.Set(
      settings_fragment.is_null() ? nullptr : settings_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->settings.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null settings in Device.SetPhotoOptions request");

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

void DeviceProxy::TakePhoto(
    TakePhotoCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::Device::TakePhoto");
#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::kDevice_TakePhoto_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_TakePhoto_Params_Data> params(
          message);
  params.Allocate();

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

void DeviceProxy::ProcessFeedback(
    const ::media::VideoCaptureFeedback& in_feedback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::Device::ProcessFeedback", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("feedback"), in_feedback,
                        "<value of type const ::media::VideoCaptureFeedback&>");
   });
#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::kDevice_ProcessFeedback_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_ProcessFeedback_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->feedback)::BaseType> feedback_fragment(
          params.message());
  mojo::internal::Serialize<::media::mojom::VideoCaptureFeedbackDataView>(
      in_feedback, feedback_fragment);
  params->feedback.Set(
      feedback_fragment.is_null() ? nullptr : feedback_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->feedback.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null feedback in Device.ProcessFeedback request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("ProcessFeedback");
#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 DeviceProxy::RequestRefreshFrame(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::Device::RequestRefreshFrame");
#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::kDevice_RequestRefreshFrame_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_RequestRefreshFrame_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("RequestRefreshFrame");
#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);
}
class Device_GetPhotoState_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static Device::GetPhotoStateCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<Device_GetPhotoState_ProxyToResponder> proxy(
        new Device_GetPhotoState_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&Device_GetPhotoState_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~Device_GetPhotoState_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:
  Device_GetPhotoState_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)
        << "Device::GetPhotoStateCallback 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(
      ::media::mojom::blink::PhotoStatePtr in_capabilities);
};

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

  DCHECK(message->is_serialized());
  internal::Device_GetPhotoState_ResponseParams_Data* params =
      reinterpret_cast<
          internal::Device_GetPhotoState_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  ::media::mojom::blink::PhotoStatePtr p_capabilities{};
  Device_GetPhotoState_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadCapabilities(&p_capabilities))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        Device::Name_, 3, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_capabilities));
  return true;
}

void Device_GetPhotoState_ProxyToResponder::Run(
    ::media::mojom::blink::PhotoStatePtr in_capabilities) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply video_capture::mojom::Device::GetPhotoState", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("capabilities"), in_capabilities,
                        "<value of type ::media::mojom::blink::PhotoStatePtr>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kDevice_GetPhotoState_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_GetPhotoState_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->capabilities)::BaseType> capabilities_fragment(
          params.message());
  mojo::internal::Serialize<::media::mojom::PhotoStateDataView>(
      in_capabilities, capabilities_fragment);
  params->capabilities.Set(
      capabilities_fragment.is_null() ? nullptr : capabilities_fragment.data());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("GetPhotoState");
#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 Device_SetPhotoOptions_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static Device::SetPhotoOptionsCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<Device_SetPhotoOptions_ProxyToResponder> proxy(
        new Device_SetPhotoOptions_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&Device_SetPhotoOptions_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~Device_SetPhotoOptions_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:
  Device_SetPhotoOptions_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)
        << "Device::SetPhotoOptionsCallback 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 Device_SetPhotoOptions_ForwardToCallback::Accept(
    mojo::Message* message) {

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

void Device_SetPhotoOptions_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply video_capture::mojom::Device::SetPhotoOptions", "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::kDevice_SetPhotoOptions_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_SetPhotoOptions_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("SetPhotoOptions");
#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 Device_TakePhoto_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static Device::TakePhotoCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<Device_TakePhoto_ProxyToResponder> proxy(
        new Device_TakePhoto_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&Device_TakePhoto_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~Device_TakePhoto_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:
  Device_TakePhoto_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)
        << "Device::TakePhotoCallback 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(
      ::media::mojom::blink::BlobPtr in_blob);
};

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

  DCHECK(message->is_serialized());
  internal::Device_TakePhoto_ResponseParams_Data* params =
      reinterpret_cast<
          internal::Device_TakePhoto_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  ::media::mojom::blink::BlobPtr p_blob{};
  Device_TakePhoto_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadBlob(&p_blob))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        Device::Name_, 5, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_blob));
  return true;
}

void Device_TakePhoto_ProxyToResponder::Run(
    ::media::mojom::blink::BlobPtr in_blob) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply video_capture::mojom::Device::TakePhoto", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("blob"), in_blob,
                        "<value of type ::media::mojom::blink::BlobPtr>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kDevice_TakePhoto_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::Device_TakePhoto_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->blob)::BaseType> blob_fragment(
          params.message());
  mojo::internal::Serialize<::media::mojom::BlobDataView>(
      in_blob, blob_fragment);
  params->blob.Set(
      blob_fragment.is_null() ? nullptr : blob_fragment.data());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Device::Name_);
  message.set_method_name("TakePhoto");
#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 DeviceStubDispatch::Accept(
    Device* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kDevice_Start_Name: {

      DCHECK(message->is_serialized());
      internal::Device_Start_Params_Data* params =
          reinterpret_cast<internal::Device_Start_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::media::VideoCaptureParams p_requested_settings{};
      ::mojo::PendingRemote<::video_capture::mojom::blink::VideoFrameHandler> p_handler{};
      Device_Start_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadRequestedSettings(&p_requested_settings))
        success = false;
      if (success) {
        p_handler =
            input_data_view.TakeHandler<decltype(p_handler)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Device::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Start(
std::move(p_requested_settings), 
std::move(p_handler));
      return true;
    }
    case internal::kDevice_MaybeSuspend_Name: {

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

      DCHECK(message->is_serialized());
      internal::Device_Resume_Params_Data* params =
          reinterpret_cast<internal::Device_Resume_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      Device_Resume_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Device::Name_, 2, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Resume();
      return true;
    }
    case internal::kDevice_GetPhotoState_Name: {
      break;
    }
    case internal::kDevice_SetPhotoOptions_Name: {
      break;
    }
    case internal::kDevice_TakePhoto_Name: {
      break;
    }
    case internal::kDevice_ProcessFeedback_Name: {

      DCHECK(message->is_serialized());
      internal::Device_ProcessFeedback_Params_Data* params =
          reinterpret_cast<internal::Device_ProcessFeedback_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::media::VideoCaptureFeedback p_feedback{};
      Device_ProcessFeedback_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadFeedback(&p_feedback))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Device::Name_, 6, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ProcessFeedback(
std::move(p_feedback));
      return true;
    }
    case internal::kDevice_RequestRefreshFrame_Name: {

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

// static
bool DeviceStubDispatch::AcceptWithResponder(
    Device* 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::kDevice_Start_Name: {
      break;
    }
    case internal::kDevice_MaybeSuspend_Name: {
      break;
    }
    case internal::kDevice_Resume_Name: {
      break;
    }
    case internal::kDevice_GetPhotoState_Name: {

      internal::Device_GetPhotoState_Params_Data* params =
          reinterpret_cast<
              internal::Device_GetPhotoState_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      Device_GetPhotoState_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Device::Name_, 3, false);
        return false;
      }
      Device::GetPhotoStateCallback callback =
          Device_GetPhotoState_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetPhotoState(std::move(callback));
      return true;
    }
    case internal::kDevice_SetPhotoOptions_Name: {

      internal::Device_SetPhotoOptions_Params_Data* params =
          reinterpret_cast<
              internal::Device_SetPhotoOptions_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::media::mojom::blink::PhotoSettingsPtr p_settings{};
      Device_SetPhotoOptions_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSettings(&p_settings))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Device::Name_, 4, false);
        return false;
      }
      Device::SetPhotoOptionsCallback callback =
          Device_SetPhotoOptions_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetPhotoOptions(
std::move(p_settings), std::move(callback));
      return true;
    }
    case internal::kDevice_TakePhoto_Name: {

      internal::Device_TakePhoto_Params_Data* params =
          reinterpret_cast<
              internal::Device_TakePhoto_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      Device_TakePhoto_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Device::Name_, 5, false);
        return false;
      }
      Device::TakePhotoCallback callback =
          Device_TakePhoto_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->TakePhoto(std::move(callback));
      return true;
    }
    case internal::kDevice_ProcessFeedback_Name: {
      break;
    }
    case internal::kDevice_RequestRefreshFrame_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kDeviceValidationInfo[] = {
    {&internal::Device_Start_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::Device_MaybeSuspend_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::Device_Resume_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::Device_GetPhotoState_Params_Data::Validate,
     &internal::Device_GetPhotoState_ResponseParams_Data::Validate},
    {&internal::Device_SetPhotoOptions_Params_Data::Validate,
     &internal::Device_SetPhotoOptions_ResponseParams_Data::Validate},
    {&internal::Device_TakePhoto_Params_Data::Validate,
     &internal::Device_TakePhoto_ResponseParams_Data::Validate},
    {&internal::Device_ProcessFeedback_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::Device_RequestRefreshFrame_Params_Data::Validate,
     nullptr /* no response */},
};

bool DeviceRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::video_capture::mojom::blink::Device::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kDeviceValidationInfo);
}

bool DeviceResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::video_capture::mojom::blink::Device::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kDeviceValidationInfo);
}


}  // namespace blink
}  // namespace mojom
}  // namespace video_capture


namespace mojo {

}  // namespace mojo


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


namespace video_capture {
namespace mojom {
namespace blink {


void DeviceInterceptorForTesting::Start(const ::media::VideoCaptureParams& requested_settings, ::mojo::PendingRemote<::video_capture::mojom::blink::VideoFrameHandler> handler) {
  GetForwardingInterface()->Start(std::move(requested_settings), std::move(handler));
}
void DeviceInterceptorForTesting::MaybeSuspend() {
  GetForwardingInterface()->MaybeSuspend();
}
void DeviceInterceptorForTesting::Resume() {
  GetForwardingInterface()->Resume();
}
void DeviceInterceptorForTesting::GetPhotoState(GetPhotoStateCallback callback) {
  GetForwardingInterface()->GetPhotoState(std::move(callback));
}
void DeviceInterceptorForTesting::SetPhotoOptions(::media::mojom::blink::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) {
  GetForwardingInterface()->SetPhotoOptions(std::move(settings), std::move(callback));
}
void DeviceInterceptorForTesting::TakePhoto(TakePhotoCallback callback) {
  GetForwardingInterface()->TakePhoto(std::move(callback));
}
void DeviceInterceptorForTesting::ProcessFeedback(const ::media::VideoCaptureFeedback& feedback) {
  GetForwardingInterface()->ProcessFeedback(std::move(feedback));
}
void DeviceInterceptorForTesting::RequestRefreshFrame() {
  GetForwardingInterface()->RequestRefreshFrame();
}
DeviceAsyncWaiter::DeviceAsyncWaiter(
    Device* proxy) : proxy_(proxy) {}

DeviceAsyncWaiter::~DeviceAsyncWaiter() = default;

void DeviceAsyncWaiter::GetPhotoState(
    ::media::mojom::blink::PhotoStatePtr* out_capabilities) {
  base::RunLoop loop;
  proxy_->GetPhotoState(
      base::BindOnce(
          [](base::RunLoop* loop,
             ::media::mojom::blink::PhotoStatePtr* out_capabilities
,
             ::media::mojom::blink::PhotoStatePtr capabilities) {*out_capabilities = std::move(capabilities);
            loop->Quit();
          },
          &loop,
          out_capabilities));
  loop.Run();
}
void DeviceAsyncWaiter::SetPhotoOptions(
    ::media::mojom::blink::PhotoSettingsPtr settings, bool* out_success) {
  base::RunLoop loop;
  proxy_->SetPhotoOptions(std::move(settings),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void DeviceAsyncWaiter::TakePhoto(
    ::media::mojom::blink::BlobPtr* out_blob) {
  base::RunLoop loop;
  proxy_->TakePhoto(
      base::BindOnce(
          [](base::RunLoop* loop,
             ::media::mojom::blink::BlobPtr* out_blob
,
             ::media::mojom::blink::BlobPtr blob) {*out_blob = std::move(blob);
            loop->Quit();
          },
          &loop,
          out_blob));
  loop.Run();
}





}  // namespace blink
}  // namespace mojom
}  // namespace video_capture


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