blob: b7c4d7cfae9b0f37b568b8c945bf8e0f0016df4a [file] [log] [blame]
// Copyright 2017 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.
#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
#include "mojo/public/cpp/bindings/lib/task_runner_helper.h"
namespace mojo {
namespace internal {
InterfacePtrStateBase::InterfacePtrStateBase() = default;
InterfacePtrStateBase::~InterfacePtrStateBase() {
endpoint_client_.reset();
if (router_)
router_->CloseMessagePipe();
}
void InterfacePtrStateBase::QueryVersion(
base::OnceCallback<void(uint32_t)> callback) {
// It is safe to capture |this| because the callback won't be run after this
// object goes away.
endpoint_client_->QueryVersion(
base::BindOnce(&InterfacePtrStateBase::OnQueryVersion,
base::Unretained(this), std::move(callback)));
}
void InterfacePtrStateBase::RequireVersion(uint32_t version) {
if (version <= version_)
return;
version_ = version;
endpoint_client_->RequireVersion(version);
}
void InterfacePtrStateBase::PauseReceiverUntilFlushCompletes(
PendingFlush flush) {
router_->PausePeerUntilFlushCompletes(std::move(flush));
}
void InterfacePtrStateBase::FlushAsync(AsyncFlusher flusher) {
router_->FlushAsync(std::move(flusher));
}
void InterfacePtrStateBase::Swap(InterfacePtrStateBase* other) {
using std::swap;
swap(other->router_, router_);
swap(other->endpoint_client_, endpoint_client_);
handle_.swap(other->handle_);
runner_.swap(other->runner_);
swap(other->version_, version_);
}
void InterfacePtrStateBase::Bind(
PendingRemoteState* remote_state,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
DCHECK(!router_);
DCHECK(!endpoint_client_);
DCHECK(!handle_.is_valid());
DCHECK_EQ(0u, version_);
DCHECK(remote_state->pipe.is_valid());
handle_ = std::move(remote_state->pipe);
version_ = remote_state->version;
runner_ =
GetTaskRunnerToUseFromUserProvidedTaskRunner(std::move(task_runner));
}
void InterfacePtrStateBase::OnQueryVersion(
base::OnceCallback<void(uint32_t)> callback,
uint32_t version) {
version_ = version;
std::move(callback).Run(version);
}
bool InterfacePtrStateBase::InitializeEndpointClient(
bool passes_associated_kinds,
bool has_sync_methods,
std::unique_ptr<MessageReceiver> payload_validator,
const char* interface_name) {
// The object hasn't been bound.
if (!handle_.is_valid())
return false;
MultiplexRouter::Config config =
passes_associated_kinds
? MultiplexRouter::MULTI_INTERFACE
: (has_sync_methods
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
: MultiplexRouter::SINGLE_INTERFACE);
DCHECK(runner_->RunsTasksInCurrentSequence());
router_ = new MultiplexRouter(std::move(handle_), config, true, runner_,
interface_name);
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), nullptr,
std::move(payload_validator), false, std::move(runner_),
// The version is only queried from the client so the value passed here
// will not be used.
0u, interface_name);
return true;
}
} // namespace internal
} // namespace mojo