// 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_LIB_BINDING_STATE_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_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/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/bindings_export.h"
#include "mojo/public/cpp/bindings/connection_error_callback.h"
#include "mojo/public/cpp/bindings/filter_chain.h"
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
#include "mojo/public/cpp/bindings/interface_id.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/interface_ptr_info.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
#include "mojo/public/cpp/bindings/message_header_validator.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/system/core.h"
namespace mojo {
namespace internal {
class MOJO_CPP_BINDINGS_EXPORT BindingStateBase {
public:
BindingStateBase();
~BindingStateBase();
void AddFilter(std::unique_ptr<MessageReceiver> filter);
bool HasAssociatedInterfaces() const;
void PauseIncomingMethodCallProcessing();
void ResumeIncomingMethodCallProcessing();
bool WaitForIncomingMethodCall(
MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE);
void Close();
void CloseWithReason(uint32_t custom_reason, const std::string& description);
void RaiseError() { endpoint_client_->RaiseError(); }
void set_connection_error_handler(base::OnceClosure error_handler) {
DCHECK(is_bound());
endpoint_client_->set_connection_error_handler(std::move(error_handler));
}
void set_connection_error_with_reason_handler(
ConnectionErrorWithReasonCallback error_handler) {
DCHECK(is_bound());
endpoint_client_->set_connection_error_with_reason_handler(
std::move(error_handler));
}
bool is_bound() const { return !!router_; }
MessagePipeHandle handle() const {
DCHECK(is_bound());
return router_->handle();
}
ReportBadMessageCallback GetBadMessageCallback();
void FlushForTesting();
void EnableTestingMode();
scoped_refptr<internal::MultiplexRouter> RouterForTesting();
protected:
void BindInternal(ScopedMessagePipeHandle handle,
scoped_refptr<base::SingleThreadTaskRunner> runner,
const char* interface_name,
std::unique_ptr<MessageReceiver> request_validator,
bool passes_associated_kinds,
bool has_sync_methods,
MessageReceiverWithResponderStatus* stub,
uint32_t interface_version);
scoped_refptr<internal::MultiplexRouter> router_;
std::unique_ptr<InterfaceEndpointClient> endpoint_client_;
base::WeakPtrFactory<BindingStateBase> weak_ptr_factory_;
};
template <typename Interface, typename ImplRefTraits>
class BindingState : public BindingStateBase {
public:
using ImplPointerType = typename ImplRefTraits::PointerType;
explicit BindingState(ImplPointerType impl) {
stub_.set_sink(std::move(impl));
}
~BindingState() { Close(); }
void Bind(ScopedMessagePipeHandle handle,
scoped_refptr<base::SingleThreadTaskRunner> runner) {
BindingStateBase::BindInternal(
std::move(handle), runner, Interface::Name_,
std::make_unique<typename Interface::RequestValidator_>(),
Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_, &stub_,
Interface::Version_);
}
InterfaceRequest<Interface> Unbind() {
endpoint_client_.reset();
InterfaceRequest<Interface> request(router_->PassMessagePipe());
router_ = nullptr;
return request;
}
Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); }
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(BindingState);
};
} // namesapce internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_