Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Unified Diff: mojo/public/cpp/bindings/lib/interface_endpoint_client.cc

Issue 2646853003: Mojo C++ bindings: Simplify associated interface API. (Closed)
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index a9eee86b6aa27ec93664b1937875287e68996ef2..2eab43036a83a24b9bb24d99d4ee6ecbb41039b5 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -137,48 +137,43 @@ InterfaceEndpointClient::InterfaceEndpointClient(
bool expect_sync_requests,
scoped_refptr<base::SingleThreadTaskRunner> runner,
uint32_t interface_version)
- : handle_(std::move(handle)),
+ : expect_sync_requests_(expect_sync_requests),
+ handle_(std::move(handle)),
incoming_receiver_(receiver),
thunk_(this),
filters_(&thunk_),
- next_request_id_(1),
- encountered_error_(false),
task_runner_(std::move(runner)),
control_message_proxy_(this),
control_message_handler_(interface_version),
weak_ptr_factory_(this) {
DCHECK(handle_.is_valid());
- DCHECK(handle_.is_local());
// TODO(yzshen): the way to use validator (or message filter in general)
// directly is a little awkward.
if (payload_validator)
filters_.Append(std::move(payload_validator));
- controller_ = handle_.group_controller()->AttachEndpointClient(
- handle_, this, task_runner_);
- if (expect_sync_requests)
- controller_->AllowWokenUpBySyncWatchOnSameThread();
+ if (handle_.pending_association()) {
+ handle_.SetAssociationEventHandler(base::Bind(
+ &InterfaceEndpointClient::OnAssociationEvent, base::Unretained(this)));
+ } else {
+ InitControllerIfNecessary();
+ }
}
InterfaceEndpointClient::~InterfaceEndpointClient() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (handle_.is_valid())
+ if (controller_)
handle_.group_controller()->DetachEndpointClient(handle_);
}
AssociatedGroup* InterfaceEndpointClient::associated_group() {
if (!associated_group_)
- associated_group_ = handle_.group_controller()->CreateAssociatedGroup();
+ associated_group_ = base::MakeUnique<AssociatedGroup>(handle_);
return associated_group_.get();
}
-uint32_t InterfaceEndpointClient::interface_id() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return handle_.id();
-}
-
ScopedInterfaceEndpointHandle InterfaceEndpointClient::PassHandle() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!has_pending_responders());
@@ -186,8 +181,13 @@ ScopedInterfaceEndpointHandle InterfaceEndpointClient::PassHandle() {
if (!handle_.is_valid())
return ScopedInterfaceEndpointHandle();
- controller_ = nullptr;
- handle_.group_controller()->DetachEndpointClient(handle_);
+ handle_.SetAssociationEventHandler(
+ ScopedInterfaceEndpointHandle::AssociationEventCallback());
+
+ if (controller_) {
+ controller_ = nullptr;
+ handle_.group_controller()->DetachEndpointClient(handle_);
+ }
return std::move(handle_);
}
@@ -200,7 +200,8 @@ void InterfaceEndpointClient::AddFilter(
void InterfaceEndpointClient::RaiseError() {
DCHECK(thread_checker_.CalledOnValidThread());
- handle_.group_controller()->RaiseError();
+ if (!handle_.pending_association())
+ handle_.group_controller()->RaiseError();
}
void InterfaceEndpointClient::CloseWithReason(uint32_t custom_reason,
@@ -213,24 +214,40 @@ void InterfaceEndpointClient::CloseWithReason(uint32_t custom_reason,
bool InterfaceEndpointClient::Accept(Message* message) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(controller_);
DCHECK(!message->has_flag(Message::kFlagExpectsResponse));
+ DCHECK(!handle_.pending_association());
+
+ // This has to been done even if connection error has occurred. For example,
+ // the message contains a pending associated request. The user may try to use
+ // the corresponding associated interface pointer after sending this message.
+ // That associated interface pointer has to join an associated group in order
+ // to work properly.
+ if (!message->associated_endpoint_handles()->empty())
+ message->SerializeAssociatedEndpointHandles(handle_.group_controller());
if (encountered_error_)
return false;
+ InitControllerIfNecessary();
+
return controller_->SendMessage(message);
}
bool InterfaceEndpointClient::AcceptWithResponder(Message* message,
MessageReceiver* responder) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(controller_);
DCHECK(message->has_flag(Message::kFlagExpectsResponse));
+ DCHECK(!handle_.pending_association());
+
+ // Please see comments in Accept().
+ if (!message->associated_endpoint_handles()->empty())
+ message->SerializeAssociatedEndpointHandles(handle_.group_controller());
if (encountered_error_)
return false;
+ InitControllerIfNecessary();
+
// Reserve 0 in case we want it to convey special meaning in the future.
uint64_t request_id = next_request_id_++;
if (request_id == 0)
@@ -305,6 +322,42 @@ void InterfaceEndpointClient::NotifyError(
}
}
+void InterfaceEndpointClient::QueryVersion(
+ const base::Callback<void(uint32_t)>& callback) {
+ control_message_proxy_.QueryVersion(callback);
+}
+
+void InterfaceEndpointClient::RequireVersion(uint32_t version) {
+ control_message_proxy_.RequireVersion(version);
+}
+
+void InterfaceEndpointClient::FlushForTesting() {
+ control_message_proxy_.FlushForTesting();
+}
+
+void InterfaceEndpointClient::InitControllerIfNecessary() {
+ if (controller_ || handle_.pending_association())
+ return;
+
+ controller_ = handle_.group_controller()->AttachEndpointClient(handle_, this,
+ task_runner_);
+ if (expect_sync_requests_)
+ controller_->AllowWokenUpBySyncWatchOnSameThread();
+}
+
+void InterfaceEndpointClient::OnAssociationEvent(
+ ScopedInterfaceEndpointHandle::AssociationEvent event) {
+ if (event == ScopedInterfaceEndpointHandle::ASSOCIATED) {
+ InitControllerIfNecessary();
+ } else if (event ==
+ ScopedInterfaceEndpointHandle::PEER_CLOSED_BEFORE_ASSOCIATION) {
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&InterfaceEndpointClient::NotifyError,
+ weak_ptr_factory_.GetWeakPtr(),
+ handle_.disconnect_reason()));
+ }
+}
+
bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) {
DCHECK_EQ(handle_.id(), message->interface_id());
DCHECK(!encountered_error_);
« no previous file with comments | « mojo/public/cpp/bindings/lib/handle_interface_serialization.h ('k') | mojo/public/cpp/bindings/lib/interface_ptr_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698