You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
6.0 KiB
156 lines
6.0 KiB
4 months ago
|
// Copyright 2015 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 MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_
|
||
|
#define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_
|
||
|
|
||
|
#include <memory>
|
||
|
#include <string>
|
||
|
#include <utility>
|
||
|
|
||
|
#include "base/bind.h"
|
||
|
#include "base/callback.h"
|
||
|
#include "base/logging.h"
|
||
|
#include "base/macros.h"
|
||
|
#include "base/memory/ptr_util.h"
|
||
|
#include "base/memory/ref_counted.h"
|
||
|
#include "base/single_thread_task_runner.h"
|
||
|
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
|
||
|
#include "mojo/public/cpp/bindings/associated_interface_request.h"
|
||
|
#include "mojo/public/cpp/bindings/bindings_export.h"
|
||
|
#include "mojo/public/cpp/bindings/connection_error_callback.h"
|
||
|
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
||
|
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
|
||
|
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
|
||
|
|
||
|
namespace mojo {
|
||
|
|
||
|
class MessageReceiver;
|
||
|
|
||
|
// Base class used to factor out code in AssociatedBinding<T> expansions, in
|
||
|
// particular for Bind().
|
||
|
class MOJO_CPP_BINDINGS_EXPORT AssociatedBindingBase {
|
||
|
public:
|
||
|
AssociatedBindingBase();
|
||
|
~AssociatedBindingBase();
|
||
|
|
||
|
// Adds a message filter to be notified of each incoming message before
|
||
|
// dispatch. If a filter returns |false| from Accept(), the message is not
|
||
|
// dispatched and the pipe is closed. Filters cannot be removed.
|
||
|
void AddFilter(std::unique_ptr<MessageReceiver> filter);
|
||
|
|
||
|
// Closes the associated interface. Puts this object into a state where it can
|
||
|
// be rebound.
|
||
|
void Close();
|
||
|
|
||
|
// Similar to the method above, but also specifies a disconnect reason.
|
||
|
void CloseWithReason(uint32_t custom_reason, const std::string& description);
|
||
|
|
||
|
// Sets an error handler that will be called if a connection error occurs.
|
||
|
//
|
||
|
// This method may only be called after this AssociatedBinding has been bound
|
||
|
// to a message pipe. The error handler will be reset when this
|
||
|
// AssociatedBinding is unbound or closed.
|
||
|
void set_connection_error_handler(base::OnceClosure error_handler);
|
||
|
|
||
|
void set_connection_error_with_reason_handler(
|
||
|
ConnectionErrorWithReasonCallback error_handler);
|
||
|
|
||
|
// Indicates whether the associated binding has been completed.
|
||
|
bool is_bound() const { return !!endpoint_client_; }
|
||
|
|
||
|
explicit operator bool() const { return !!endpoint_client_; }
|
||
|
|
||
|
// Sends a message on the underlying message pipe and runs the current
|
||
|
// message loop until its response is received. This can be used in tests to
|
||
|
// verify that no message was sent on a message pipe in response to some
|
||
|
// stimulus.
|
||
|
void FlushForTesting();
|
||
|
|
||
|
protected:
|
||
|
void BindImpl(ScopedInterfaceEndpointHandle handle,
|
||
|
MessageReceiverWithResponderStatus* receiver,
|
||
|
std::unique_ptr<MessageReceiver> payload_validator,
|
||
|
bool expect_sync_requests,
|
||
|
scoped_refptr<base::SingleThreadTaskRunner> runner,
|
||
|
uint32_t interface_version);
|
||
|
|
||
|
std::unique_ptr<InterfaceEndpointClient> endpoint_client_;
|
||
|
};
|
||
|
|
||
|
// Represents the implementation side of an associated interface. It is similar
|
||
|
// to Binding, except that it doesn't own a message pipe handle.
|
||
|
//
|
||
|
// When you bind this class to a request, optionally you can specify a
|
||
|
// base::SingleThreadTaskRunner. This task runner must belong to the same
|
||
|
// thread. It will be used to dispatch incoming method calls and connection
|
||
|
// error notification. It is useful when you attach multiple task runners to a
|
||
|
// single thread for the purposes of task scheduling. Please note that
|
||
|
// incoming synchronous method calls may not be run from this task runner, when
|
||
|
// they reenter outgoing synchronous calls on the same thread.
|
||
|
template <typename Interface,
|
||
|
typename ImplRefTraits = RawPtrImplRefTraits<Interface>>
|
||
|
class AssociatedBinding : public AssociatedBindingBase {
|
||
|
public:
|
||
|
using ImplPointerType = typename ImplRefTraits::PointerType;
|
||
|
|
||
|
// Constructs an incomplete associated binding that will use the
|
||
|
// implementation |impl|. It may be completed with a subsequent call to the
|
||
|
// |Bind| method.
|
||
|
explicit AssociatedBinding(ImplPointerType impl) {
|
||
|
stub_.set_sink(std::move(impl));
|
||
|
}
|
||
|
|
||
|
// Constructs a completed associated binding of |impl|. |impl| must outlive
|
||
|
// the binding.
|
||
|
AssociatedBinding(
|
||
|
ImplPointerType impl,
|
||
|
AssociatedInterfaceRequest<Interface> request,
|
||
|
scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr)
|
||
|
: AssociatedBinding(std::move(impl)) {
|
||
|
Bind(std::move(request), std::move(runner));
|
||
|
}
|
||
|
|
||
|
~AssociatedBinding() {}
|
||
|
|
||
|
// Sets up this object as the implementation side of an associated interface.
|
||
|
void Bind(AssociatedInterfaceRequest<Interface> request,
|
||
|
scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) {
|
||
|
BindImpl(request.PassHandle(), &stub_,
|
||
|
base::WrapUnique(new typename Interface::RequestValidator_()),
|
||
|
Interface::HasSyncMethods_, std::move(runner),
|
||
|
Interface::Version_);
|
||
|
}
|
||
|
|
||
|
// Unbinds and returns the associated interface request so it can be
|
||
|
// used in another context, such as on another sequence or with a different
|
||
|
// implementation. Puts this object into a state where it can be rebound.
|
||
|
AssociatedInterfaceRequest<Interface> Unbind() {
|
||
|
DCHECK(endpoint_client_);
|
||
|
AssociatedInterfaceRequest<Interface> request(
|
||
|
endpoint_client_->PassHandle());
|
||
|
endpoint_client_.reset();
|
||
|
return request;
|
||
|
}
|
||
|
|
||
|
// Returns the interface implementation that was previously specified.
|
||
|
Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); }
|
||
|
|
||
|
// Allows test code to swap the interface implementation.
|
||
|
ImplPointerType SwapImplForTesting(ImplPointerType new_impl) {
|
||
|
Interface* old_impl = impl();
|
||
|
stub_.set_sink(std::move(new_impl));
|
||
|
return old_impl;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
typename Interface::template Stub_<ImplRefTraits> stub_;
|
||
|
|
||
|
DISALLOW_COPY_AND_ASSIGN(AssociatedBinding);
|
||
|
};
|
||
|
|
||
|
} // namespace mojo
|
||
|
|
||
|
#endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_
|