// services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom.h 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.

#ifndef SERVICES_VIZ_PRIVILEGED_MOJOM_COMPOSITING_VSYNC_PARAMETER_OBSERVER_MOJOM_H_
#define SERVICES_VIZ_PRIVILEGED_MOJOM_COMPOSITING_VSYNC_PARAMETER_OBSERVER_MOJOM_H_

#include <stdint.h>

#include <limits>
#include <type_traits>
#include <utility>

#include "third_party/abseil-cpp/absl/types/optional.h"
#include "mojo/public/cpp/bindings/clone_traits.h"
#include "mojo/public/cpp/bindings/equals_traits.h"
#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/bindings/union_traits.h"

#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"

#include "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom-shared.h"
#include "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom-forward.h"
#include "mojo/public/mojom/base/time.mojom.h"
#include <string>
#include <vector>

#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"



#ifdef KYTHE_IS_RUNNING
#pragma kythe_inline_metadata "Metadata comment"
#endif


namespace viz {
namespace mojom {

class VSyncParameterObserverProxy;

template <typename ImplRefTraits>
class VSyncParameterObserverStub;

class VSyncParameterObserverRequestValidator;


// @generated_from: viz.mojom.VSyncParameterObserver
class  VSyncParameterObserver
    : public VSyncParameterObserverInterfaceBase {
 public:
  static const char Name_[];
  static std::pair<uint32_t, const void*> MessageToMethodInfo_(mojo::Message& message);
  static const char* MessageToMethodName_(mojo::Message& message);
  static constexpr uint32_t Version_ = 0;
  static constexpr bool PassesAssociatedKinds_ = false;
  static constexpr bool HasSyncMethods_ = false;
  static constexpr bool HasUninterruptableMethods_ = false;

  using Base_ = VSyncParameterObserverInterfaceBase;
  using Proxy_ = VSyncParameterObserverProxy;

  template <typename ImplRefTraits>
  using Stub_ = VSyncParameterObserverStub<ImplRefTraits>;

  using RequestValidator_ = VSyncParameterObserverRequestValidator;
  using ResponseValidator_ = mojo::PassThroughFilter;
  enum MethodMinVersions : uint32_t {
    kOnUpdateVSyncParametersMinVersion = 0,
  };

// crbug.com/1340245 - this causes binary size bloat on Fuchsia, and we're OK
// with not having this data in traces there.
#if !BUILDFLAG(IS_FUCHSIA)
  struct OnUpdateVSyncParameters_Sym {
    NOINLINE static void IPCSymbol();
  };
#endif // !BUILDFLAG(IS_FUCHSIA)
  virtual ~VSyncParameterObserver() = default;

  
// @generated_from: viz.mojom.VSyncParameterObserver.OnUpdateVSyncParameters
  virtual void OnUpdateVSyncParameters(::base::TimeTicks timebase, ::base::TimeDelta interval) = 0;
};



// @generated_from: viz.mojom.VSyncParameterObserver
class  VSyncParameterObserverProxy
    : public VSyncParameterObserver {
 public:
  using InterfaceType = VSyncParameterObserver;

  explicit VSyncParameterObserverProxy(mojo::MessageReceiverWithResponder* receiver);
  
// @generated_from: viz.mojom.VSyncParameterObserver.OnUpdateVSyncParameters
  void OnUpdateVSyncParameters(::base::TimeTicks timebase, ::base::TimeDelta interval) final;

 private:
  mojo::MessageReceiverWithResponder* receiver_;
};
class  VSyncParameterObserverStubDispatch {
 public:
  static bool Accept(VSyncParameterObserver* impl, mojo::Message* message);
  static bool AcceptWithResponder(
      VSyncParameterObserver* impl,
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder);
};

template <typename ImplRefTraits =
              mojo::RawPtrImplRefTraits<VSyncParameterObserver>>
class VSyncParameterObserverStub
    : public mojo::MessageReceiverWithResponderStatus {
 public:
  using ImplPointerType = typename ImplRefTraits::PointerType;

  VSyncParameterObserverStub() = default;
  ~VSyncParameterObserverStub() override = default;

  void set_sink(ImplPointerType sink) { sink_ = std::move(sink); }
  ImplPointerType& sink() { return sink_; }

  bool Accept(mojo::Message* message) override {
    if (ImplRefTraits::IsNull(sink_))
      return false;
    return VSyncParameterObserverStubDispatch::Accept(
        ImplRefTraits::GetRawPointer(&sink_), message);
  }

  bool AcceptWithResponder(
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) override {
    if (ImplRefTraits::IsNull(sink_))
      return false;
    return VSyncParameterObserverStubDispatch::AcceptWithResponder(
        ImplRefTraits::GetRawPointer(&sink_), message, std::move(responder));
  }

 private:
  ImplPointerType sink_;
};
class  VSyncParameterObserverRequestValidator : public mojo::MessageReceiver {
 public:
  bool Accept(mojo::Message* message) override;
};





}  // namespace mojom
}  // namespace viz

namespace mojo {

}  // namespace mojo

#endif  // SERVICES_VIZ_PRIVILEGED_MOJOM_COMPOSITING_VSYNC_PARAMETER_OBSERVER_MOJOM_H_

/* Metadata comment
eyJtZXRhIjogW3siZW5kIjogMTc2MSwgImJlZ2luIjogMTczOSwgImVkZ2UiOiAiJS9reXRoZS9l
ZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3Jw
dXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2Ui
OiAibW9qb20iLCAic2lnbmF0dXJlIjogInZpei5tb2pvbS5WU3luY1BhcmFtZXRlck9ic2VydmVy
In19LCB7ImVuZCI6IDMwNTIsICJiZWdpbiI6IDMwMjksICJlZGdlIjogIiUva3l0aGUvZWRnZS9n
ZW5lcmF0ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVmaW5lcyIsICJ2bmFtZSI6IHsiY29ycHVzIjog
ImNocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjIiwgImxhbmd1YWdlIjogIm1v
am9tIiwgInNpZ25hdHVyZSI6ICJ2aXoubW9qb20uVlN5bmNQYXJhbWV0ZXJPYnNlcnZlci5PblVw
ZGF0ZVZTeW5jUGFyYW1ldGVycyJ9fSwgeyJlbmQiOiAzNTAwLCAiYmVnaW4iOiAzNDc3LCAiZWRn
ZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAi
dm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3Ny
YyIsICJsYW5ndWFnZSI6ICJtb2pvbSIsICJzaWduYXR1cmUiOiAidml6Lm1vam9tLlZTeW5jUGFy
YW1ldGVyT2JzZXJ2ZXIuT25VcGRhdGVWU3luY1BhcmFtZXRlcnMifX1dLCAidHlwZSI6ICJreXRo
ZTAifQ==
*/