// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_SET_H_ #define MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_SET_H_ #include <map> #include <memory> #include <optional> #include <string> #include <utility> #include "base/compiler_specific.h" #include "base/component_export.h" #include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr_exclusion.h" #include "base/task/sequenced_task_runner.h" #include "mojo/public/cpp/bindings/connection_error_callback.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/runtime_features.h" #include "mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h" namespace mojo { namespace test { class ReceiverSetStaticAssertTests; } ReceiverId; template <typename ReceiverType> struct ReceiverSetTraits; ReceiverSetTraits<Receiver<Interface, ImplRefTraits>>; template <typename ContextType> struct ReceiverSetContextTraits { … }; template <> struct ReceiverSetContextTraits<void> { … }; // Shared base class owning specific type-agnostic ReceiverSet state and logic. class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) ReceiverSetState { … }; // Generic helper used to own a collection of Receiver endpoints. For // convenience this type automatically manages cleanup of receivers that have // been disconnected from their remote caller. // // Note that this type is not typically used directly by application. Instead, // prefer to use one of the various aliases (like ReceiverSet) that are based on // it. // // If |ContextType| is non-void, then every added receiver must include a // context value of that type (when calling |Add()|), and |current_context()| // will return that value during the extent of any message dispatch or // disconnection notification pertaining to that specific receiver. // // So for example if ContextType is |int| and we call: // // Remote<mojom::Foo> foo1, foo2; // ReceiverSet<mojom::Foo> receivers; // // Assume |this| is an implementation of mojom::Foo... // receivers.Add(this, foo1.BindNewReceiver(), 42); // receivers.Add(this, foo2.BindNewReceiver(), 43); // // foo1->DoSomething(); // foo2->DoSomething(); // // We can expect two asynchronous calls to |this->DoSomething()|. If that // method looks at the value of |current_context()|, it will see a value of 42 // while executing the call from |foo1| and a value of 43 while executing the // call from |foo2|. // // RuntimeFeature guarded receivers should only be added to a set if they are // enabled - if an interface is feature guarded validate the enabled state of // the corresponding feature before calling Add(). // // Finally, note that ContextType can be any type of thing, including move-only // objects like std::unique_ptrs. template <typename ReceiverType, typename ContextType> class ReceiverSetBase { … }; // Common helper for a set of Receivers which do not own their implementation. ReceiverSet; } // namespace mojo #endif // MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_SET_H_