// media/mojo/mojom/media_player.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 "media/mojo/mojom/media_player.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 "media/mojo/mojom/media_player.mojom-params-data.h"
#include "media/mojo/mojom/media_player.mojom-shared-message-ids.h"

#include "media/mojo/mojom/media_player.mojom-blink-import-headers.h"
#include "media/mojo/mojom/media_player.mojom-blink-test-utils.h"
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"


#ifndef MEDIA_MOJO_MOJOM_MEDIA_PLAYER_MOJOM_BLINK_JUMBO_H_
#define MEDIA_MOJO_MOJOM_MEDIA_PLAYER_MOJOM_BLINK_JUMBO_H_
#endif



namespace media {
namespace mojom {
namespace blink {
const char MediaPlayer::Name_[] = "media.mojom.MediaPlayer";

std::pair<uint32_t, const void*> MediaPlayer::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kMediaPlayer_RequestPlay_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestPlay");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestPlay_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestPause_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestPause");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestPause_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestSeekForward_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestSeekForward");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestSeekForward_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestSeekBackward_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestSeekBackward");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestSeekBackward_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestSeekTo_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestSeekTo");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestSeekTo_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestEnterPictureInPicture_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestEnterPictureInPicture");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestEnterPictureInPicture_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestExitPictureInPicture_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestExitPictureInPicture");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestExitPictureInPicture_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_RequestMute_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::RequestMute");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::RequestMute_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_SetVolumeMultiplier_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::SetVolumeMultiplier");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::SetVolumeMultiplier_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_SetPersistentState_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::SetPersistentState");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::SetPersistentState_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_SetPowerExperimentState_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::SetPowerExperimentState");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::SetPowerExperimentState_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_SetAudioSinkId_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::SetAudioSinkId");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::SetAudioSinkId_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayer_SuspendForFrameClosed_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayer::SuspendForFrameClosed");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayer::SuspendForFrameClosed_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* MediaPlayer::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::kMediaPlayer_RequestPlay_Name:
            return "Receive media::mojom::MediaPlayer::RequestPlay";
      case internal::kMediaPlayer_RequestPause_Name:
            return "Receive media::mojom::MediaPlayer::RequestPause";
      case internal::kMediaPlayer_RequestSeekForward_Name:
            return "Receive media::mojom::MediaPlayer::RequestSeekForward";
      case internal::kMediaPlayer_RequestSeekBackward_Name:
            return "Receive media::mojom::MediaPlayer::RequestSeekBackward";
      case internal::kMediaPlayer_RequestSeekTo_Name:
            return "Receive media::mojom::MediaPlayer::RequestSeekTo";
      case internal::kMediaPlayer_RequestEnterPictureInPicture_Name:
            return "Receive media::mojom::MediaPlayer::RequestEnterPictureInPicture";
      case internal::kMediaPlayer_RequestExitPictureInPicture_Name:
            return "Receive media::mojom::MediaPlayer::RequestExitPictureInPicture";
      case internal::kMediaPlayer_RequestMute_Name:
            return "Receive media::mojom::MediaPlayer::RequestMute";
      case internal::kMediaPlayer_SetVolumeMultiplier_Name:
            return "Receive media::mojom::MediaPlayer::SetVolumeMultiplier";
      case internal::kMediaPlayer_SetPersistentState_Name:
            return "Receive media::mojom::MediaPlayer::SetPersistentState";
      case internal::kMediaPlayer_SetPowerExperimentState_Name:
            return "Receive media::mojom::MediaPlayer::SetPowerExperimentState";
      case internal::kMediaPlayer_SetAudioSinkId_Name:
            return "Receive media::mojom::MediaPlayer::SetAudioSinkId";
      case internal::kMediaPlayer_SuspendForFrameClosed_Name:
            return "Receive media::mojom::MediaPlayer::SuspendForFrameClosed";
    }
  } else {
    switch (message.name()) {
      case internal::kMediaPlayer_RequestPlay_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestPlay";
      case internal::kMediaPlayer_RequestPause_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestPause";
      case internal::kMediaPlayer_RequestSeekForward_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestSeekForward";
      case internal::kMediaPlayer_RequestSeekBackward_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestSeekBackward";
      case internal::kMediaPlayer_RequestSeekTo_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestSeekTo";
      case internal::kMediaPlayer_RequestEnterPictureInPicture_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestEnterPictureInPicture";
      case internal::kMediaPlayer_RequestExitPictureInPicture_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestExitPictureInPicture";
      case internal::kMediaPlayer_RequestMute_Name:
            return "Receive reply media::mojom::MediaPlayer::RequestMute";
      case internal::kMediaPlayer_SetVolumeMultiplier_Name:
            return "Receive reply media::mojom::MediaPlayer::SetVolumeMultiplier";
      case internal::kMediaPlayer_SetPersistentState_Name:
            return "Receive reply media::mojom::MediaPlayer::SetPersistentState";
      case internal::kMediaPlayer_SetPowerExperimentState_Name:
            return "Receive reply media::mojom::MediaPlayer::SetPowerExperimentState";
      case internal::kMediaPlayer_SetAudioSinkId_Name:
            return "Receive reply media::mojom::MediaPlayer::SetAudioSinkId";
      case internal::kMediaPlayer_SuspendForFrameClosed_Name:
            return "Receive reply media::mojom::MediaPlayer::SuspendForFrameClosed";
    }
  }
  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 MediaPlayer::RequestPlay_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 MediaPlayer::RequestPause_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 MediaPlayer::RequestSeekForward_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 MediaPlayer::RequestSeekBackward_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 MediaPlayer::RequestSeekTo_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 MediaPlayer::RequestEnterPictureInPicture_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 MediaPlayer::RequestExitPictureInPicture_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 MediaPlayer::RequestMute_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 MediaPlayer::SetVolumeMultiplier_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 MediaPlayer::SetPersistentState_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 MediaPlayer::SetPowerExperimentState_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 MediaPlayer::SetAudioSinkId_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 MediaPlayer::SuspendForFrameClosed_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)

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

void MediaPlayerProxy::RequestPlay(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayer::RequestPlay");
#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::kMediaPlayer_RequestPlay_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestPlay_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestPlay");
#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 MediaPlayerProxy::RequestPause(
    bool in_triggered_by_user) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::RequestPause", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("triggered_by_user"), in_triggered_by_user,
                        "<value of type bool>");
   });
#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::kMediaPlayer_RequestPause_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestPause_Params_Data> params(
          message);
  params.Allocate();
  params->triggered_by_user = in_triggered_by_user;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestPause");
#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 MediaPlayerProxy::RequestSeekForward(
    ::base::TimeDelta in_seek_time) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::RequestSeekForward", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("seek_time"), in_seek_time,
                        "<value of type ::base::TimeDelta>");
   });
#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::kMediaPlayer_RequestSeekForward_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestSeekForward_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->seek_time)::BaseType> seek_time_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::TimeDeltaDataView>(
      in_seek_time, seek_time_fragment);
  params->seek_time.Set(
      seek_time_fragment.is_null() ? nullptr : seek_time_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->seek_time.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null seek_time in MediaPlayer.RequestSeekForward request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestSeekForward");
#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 MediaPlayerProxy::RequestSeekBackward(
    ::base::TimeDelta in_seek_time) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::RequestSeekBackward", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("seek_time"), in_seek_time,
                        "<value of type ::base::TimeDelta>");
   });
#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::kMediaPlayer_RequestSeekBackward_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestSeekBackward_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->seek_time)::BaseType> seek_time_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::TimeDeltaDataView>(
      in_seek_time, seek_time_fragment);
  params->seek_time.Set(
      seek_time_fragment.is_null() ? nullptr : seek_time_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->seek_time.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null seek_time in MediaPlayer.RequestSeekBackward request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestSeekBackward");
#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 MediaPlayerProxy::RequestSeekTo(
    ::base::TimeDelta in_seek_time) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::RequestSeekTo", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("seek_time"), in_seek_time,
                        "<value of type ::base::TimeDelta>");
   });
#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::kMediaPlayer_RequestSeekTo_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestSeekTo_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->seek_time)::BaseType> seek_time_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::TimeDeltaDataView>(
      in_seek_time, seek_time_fragment);
  params->seek_time.Set(
      seek_time_fragment.is_null() ? nullptr : seek_time_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->seek_time.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null seek_time in MediaPlayer.RequestSeekTo request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestSeekTo");
#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 MediaPlayerProxy::RequestEnterPictureInPicture(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayer::RequestEnterPictureInPicture");
#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::kMediaPlayer_RequestEnterPictureInPicture_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestEnterPictureInPicture_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestEnterPictureInPicture");
#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 MediaPlayerProxy::RequestExitPictureInPicture(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayer::RequestExitPictureInPicture");
#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::kMediaPlayer_RequestExitPictureInPicture_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestExitPictureInPicture_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestExitPictureInPicture");
#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 MediaPlayerProxy::RequestMute(
    bool in_mute) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::RequestMute", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("mute"), in_mute,
                        "<value of type bool>");
   });
#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::kMediaPlayer_RequestMute_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_RequestMute_Params_Data> params(
          message);
  params.Allocate();
  params->mute = in_mute;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("RequestMute");
#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 MediaPlayerProxy::SetVolumeMultiplier(
    double in_multiplier) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::SetVolumeMultiplier", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("multiplier"), in_multiplier,
                        "<value of type double>");
   });
#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::kMediaPlayer_SetVolumeMultiplier_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_SetVolumeMultiplier_Params_Data> params(
          message);
  params.Allocate();
  params->multiplier = in_multiplier;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("SetVolumeMultiplier");
#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 MediaPlayerProxy::SetPersistentState(
    bool in_persistent) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::SetPersistentState", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("persistent"), in_persistent,
                        "<value of type bool>");
   });
#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::kMediaPlayer_SetPersistentState_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_SetPersistentState_Params_Data> params(
          message);
  params.Allocate();
  params->persistent = in_persistent;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("SetPersistentState");
#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 MediaPlayerProxy::SetPowerExperimentState(
    bool in_enabled) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::SetPowerExperimentState", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("enabled"), in_enabled,
                        "<value of type bool>");
   });
#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::kMediaPlayer_SetPowerExperimentState_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_SetPowerExperimentState_Params_Data> params(
          message);
  params.Allocate();
  params->enabled = in_enabled;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("SetPowerExperimentState");
#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 MediaPlayerProxy::SetAudioSinkId(
    const WTF::String& in_sink_id) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayer::SetAudioSinkId", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("sink_id"), in_sink_id,
                        "<value of type const WTF::String&>");
   });
#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::kMediaPlayer_SetAudioSinkId_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_SetAudioSinkId_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->sink_id)::BaseType> sink_id_fragment(
          params.message());
  mojo::internal::Serialize<mojo::StringDataView>(
      in_sink_id, sink_id_fragment);
  params->sink_id.Set(
      sink_id_fragment.is_null() ? nullptr : sink_id_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->sink_id.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null sink_id in MediaPlayer.SetAudioSinkId request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayer::Name_);
  message.set_method_name("SetAudioSinkId");
#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 MediaPlayerProxy::SuspendForFrameClosed(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayer::SuspendForFrameClosed");
#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::kMediaPlayer_SuspendForFrameClosed_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayer_SuspendForFrameClosed_Params_Data> params(
          message);
  params.Allocate();

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

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

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestPause_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestPause_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_triggered_by_user{};
      MediaPlayer_RequestPause_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_triggered_by_user = input_data_view.triggered_by_user();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestPause(
std::move(p_triggered_by_user));
      return true;
    }
    case internal::kMediaPlayer_RequestSeekForward_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestSeekForward_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestSeekForward_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::base::TimeDelta p_seek_time{};
      MediaPlayer_RequestSeekForward_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSeekTime(&p_seek_time))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 2, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestSeekForward(
std::move(p_seek_time));
      return true;
    }
    case internal::kMediaPlayer_RequestSeekBackward_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestSeekBackward_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestSeekBackward_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::base::TimeDelta p_seek_time{};
      MediaPlayer_RequestSeekBackward_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSeekTime(&p_seek_time))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 3, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestSeekBackward(
std::move(p_seek_time));
      return true;
    }
    case internal::kMediaPlayer_RequestSeekTo_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestSeekTo_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestSeekTo_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::base::TimeDelta p_seek_time{};
      MediaPlayer_RequestSeekTo_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSeekTime(&p_seek_time))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 4, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestSeekTo(
std::move(p_seek_time));
      return true;
    }
    case internal::kMediaPlayer_RequestEnterPictureInPicture_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestEnterPictureInPicture_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestEnterPictureInPicture_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      MediaPlayer_RequestEnterPictureInPicture_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 5, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestEnterPictureInPicture();
      return true;
    }
    case internal::kMediaPlayer_RequestExitPictureInPicture_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestExitPictureInPicture_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestExitPictureInPicture_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      MediaPlayer_RequestExitPictureInPicture_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 6, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestExitPictureInPicture();
      return true;
    }
    case internal::kMediaPlayer_RequestMute_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_RequestMute_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_RequestMute_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_mute{};
      MediaPlayer_RequestMute_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_mute = input_data_view.mute();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 7, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RequestMute(
std::move(p_mute));
      return true;
    }
    case internal::kMediaPlayer_SetVolumeMultiplier_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_SetVolumeMultiplier_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_SetVolumeMultiplier_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      double p_multiplier{};
      MediaPlayer_SetVolumeMultiplier_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_multiplier = input_data_view.multiplier();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 8, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetVolumeMultiplier(
std::move(p_multiplier));
      return true;
    }
    case internal::kMediaPlayer_SetPersistentState_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_SetPersistentState_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_SetPersistentState_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_persistent{};
      MediaPlayer_SetPersistentState_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_persistent = input_data_view.persistent();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 9, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetPersistentState(
std::move(p_persistent));
      return true;
    }
    case internal::kMediaPlayer_SetPowerExperimentState_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_SetPowerExperimentState_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_SetPowerExperimentState_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_enabled{};
      MediaPlayer_SetPowerExperimentState_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_enabled = input_data_view.enabled();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 10, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetPowerExperimentState(
std::move(p_enabled));
      return true;
    }
    case internal::kMediaPlayer_SetAudioSinkId_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayer_SetAudioSinkId_Params_Data* params =
          reinterpret_cast<internal::MediaPlayer_SetAudioSinkId_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      WTF::String p_sink_id{};
      MediaPlayer_SetAudioSinkId_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSinkId(&p_sink_id))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayer::Name_, 11, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetAudioSinkId(
std::move(p_sink_id));
      return true;
    }
    case internal::kMediaPlayer_SuspendForFrameClosed_Name: {

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

// static
bool MediaPlayerStubDispatch::AcceptWithResponder(
    MediaPlayer* 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::kMediaPlayer_RequestPlay_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestPause_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestSeekForward_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestSeekBackward_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestSeekTo_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestEnterPictureInPicture_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestExitPictureInPicture_Name: {
      break;
    }
    case internal::kMediaPlayer_RequestMute_Name: {
      break;
    }
    case internal::kMediaPlayer_SetVolumeMultiplier_Name: {
      break;
    }
    case internal::kMediaPlayer_SetPersistentState_Name: {
      break;
    }
    case internal::kMediaPlayer_SetPowerExperimentState_Name: {
      break;
    }
    case internal::kMediaPlayer_SetAudioSinkId_Name: {
      break;
    }
    case internal::kMediaPlayer_SuspendForFrameClosed_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kMediaPlayerValidationInfo[] = {
    {&internal::MediaPlayer_RequestPlay_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestPause_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestSeekForward_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestSeekBackward_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestSeekTo_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestEnterPictureInPicture_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestExitPictureInPicture_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_RequestMute_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_SetVolumeMultiplier_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_SetPersistentState_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_SetPowerExperimentState_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_SetAudioSinkId_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayer_SuspendForFrameClosed_Params_Data::Validate,
     nullptr /* no response */},
};

bool MediaPlayerRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::media::mojom::blink::MediaPlayer::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kMediaPlayerValidationInfo);
}

const char MediaPlayerObserverClient::Name_[] = "media.mojom.MediaPlayerObserverClient";

std::pair<uint32_t, const void*> MediaPlayerObserverClient::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kMediaPlayerObserverClient_GetHasPlayedBefore_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserverClient::GetHasPlayedBefore");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserverClient::GetHasPlayedBefore_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* MediaPlayerObserverClient::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::kMediaPlayerObserverClient_GetHasPlayedBefore_Name:
            return "Receive media::mojom::MediaPlayerObserverClient::GetHasPlayedBefore";
    }
  } else {
    switch (message.name()) {
      case internal::kMediaPlayerObserverClient_GetHasPlayedBefore_Name:
            return "Receive reply media::mojom::MediaPlayerObserverClient::GetHasPlayedBefore";
    }
  }
  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 MediaPlayerObserverClient::GetHasPlayedBefore_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 MediaPlayerObserverClient_GetHasPlayedBefore_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  MediaPlayerObserverClient_GetHasPlayedBefore_ForwardToCallback(
      MediaPlayerObserverClient::GetHasPlayedBeforeCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  MediaPlayerObserverClient::GetHasPlayedBeforeCallback callback_;
};

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

void MediaPlayerObserverClientProxy::GetHasPlayedBefore(
    GetHasPlayedBeforeCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayerObserverClient::GetHasPlayedBefore");
#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::kMediaPlayerObserverClient_GetHasPlayedBefore_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserverClient_GetHasPlayedBefore_Params_Data> params(
          message);
  params.Allocate();

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

  ~MediaPlayerObserverClient_GetHasPlayedBefore_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:
  MediaPlayerObserverClient_GetHasPlayedBefore_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)
        << "MediaPlayerObserverClient::GetHasPlayedBeforeCallback 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_has_played_before);
};

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

  DCHECK(message->is_serialized());
  internal::MediaPlayerObserverClient_GetHasPlayedBefore_ResponseParams_Data* params =
      reinterpret_cast<
          internal::MediaPlayerObserverClient_GetHasPlayedBefore_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_has_played_before{};
  MediaPlayerObserverClient_GetHasPlayedBefore_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_has_played_before = input_data_view.has_played_before();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        MediaPlayerObserverClient::Name_, 0, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_has_played_before));
  return true;
}

void MediaPlayerObserverClient_GetHasPlayedBefore_ProxyToResponder::Run(
    bool in_has_played_before) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply media::mojom::MediaPlayerObserverClient::GetHasPlayedBefore", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("has_played_before"), in_has_played_before,
                        "<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::kMediaPlayerObserverClient_GetHasPlayedBefore_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserverClient_GetHasPlayedBefore_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->has_played_before = in_has_played_before;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserverClient::Name_);
  message.set_method_name("GetHasPlayedBefore");
#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 MediaPlayerObserverClientStubDispatch::Accept(
    MediaPlayerObserverClient* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kMediaPlayerObserverClient_GetHasPlayedBefore_Name: {
      break;
    }
  }
  return false;
}

// static
bool MediaPlayerObserverClientStubDispatch::AcceptWithResponder(
    MediaPlayerObserverClient* 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::kMediaPlayerObserverClient_GetHasPlayedBefore_Name: {

      internal::MediaPlayerObserverClient_GetHasPlayedBefore_Params_Data* params =
          reinterpret_cast<
              internal::MediaPlayerObserverClient_GetHasPlayedBefore_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      MediaPlayerObserverClient_GetHasPlayedBefore_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserverClient::Name_, 0, false);
        return false;
      }
      MediaPlayerObserverClient::GetHasPlayedBeforeCallback callback =
          MediaPlayerObserverClient_GetHasPlayedBefore_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetHasPlayedBefore(std::move(callback));
      return true;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kMediaPlayerObserverClientValidationInfo[] = {
    {&internal::MediaPlayerObserverClient_GetHasPlayedBefore_Params_Data::Validate,
     &internal::MediaPlayerObserverClient_GetHasPlayedBefore_ResponseParams_Data::Validate},
};

bool MediaPlayerObserverClientRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::media::mojom::blink::MediaPlayerObserverClient::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kMediaPlayerObserverClientValidationInfo);
}

bool MediaPlayerObserverClientResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::media::mojom::blink::MediaPlayerObserverClient::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kMediaPlayerObserverClientValidationInfo);
}
const char MediaPlayerObserver::Name_[] = "media.mojom.MediaPlayerObserver";

std::pair<uint32_t, const void*> MediaPlayerObserver::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kMediaPlayerObserver_OnMediaPlaying_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMediaPlaying");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMediaPlaying_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnMediaPaused_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMediaPaused");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMediaPaused_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnMutedStatusChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMutedStatusChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMutedStatusChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnMediaMetadataChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMediaMetadataChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMediaMetadataChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnMediaPositionStateChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMediaPositionStateChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMediaPositionStateChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMediaEffectivelyFullscreenChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMediaEffectivelyFullscreenChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnMediaSizeChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnMediaSizeChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnMediaSizeChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnPictureInPictureAvailabilityChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnPictureInPictureAvailabilityChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnAudioOutputSinkChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnAudioOutputSinkChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnAudioOutputSinkChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnUseAudioServiceChanged_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnUseAudioServiceChanged");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnUseAudioServiceChanged_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kMediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerObserver::OnAudioOutputSinkChangingDisabled");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerObserver::OnAudioOutputSinkChangingDisabled_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* MediaPlayerObserver::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::kMediaPlayerObserver_OnMediaPlaying_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMediaPlaying";
      case internal::kMediaPlayerObserver_OnMediaPaused_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMediaPaused";
      case internal::kMediaPlayerObserver_OnMutedStatusChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMutedStatusChanged";
      case internal::kMediaPlayerObserver_OnMediaMetadataChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMediaMetadataChanged";
      case internal::kMediaPlayerObserver_OnMediaPositionStateChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMediaPositionStateChanged";
      case internal::kMediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMediaEffectivelyFullscreenChanged";
      case internal::kMediaPlayerObserver_OnMediaSizeChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnMediaSizeChanged";
      case internal::kMediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnPictureInPictureAvailabilityChanged";
      case internal::kMediaPlayerObserver_OnAudioOutputSinkChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnAudioOutputSinkChanged";
      case internal::kMediaPlayerObserver_OnUseAudioServiceChanged_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnUseAudioServiceChanged";
      case internal::kMediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Name:
            return "Receive media::mojom::MediaPlayerObserver::OnAudioOutputSinkChangingDisabled";
    }
  } else {
    switch (message.name()) {
      case internal::kMediaPlayerObserver_OnMediaPlaying_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMediaPlaying";
      case internal::kMediaPlayerObserver_OnMediaPaused_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMediaPaused";
      case internal::kMediaPlayerObserver_OnMutedStatusChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMutedStatusChanged";
      case internal::kMediaPlayerObserver_OnMediaMetadataChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMediaMetadataChanged";
      case internal::kMediaPlayerObserver_OnMediaPositionStateChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMediaPositionStateChanged";
      case internal::kMediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMediaEffectivelyFullscreenChanged";
      case internal::kMediaPlayerObserver_OnMediaSizeChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnMediaSizeChanged";
      case internal::kMediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnPictureInPictureAvailabilityChanged";
      case internal::kMediaPlayerObserver_OnAudioOutputSinkChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnAudioOutputSinkChanged";
      case internal::kMediaPlayerObserver_OnUseAudioServiceChanged_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnUseAudioServiceChanged";
      case internal::kMediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Name:
            return "Receive reply media::mojom::MediaPlayerObserver::OnAudioOutputSinkChangingDisabled";
    }
  }
  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 MediaPlayerObserver::OnMediaPlaying_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 MediaPlayerObserver::OnMediaPaused_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 MediaPlayerObserver::OnMutedStatusChanged_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 MediaPlayerObserver::OnMediaMetadataChanged_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 MediaPlayerObserver::OnMediaPositionStateChanged_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 MediaPlayerObserver::OnMediaEffectivelyFullscreenChanged_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 MediaPlayerObserver::OnMediaSizeChanged_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 MediaPlayerObserver::OnPictureInPictureAvailabilityChanged_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 MediaPlayerObserver::OnAudioOutputSinkChanged_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 MediaPlayerObserver::OnUseAudioServiceChanged_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 MediaPlayerObserver::OnAudioOutputSinkChangingDisabled_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)

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

void MediaPlayerObserverProxy::OnMediaPlaying(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayerObserver::OnMediaPlaying");
#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::kMediaPlayerObserver_OnMediaPlaying_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMediaPlaying_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMediaPlaying");
#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 MediaPlayerObserverProxy::OnMediaPaused(
    bool in_stream_ended) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnMediaPaused", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("stream_ended"), in_stream_ended,
                        "<value of type bool>");
   });
#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::kMediaPlayerObserver_OnMediaPaused_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMediaPaused_Params_Data> params(
          message);
  params.Allocate();
  params->stream_ended = in_stream_ended;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMediaPaused");
#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 MediaPlayerObserverProxy::OnMutedStatusChanged(
    bool in_muted) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnMutedStatusChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("muted"), in_muted,
                        "<value of type bool>");
   });
#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::kMediaPlayerObserver_OnMutedStatusChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMutedStatusChanged_Params_Data> params(
          message);
  params.Allocate();
  params->muted = in_muted;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMutedStatusChanged");
#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 MediaPlayerObserverProxy::OnMediaMetadataChanged(
    bool in_has_audio, bool in_has_video, ::media::MediaContentType in_content_type) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnMediaMetadataChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("has_audio"), in_has_audio,
                        "<value of type bool>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("has_video"), in_has_video,
                        "<value of type bool>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("content_type"), in_content_type,
                        "<value of type ::media::MediaContentType>");
   });
#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::kMediaPlayerObserver_OnMediaMetadataChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMediaMetadataChanged_Params_Data> params(
          message);
  params.Allocate();
  params->has_audio = in_has_audio;
  params->has_video = in_has_video;
  mojo::internal::Serialize<::media::mojom::MediaContentType>(
      in_content_type, &params->content_type);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMediaMetadataChanged");
#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 MediaPlayerObserverProxy::OnMediaPositionStateChanged(
    ::media_session::mojom::blink::MediaPositionPtr in_media_position) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnMediaPositionStateChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("media_position"), in_media_position,
                        "<value of type ::media_session::mojom::blink::MediaPositionPtr>");
   });
#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::kMediaPlayerObserver_OnMediaPositionStateChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMediaPositionStateChanged_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->media_position)::BaseType> media_position_fragment(
          params.message());
  mojo::internal::Serialize<::media_session::mojom::MediaPositionDataView>(
      in_media_position, media_position_fragment);
  params->media_position.Set(
      media_position_fragment.is_null() ? nullptr : media_position_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->media_position.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null media_position in MediaPlayerObserver.OnMediaPositionStateChanged request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMediaPositionStateChanged");
#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 MediaPlayerObserverProxy::OnMediaEffectivelyFullscreenChanged(
    ::blink::WebFullscreenVideoStatus in_status) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnMediaEffectivelyFullscreenChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("status"), in_status,
                        "<value of type ::blink::WebFullscreenVideoStatus>");
   });
#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::kMediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::media::mojom::FullscreenVideoStatus>(
      in_status, &params->status);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMediaEffectivelyFullscreenChanged");
#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 MediaPlayerObserverProxy::OnMediaSizeChanged(
    const ::gfx::Size& in_size) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnMediaSizeChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("size"), in_size,
                        "<value of type const ::gfx::Size&>");
   });
#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::kMediaPlayerObserver_OnMediaSizeChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnMediaSizeChanged_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->size)::BaseType> size_fragment(
          params.message());
  mojo::internal::Serialize<::gfx::mojom::SizeDataView>(
      in_size, size_fragment);
  params->size.Set(
      size_fragment.is_null() ? nullptr : size_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->size.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null size in MediaPlayerObserver.OnMediaSizeChanged request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnMediaSizeChanged");
#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 MediaPlayerObserverProxy::OnPictureInPictureAvailabilityChanged(
    bool in_available) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnPictureInPictureAvailabilityChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("available"), in_available,
                        "<value of type bool>");
   });
#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::kMediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Params_Data> params(
          message);
  params.Allocate();
  params->available = in_available;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnPictureInPictureAvailabilityChanged");
#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 MediaPlayerObserverProxy::OnAudioOutputSinkChanged(
    const WTF::String& in_hashed_device_id) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnAudioOutputSinkChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("hashed_device_id"), in_hashed_device_id,
                        "<value of type const WTF::String&>");
   });
#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::kMediaPlayerObserver_OnAudioOutputSinkChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnAudioOutputSinkChanged_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->hashed_device_id)::BaseType> hashed_device_id_fragment(
          params.message());
  mojo::internal::Serialize<mojo::StringDataView>(
      in_hashed_device_id, hashed_device_id_fragment);
  params->hashed_device_id.Set(
      hashed_device_id_fragment.is_null() ? nullptr : hashed_device_id_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->hashed_device_id.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null hashed_device_id in MediaPlayerObserver.OnAudioOutputSinkChanged request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnAudioOutputSinkChanged");
#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 MediaPlayerObserverProxy::OnUseAudioServiceChanged(
    bool in_uses_audio_service) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerObserver::OnUseAudioServiceChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("uses_audio_service"), in_uses_audio_service,
                        "<value of type bool>");
   });
#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::kMediaPlayerObserver_OnUseAudioServiceChanged_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnUseAudioServiceChanged_Params_Data> params(
          message);
  params.Allocate();
  params->uses_audio_service = in_uses_audio_service;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(MediaPlayerObserver::Name_);
  message.set_method_name("OnUseAudioServiceChanged");
#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 MediaPlayerObserverProxy::OnAudioOutputSinkChangingDisabled(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send media::mojom::MediaPlayerObserver::OnAudioOutputSinkChangingDisabled");
#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::kMediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Params_Data> params(
          message);
  params.Allocate();

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

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

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnMediaPaused_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnMediaPaused_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_stream_ended{};
      MediaPlayerObserver_OnMediaPaused_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_stream_ended = input_data_view.stream_ended();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMediaPaused(
std::move(p_stream_ended));
      return true;
    }
    case internal::kMediaPlayerObserver_OnMutedStatusChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnMutedStatusChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnMutedStatusChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_muted{};
      MediaPlayerObserver_OnMutedStatusChanged_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_muted = input_data_view.muted();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 2, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMutedStatusChanged(
std::move(p_muted));
      return true;
    }
    case internal::kMediaPlayerObserver_OnMediaMetadataChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnMediaMetadataChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnMediaMetadataChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_has_audio{};
      bool p_has_video{};
      ::media::MediaContentType p_content_type{};
      MediaPlayerObserver_OnMediaMetadataChanged_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_has_audio = input_data_view.has_audio();
      if (success)
        p_has_video = input_data_view.has_video();
      if (success && !input_data_view.ReadContentType(&p_content_type))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 3, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMediaMetadataChanged(
std::move(p_has_audio), 
std::move(p_has_video), 
std::move(p_content_type));
      return true;
    }
    case internal::kMediaPlayerObserver_OnMediaPositionStateChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnMediaPositionStateChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnMediaPositionStateChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::media_session::mojom::blink::MediaPositionPtr p_media_position{};
      MediaPlayerObserver_OnMediaPositionStateChanged_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadMediaPosition(&p_media_position))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 4, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMediaPositionStateChanged(
std::move(p_media_position));
      return true;
    }
    case internal::kMediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::blink::WebFullscreenVideoStatus p_status{};
      MediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_ParamsDataView 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,
            MediaPlayerObserver::Name_, 5, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMediaEffectivelyFullscreenChanged(
std::move(p_status));
      return true;
    }
    case internal::kMediaPlayerObserver_OnMediaSizeChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnMediaSizeChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnMediaSizeChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::gfx::Size p_size{};
      MediaPlayerObserver_OnMediaSizeChanged_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSize(&p_size))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 6, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMediaSizeChanged(
std::move(p_size));
      return true;
    }
    case internal::kMediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_available{};
      MediaPlayerObserver_OnPictureInPictureAvailabilityChanged_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_available = input_data_view.available();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 7, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnPictureInPictureAvailabilityChanged(
std::move(p_available));
      return true;
    }
    case internal::kMediaPlayerObserver_OnAudioOutputSinkChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnAudioOutputSinkChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnAudioOutputSinkChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      WTF::String p_hashed_device_id{};
      MediaPlayerObserver_OnAudioOutputSinkChanged_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadHashedDeviceId(&p_hashed_device_id))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 8, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnAudioOutputSinkChanged(
std::move(p_hashed_device_id));
      return true;
    }
    case internal::kMediaPlayerObserver_OnUseAudioServiceChanged_Name: {

      DCHECK(message->is_serialized());
      internal::MediaPlayerObserver_OnUseAudioServiceChanged_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerObserver_OnUseAudioServiceChanged_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_uses_audio_service{};
      MediaPlayerObserver_OnUseAudioServiceChanged_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_uses_audio_service = input_data_view.uses_audio_service();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerObserver::Name_, 9, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnUseAudioServiceChanged(
std::move(p_uses_audio_service));
      return true;
    }
    case internal::kMediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Name: {

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

// static
bool MediaPlayerObserverStubDispatch::AcceptWithResponder(
    MediaPlayerObserver* 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::kMediaPlayerObserver_OnMediaPlaying_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnMediaPaused_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnMutedStatusChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnMediaMetadataChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnMediaPositionStateChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnMediaSizeChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnAudioOutputSinkChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnUseAudioServiceChanged_Name: {
      break;
    }
    case internal::kMediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kMediaPlayerObserverValidationInfo[] = {
    {&internal::MediaPlayerObserver_OnMediaPlaying_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnMediaPaused_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnMutedStatusChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnMediaMetadataChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnMediaPositionStateChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnMediaEffectivelyFullscreenChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnMediaSizeChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnPictureInPictureAvailabilityChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnAudioOutputSinkChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnUseAudioServiceChanged_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::MediaPlayerObserver_OnAudioOutputSinkChangingDisabled_Params_Data::Validate,
     nullptr /* no response */},
};

bool MediaPlayerObserverRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::media::mojom::blink::MediaPlayerObserver::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kMediaPlayerObserverValidationInfo);
}

const char MediaPlayerHost::Name_[] = "media.mojom.MediaPlayerHost";

std::pair<uint32_t, const void*> MediaPlayerHost::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kMediaPlayerHost_OnMediaPlayerAdded_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)media::mojom::MediaPlayerHost::OnMediaPlayerAdded");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&MediaPlayerHost::OnMediaPlayerAdded_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* MediaPlayerHost::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::kMediaPlayerHost_OnMediaPlayerAdded_Name:
            return "Receive media::mojom::MediaPlayerHost::OnMediaPlayerAdded";
    }
  } else {
    switch (message.name()) {
      case internal::kMediaPlayerHost_OnMediaPlayerAdded_Name:
            return "Receive reply media::mojom::MediaPlayerHost::OnMediaPlayerAdded";
    }
  }
  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 MediaPlayerHost::OnMediaPlayerAdded_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)

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

void MediaPlayerHostProxy::OnMediaPlayerAdded(
    ::mojo::PendingAssociatedRemote<MediaPlayer> in_player_remote, ::mojo::PendingAssociatedReceiver<MediaPlayerObserver> in_observer, int32_t in_player_id) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send media::mojom::MediaPlayerHost::OnMediaPlayerAdded", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("player_remote"), in_player_remote,
                        "<value of type ::mojo::PendingAssociatedRemote<MediaPlayer>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("observer"), in_observer,
                        "<value of type ::mojo::PendingAssociatedReceiver<MediaPlayerObserver>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("player_id"), in_player_id,
                        "<value of type int32_t>");
   });
#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::kMediaPlayerHost_OnMediaPlayerAdded_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::media::mojom::internal::MediaPlayerHost_OnMediaPlayerAdded_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::media::mojom::MediaPlayerAssociatedPtrInfoDataView>(
      in_player_remote, &params->player_remote, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->player_remote),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
      "invalid player_remote in MediaPlayerHost.OnMediaPlayerAdded request");
  mojo::internal::Serialize<::media::mojom::MediaPlayerObserverAssociatedRequestDataView>(
      in_observer, &params->observer, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->observer),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
      "invalid observer in MediaPlayerHost.OnMediaPlayerAdded request");
  params->player_id = in_player_id;

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

      DCHECK(message->is_serialized());
      internal::MediaPlayerHost_OnMediaPlayerAdded_Params_Data* params =
          reinterpret_cast<internal::MediaPlayerHost_OnMediaPlayerAdded_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::mojo::PendingAssociatedRemote<MediaPlayer> p_player_remote{};
      ::mojo::PendingAssociatedReceiver<MediaPlayerObserver> p_observer{};
      int32_t p_player_id{};
      MediaPlayerHost_OnMediaPlayerAdded_ParamsDataView input_data_view(params, message);
      
      if (success) {
        p_player_remote =
            input_data_view.TakePlayerRemote<decltype(p_player_remote)>();
      }
      if (success) {
        p_observer =
            input_data_view.TakeObserver<decltype(p_observer)>();
      }
      if (success)
        p_player_id = input_data_view.player_id();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            MediaPlayerHost::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnMediaPlayerAdded(
std::move(p_player_remote), 
std::move(p_observer), 
std::move(p_player_id));
      return true;
    }
  }
  return false;
}

// static
bool MediaPlayerHostStubDispatch::AcceptWithResponder(
    MediaPlayerHost* 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::kMediaPlayerHost_OnMediaPlayerAdded_Name: {
      break;
    }
  }
  return false;
}


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

bool MediaPlayerHostRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::media::mojom::blink::MediaPlayerHost::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kMediaPlayerHostValidationInfo);
}



}  // namespace blink
}  // namespace mojom
}  // namespace media


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 media {
namespace mojom {
namespace blink {


void MediaPlayerInterceptorForTesting::RequestPlay() {
  GetForwardingInterface()->RequestPlay();
}
void MediaPlayerInterceptorForTesting::RequestPause(bool triggered_by_user) {
  GetForwardingInterface()->RequestPause(std::move(triggered_by_user));
}
void MediaPlayerInterceptorForTesting::RequestSeekForward(::base::TimeDelta seek_time) {
  GetForwardingInterface()->RequestSeekForward(std::move(seek_time));
}
void MediaPlayerInterceptorForTesting::RequestSeekBackward(::base::TimeDelta seek_time) {
  GetForwardingInterface()->RequestSeekBackward(std::move(seek_time));
}
void MediaPlayerInterceptorForTesting::RequestSeekTo(::base::TimeDelta seek_time) {
  GetForwardingInterface()->RequestSeekTo(std::move(seek_time));
}
void MediaPlayerInterceptorForTesting::RequestEnterPictureInPicture() {
  GetForwardingInterface()->RequestEnterPictureInPicture();
}
void MediaPlayerInterceptorForTesting::RequestExitPictureInPicture() {
  GetForwardingInterface()->RequestExitPictureInPicture();
}
void MediaPlayerInterceptorForTesting::RequestMute(bool mute) {
  GetForwardingInterface()->RequestMute(std::move(mute));
}
void MediaPlayerInterceptorForTesting::SetVolumeMultiplier(double multiplier) {
  GetForwardingInterface()->SetVolumeMultiplier(std::move(multiplier));
}
void MediaPlayerInterceptorForTesting::SetPersistentState(bool persistent) {
  GetForwardingInterface()->SetPersistentState(std::move(persistent));
}
void MediaPlayerInterceptorForTesting::SetPowerExperimentState(bool enabled) {
  GetForwardingInterface()->SetPowerExperimentState(std::move(enabled));
}
void MediaPlayerInterceptorForTesting::SetAudioSinkId(const WTF::String& sink_id) {
  GetForwardingInterface()->SetAudioSinkId(std::move(sink_id));
}
void MediaPlayerInterceptorForTesting::SuspendForFrameClosed() {
  GetForwardingInterface()->SuspendForFrameClosed();
}
MediaPlayerAsyncWaiter::MediaPlayerAsyncWaiter(
    MediaPlayer* proxy) : proxy_(proxy) {}

MediaPlayerAsyncWaiter::~MediaPlayerAsyncWaiter() = default;




void MediaPlayerObserverClientInterceptorForTesting::GetHasPlayedBefore(GetHasPlayedBeforeCallback callback) {
  GetForwardingInterface()->GetHasPlayedBefore(std::move(callback));
}
MediaPlayerObserverClientAsyncWaiter::MediaPlayerObserverClientAsyncWaiter(
    MediaPlayerObserverClient* proxy) : proxy_(proxy) {}

MediaPlayerObserverClientAsyncWaiter::~MediaPlayerObserverClientAsyncWaiter() = default;

void MediaPlayerObserverClientAsyncWaiter::GetHasPlayedBefore(
    bool* out_has_played_before) {
  base::RunLoop loop;
  proxy_->GetHasPlayedBefore(
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_has_played_before
,
             bool has_played_before) {*out_has_played_before = std::move(has_played_before);
            loop->Quit();
          },
          &loop,
          out_has_played_before));
  loop.Run();
}



void MediaPlayerObserverInterceptorForTesting::OnMediaPlaying() {
  GetForwardingInterface()->OnMediaPlaying();
}
void MediaPlayerObserverInterceptorForTesting::OnMediaPaused(bool stream_ended) {
  GetForwardingInterface()->OnMediaPaused(std::move(stream_ended));
}
void MediaPlayerObserverInterceptorForTesting::OnMutedStatusChanged(bool muted) {
  GetForwardingInterface()->OnMutedStatusChanged(std::move(muted));
}
void MediaPlayerObserverInterceptorForTesting::OnMediaMetadataChanged(bool has_audio, bool has_video, ::media::MediaContentType content_type) {
  GetForwardingInterface()->OnMediaMetadataChanged(std::move(has_audio), std::move(has_video), std::move(content_type));
}
void MediaPlayerObserverInterceptorForTesting::OnMediaPositionStateChanged(::media_session::mojom::blink::MediaPositionPtr media_position) {
  GetForwardingInterface()->OnMediaPositionStateChanged(std::move(media_position));
}
void MediaPlayerObserverInterceptorForTesting::OnMediaEffectivelyFullscreenChanged(::blink::WebFullscreenVideoStatus status) {
  GetForwardingInterface()->OnMediaEffectivelyFullscreenChanged(std::move(status));
}
void MediaPlayerObserverInterceptorForTesting::OnMediaSizeChanged(const ::gfx::Size& size) {
  GetForwardingInterface()->OnMediaSizeChanged(std::move(size));
}
void MediaPlayerObserverInterceptorForTesting::OnPictureInPictureAvailabilityChanged(bool available) {
  GetForwardingInterface()->OnPictureInPictureAvailabilityChanged(std::move(available));
}
void MediaPlayerObserverInterceptorForTesting::OnAudioOutputSinkChanged(const WTF::String& hashed_device_id) {
  GetForwardingInterface()->OnAudioOutputSinkChanged(std::move(hashed_device_id));
}
void MediaPlayerObserverInterceptorForTesting::OnUseAudioServiceChanged(bool uses_audio_service) {
  GetForwardingInterface()->OnUseAudioServiceChanged(std::move(uses_audio_service));
}
void MediaPlayerObserverInterceptorForTesting::OnAudioOutputSinkChangingDisabled() {
  GetForwardingInterface()->OnAudioOutputSinkChangingDisabled();
}
MediaPlayerObserverAsyncWaiter::MediaPlayerObserverAsyncWaiter(
    MediaPlayerObserver* proxy) : proxy_(proxy) {}

MediaPlayerObserverAsyncWaiter::~MediaPlayerObserverAsyncWaiter() = default;




void MediaPlayerHostInterceptorForTesting::OnMediaPlayerAdded(::mojo::PendingAssociatedRemote<MediaPlayer> player_remote, ::mojo::PendingAssociatedReceiver<MediaPlayerObserver> observer, int32_t player_id) {
  GetForwardingInterface()->OnMediaPlayerAdded(std::move(player_remote), std::move(observer), std::move(player_id));
}
MediaPlayerHostAsyncWaiter::MediaPlayerHostAsyncWaiter(
    MediaPlayerHost* proxy) : proxy_(proxy) {}

MediaPlayerHostAsyncWaiter::~MediaPlayerHostAsyncWaiter() = default;






}  // namespace blink
}  // namespace mojom
}  // namespace media


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