// services/network/public/mojom/network_change_manager.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_NETWORK_PUBLIC_MOJOM_NETWORK_CHANGE_MANAGER_MOJOM_H_
#define SERVICES_NETWORK_PUBLIC_MOJOM_NETWORK_CHANGE_MANAGER_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/network/public/mojom/network_change_manager.mojom-shared.h"
#include "services/network/public/mojom/network_change_manager.mojom-forward.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 network {
namespace mojom {

class NetworkChangeManagerClientProxy;

template <typename ImplRefTraits>
class NetworkChangeManagerClientStub;

class NetworkChangeManagerClientRequestValidator;


// @generated_from: network.mojom.NetworkChangeManagerClient
class  NetworkChangeManagerClient
    : public NetworkChangeManagerClientInterfaceBase {
 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_ = NetworkChangeManagerClientInterfaceBase;
  using Proxy_ = NetworkChangeManagerClientProxy;

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

  using RequestValidator_ = NetworkChangeManagerClientRequestValidator;
  using ResponseValidator_ = mojo::PassThroughFilter;
  enum MethodMinVersions : uint32_t {
    kOnInitialConnectionTypeMinVersion = 0,
    kOnNetworkChangedMinVersion = 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 OnInitialConnectionType_Sym {
    NOINLINE static void IPCSymbol();
  };
  struct OnNetworkChanged_Sym {
    NOINLINE static void IPCSymbol();
  };
#endif // !BUILDFLAG(IS_FUCHSIA)
  virtual ~NetworkChangeManagerClient() = default;

  
// @generated_from: network.mojom.NetworkChangeManagerClient.OnInitialConnectionType
  virtual void OnInitialConnectionType(ConnectionType type) = 0;

  
// @generated_from: network.mojom.NetworkChangeManagerClient.OnNetworkChanged
  virtual void OnNetworkChanged(ConnectionType type) = 0;
};

class NetworkChangeManagerProxy;

template <typename ImplRefTraits>
class NetworkChangeManagerStub;

class NetworkChangeManagerRequestValidator;


// @generated_from: network.mojom.NetworkChangeManager
class  NetworkChangeManager
    : public NetworkChangeManagerInterfaceBase {
 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_ = NetworkChangeManagerInterfaceBase;
  using Proxy_ = NetworkChangeManagerProxy;

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

  using RequestValidator_ = NetworkChangeManagerRequestValidator;
  using ResponseValidator_ = mojo::PassThroughFilter;
  enum MethodMinVersions : uint32_t {
    kRequestNotificationsMinVersion = 0,
    kOnNetworkChangedMinVersion = 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 RequestNotifications_Sym {
    NOINLINE static void IPCSymbol();
  };
  struct OnNetworkChanged_Sym {
    NOINLINE static void IPCSymbol();
  };
#endif // !BUILDFLAG(IS_FUCHSIA)
  virtual ~NetworkChangeManager() = default;

  
// @generated_from: network.mojom.NetworkChangeManager.RequestNotifications
  virtual void RequestNotifications(::mojo::PendingRemote<NetworkChangeManagerClient> client_remote) = 0;

  
// @generated_from: network.mojom.NetworkChangeManager.OnNetworkChanged
  virtual void OnNetworkChanged(bool dns_changed, bool ip_address_changed, bool connection_type_changed, ConnectionType new_connection_type, bool connection_subtype_changed, ConnectionSubtype new_connection_subtype) = 0;
};



// @generated_from: network.mojom.NetworkChangeManagerClient
class  NetworkChangeManagerClientProxy
    : public NetworkChangeManagerClient {
 public:
  using InterfaceType = NetworkChangeManagerClient;

  explicit NetworkChangeManagerClientProxy(mojo::MessageReceiverWithResponder* receiver);
  
// @generated_from: network.mojom.NetworkChangeManagerClient.OnInitialConnectionType
  void OnInitialConnectionType(ConnectionType type) final;
  
// @generated_from: network.mojom.NetworkChangeManagerClient.OnNetworkChanged
  void OnNetworkChanged(ConnectionType type) final;

 private:
  mojo::MessageReceiverWithResponder* receiver_;
};



// @generated_from: network.mojom.NetworkChangeManager
class  NetworkChangeManagerProxy
    : public NetworkChangeManager {
 public:
  using InterfaceType = NetworkChangeManager;

  explicit NetworkChangeManagerProxy(mojo::MessageReceiverWithResponder* receiver);
  
// @generated_from: network.mojom.NetworkChangeManager.RequestNotifications
  void RequestNotifications(::mojo::PendingRemote<NetworkChangeManagerClient> client_remote) final;
  
// @generated_from: network.mojom.NetworkChangeManager.OnNetworkChanged
  void OnNetworkChanged(bool dns_changed, bool ip_address_changed, bool connection_type_changed, ConnectionType new_connection_type, bool connection_subtype_changed, ConnectionSubtype new_connection_subtype) final;

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

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

  NetworkChangeManagerClientStub() = default;
  ~NetworkChangeManagerClientStub() 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 NetworkChangeManagerClientStubDispatch::Accept(
        ImplRefTraits::GetRawPointer(&sink_), message);
  }

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

 private:
  ImplPointerType sink_;
};
class  NetworkChangeManagerStubDispatch {
 public:
  static bool Accept(NetworkChangeManager* impl, mojo::Message* message);
  static bool AcceptWithResponder(
      NetworkChangeManager* impl,
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder);
};

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

  NetworkChangeManagerStub() = default;
  ~NetworkChangeManagerStub() 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 NetworkChangeManagerStubDispatch::Accept(
        ImplRefTraits::GetRawPointer(&sink_), message);
  }

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

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





}  // namespace mojom
}  // namespace network

namespace mojo {

}  // namespace mojo

#endif  // SERVICES_NETWORK_PUBLIC_MOJOM_NETWORK_CHANGE_MANAGER_MOJOM_H_

/* Metadata comment
eyJtZXRhIjogW3siZW5kIjogMTY3MiwgImJlZ2luIjogMTY0NiwgImVkZ2UiOiAiJS9reXRoZS9l
ZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3Jw
dXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2Ui
OiAibW9qb20iLCAic2lnbmF0dXJlIjogIm5ldHdvcmsubW9qb20uTmV0d29ya0NoYW5nZU1hbmFn
ZXJDbGllbnQifX0sIHsiZW5kIjogMzEwNywgImJlZ2luIjogMzA4NCwgImVkZ2UiOiAiJS9reXRo
ZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJj
b3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3Vh
Z2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogIm5ldHdvcmsubW9qb20uTmV0d29ya0NoYW5nZU1h
bmFnZXJDbGllbnQuT25Jbml0aWFsQ29ubmVjdGlvblR5cGUifX0sIHsiZW5kIjogMzI0NywgImJl
Z2luIjogMzIzMSwgImVkZ2UiOiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFu
Y2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNl
LmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogIm5l
dHdvcmsubW9qb20uTmV0d29ya0NoYW5nZU1hbmFnZXJDbGllbnQuT25OZXR3b3JrQ2hhbmdlZCJ9
fSwgeyJlbmQiOiAzNTA3LCAiYmVnaW4iOiAzNDg3LCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2Vu
ZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJj
aHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pv
bSIsICJzaWduYXR1cmUiOiAibmV0d29yay5tb2pvbS5OZXR3b3JrQ2hhbmdlTWFuYWdlciJ9fSwg
eyJlbmQiOiA0ODg4LCAiYmVnaW4iOiA0ODY4LCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJh
dGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJv
bWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pvbSIs
ICJzaWduYXR1cmUiOiAibmV0d29yay5tb2pvbS5OZXR3b3JrQ2hhbmdlTWFuYWdlci5SZXF1ZXN0
Tm90aWZpY2F0aW9ucyJ9fSwgeyJlbmQiOiA1MDY2LCAiYmVnaW4iOiA1MDUwLCAiZWRnZSI6ICIl
L2t5dGhlL2VkZ2UvZ2VuZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUi
OiB7ImNvcnB1cyI6ICJjaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJs
YW5ndWFnZSI6ICJtb2pvbSIsICJzaWduYXR1cmUiOiAibmV0d29yay5tb2pvbS5OZXR3b3JrQ2hh
bmdlTWFuYWdlci5Pbk5ldHdvcmtDaGFuZ2VkIn19LCB7ImVuZCI6IDU2NzQsICJiZWdpbiI6IDU2
NTEsICJlZGdlIjogIiUva3l0aGUvZWRnZS9nZW5lcmF0ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVm
aW5lcyIsICJ2bmFtZSI6IHsiY29ycHVzIjogImNocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hy
b21pdW0vc3JjIiwgImxhbmd1YWdlIjogIm1vam9tIiwgInNpZ25hdHVyZSI6ICJuZXR3b3JrLm1v
am9tLk5ldHdvcmtDaGFuZ2VNYW5hZ2VyQ2xpZW50Lk9uSW5pdGlhbENvbm5lY3Rpb25UeXBlIn19
LCB7ImVuZCI6IDU4MDcsICJiZWdpbiI6IDU3OTEsICJlZGdlIjogIiUva3l0aGUvZWRnZS9nZW5l
cmF0ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVmaW5lcyIsICJ2bmFtZSI6IHsiY29ycHVzIjogImNo
cm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjIiwgImxhbmd1YWdlIjogIm1vam9t
IiwgInNpZ25hdHVyZSI6ICJuZXR3b3JrLm1vam9tLk5ldHdvcmtDaGFuZ2VNYW5hZ2VyQ2xpZW50
Lk9uTmV0d29ya0NoYW5nZWQifX0sIHsiZW5kIjogNjI3MiwgImJlZ2luIjogNjI1MiwgImVkZ2Ui
OiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZu
YW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMi
LCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogIm5ldHdvcmsubW9qb20uTmV0d29y
a0NoYW5nZU1hbmFnZXIuUmVxdWVzdE5vdGlmaWNhdGlvbnMifX0sIHsiZW5kIjogNjQ0MywgImJl
Z2luIjogNjQyNywgImVkZ2UiOiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFu
Y2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNl
LmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogIm5l
dHdvcmsubW9qb20uTmV0d29ya0NoYW5nZU1hbmFnZXIuT25OZXR3b3JrQ2hhbmdlZCJ9fV0sICJ0
eXBlIjogImt5dGhlMCJ9
*/