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

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

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

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

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

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

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


#ifndef SERVICES_DEVICE_PUBLIC_MOJOM_POWER_MONITOR_MOJOM_JUMBO_H_
#define SERVICES_DEVICE_PUBLIC_MOJOM_POWER_MONITOR_MOJOM_JUMBO_H_
#endif



namespace device {
namespace mojom {
const char PowerMonitor::Name_[] = "device.mojom.PowerMonitor";

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


const char* PowerMonitor::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::kPowerMonitor_AddClient_Name:
            return "Receive device::mojom::PowerMonitor::AddClient";
    }
  } else {
    switch (message.name()) {
      case internal::kPowerMonitor_AddClient_Name:
            return "Receive reply device::mojom::PowerMonitor::AddClient";
    }
  }
  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 PowerMonitor::AddClient_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)

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

void PowerMonitorProxy::AddClient(
    ::mojo::PendingRemote<PowerMonitorClient> in_client) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::PowerMonitor::AddClient", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("client"), in_client,
                        "<value of type ::mojo::PendingRemote<PowerMonitorClient>>");
   });
#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::kPowerMonitor_AddClient_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::PowerMonitor_AddClient_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::device::mojom::PowerMonitorClientInterfaceBase>>(
      in_client, &params->client, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->client),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid client in PowerMonitor.AddClient request");

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

      DCHECK(message->is_serialized());
      internal::PowerMonitor_AddClient_Params_Data* params =
          reinterpret_cast<internal::PowerMonitor_AddClient_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::mojo::PendingRemote<PowerMonitorClient> p_client{};
      PowerMonitor_AddClient_ParamsDataView input_data_view(params, message);
      
      if (success) {
        p_client =
            input_data_view.TakeClient<decltype(p_client)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            PowerMonitor::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->AddClient(
std::move(p_client));
      return true;
    }
  }
  return false;
}

// static
bool PowerMonitorStubDispatch::AcceptWithResponder(
    PowerMonitor* 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::kPowerMonitor_AddClient_Name: {
      break;
    }
  }
  return false;
}


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

bool PowerMonitorRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::PowerMonitor::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kPowerMonitorValidationInfo);
}

const char PowerMonitorClient::Name_[] = "device.mojom.PowerMonitorClient";

std::pair<uint32_t, const void*> PowerMonitorClient::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kPowerMonitorClient_PowerStateChange_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::PowerMonitorClient::PowerStateChange");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PowerMonitorClient::PowerStateChange_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kPowerMonitorClient_Suspend_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::PowerMonitorClient::Suspend");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PowerMonitorClient::Suspend_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kPowerMonitorClient_Resume_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)device::mojom::PowerMonitorClient::Resume");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PowerMonitorClient::Resume_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* PowerMonitorClient::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::kPowerMonitorClient_PowerStateChange_Name:
            return "Receive device::mojom::PowerMonitorClient::PowerStateChange";
      case internal::kPowerMonitorClient_Suspend_Name:
            return "Receive device::mojom::PowerMonitorClient::Suspend";
      case internal::kPowerMonitorClient_Resume_Name:
            return "Receive device::mojom::PowerMonitorClient::Resume";
    }
  } else {
    switch (message.name()) {
      case internal::kPowerMonitorClient_PowerStateChange_Name:
            return "Receive reply device::mojom::PowerMonitorClient::PowerStateChange";
      case internal::kPowerMonitorClient_Suspend_Name:
            return "Receive reply device::mojom::PowerMonitorClient::Suspend";
      case internal::kPowerMonitorClient_Resume_Name:
            return "Receive reply device::mojom::PowerMonitorClient::Resume";
    }
  }
  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 PowerMonitorClient::PowerStateChange_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 PowerMonitorClient::Suspend_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 PowerMonitorClient::Resume_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
# endif // !BUILDFLAG(IS_FUCHSIA)

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

void PowerMonitorClientProxy::PowerStateChange(
    bool in_on_battery_power) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::PowerMonitorClient::PowerStateChange", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("on_battery_power"), in_on_battery_power,
                        "<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::kPowerMonitorClient_PowerStateChange_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::PowerMonitorClient_PowerStateChange_Params_Data> params(
          message);
  params.Allocate();
  params->on_battery_power = in_on_battery_power;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PowerMonitorClient::Name_);
  message.set_method_name("PowerStateChange");
#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 PowerMonitorClientProxy::Suspend(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::PowerMonitorClient::Suspend");
#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::kPowerMonitorClient_Suspend_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::PowerMonitorClient_Suspend_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PowerMonitorClient::Name_);
  message.set_method_name("Suspend");
#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 PowerMonitorClientProxy::Resume(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::PowerMonitorClient::Resume");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPowerMonitorClient_Resume_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::PowerMonitorClient_Resume_Params_Data> params(
          message);
  params.Allocate();

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

// static
bool PowerMonitorClientStubDispatch::Accept(
    PowerMonitorClient* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kPowerMonitorClient_PowerStateChange_Name: {

      DCHECK(message->is_serialized());
      internal::PowerMonitorClient_PowerStateChange_Params_Data* params =
          reinterpret_cast<internal::PowerMonitorClient_PowerStateChange_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      bool p_on_battery_power{};
      PowerMonitorClient_PowerStateChange_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_on_battery_power = input_data_view.on_battery_power();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            PowerMonitorClient::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->PowerStateChange(
std::move(p_on_battery_power));
      return true;
    }
    case internal::kPowerMonitorClient_Suspend_Name: {

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

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

// static
bool PowerMonitorClientStubDispatch::AcceptWithResponder(
    PowerMonitorClient* 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::kPowerMonitorClient_PowerStateChange_Name: {
      break;
    }
    case internal::kPowerMonitorClient_Suspend_Name: {
      break;
    }
    case internal::kPowerMonitorClient_Resume_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kPowerMonitorClientValidationInfo[] = {
    {&internal::PowerMonitorClient_PowerStateChange_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::PowerMonitorClient_Suspend_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::PowerMonitorClient_Resume_Params_Data::Validate,
     nullptr /* no response */},
};

bool PowerMonitorClientRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::PowerMonitorClient::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kPowerMonitorClientValidationInfo);
}



}  // namespace mojom
}  // namespace device


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 device {
namespace mojom {


void PowerMonitorInterceptorForTesting::AddClient(::mojo::PendingRemote<PowerMonitorClient> client) {
  GetForwardingInterface()->AddClient(std::move(client));
}
PowerMonitorAsyncWaiter::PowerMonitorAsyncWaiter(
    PowerMonitor* proxy) : proxy_(proxy) {}

PowerMonitorAsyncWaiter::~PowerMonitorAsyncWaiter() = default;




void PowerMonitorClientInterceptorForTesting::PowerStateChange(bool on_battery_power) {
  GetForwardingInterface()->PowerStateChange(std::move(on_battery_power));
}
void PowerMonitorClientInterceptorForTesting::Suspend() {
  GetForwardingInterface()->Suspend();
}
void PowerMonitorClientInterceptorForTesting::Resume() {
  GetForwardingInterface()->Resume();
}
PowerMonitorClientAsyncWaiter::PowerMonitorClientAsyncWaiter(
    PowerMonitorClient* proxy) : proxy_(proxy) {}

PowerMonitorClientAsyncWaiter::~PowerMonitorClientAsyncWaiter() = default;






}  // namespace mojom
}  // namespace device


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