blob: 8088a7e6b50de066686d0d0c9d7a6905341caa11 [file] [log] [blame]
// Copyright 2014 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 "device/serial/serial_connection_factory.h"
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "device/serial/serial_connection.h"
#include "device/serial/serial_io_handler.h"
namespace device {
namespace {
void FillDefaultConnectionOptions(serial::ConnectionOptions* options) {
if (!options->bitrate)
options->bitrate = 9600;
if (options->data_bits == serial::DataBits::NONE)
options->data_bits = serial::DataBits::EIGHT;
if (options->stop_bits == serial::StopBits::NONE)
options->stop_bits = serial::StopBits::ONE;
if (options->parity_bit == serial::ParityBit::NONE)
options->parity_bit = serial::ParityBit::NO;
if (!options->has_cts_flow_control) {
options->has_cts_flow_control = true;
options->cts_flow_control = false;
}
}
} // namespace
class SerialConnectionFactory::ConnectTask
: public base::RefCountedThreadSafe<SerialConnectionFactory::ConnectTask> {
public:
ConnectTask(scoped_refptr<SerialConnectionFactory> factory,
const std::string& path,
serial::ConnectionOptionsPtr options,
mojo::InterfaceRequest<serial::Connection> connection_request,
mojo::InterfaceRequest<serial::DataSink> sink,
mojo::InterfaceRequest<serial::DataSource> source,
mojo::InterfacePtr<serial::DataSourceClient> source_client);
void Run();
private:
friend class base::RefCountedThreadSafe<SerialConnectionFactory::ConnectTask>;
virtual ~ConnectTask();
void Connect();
void OnConnected(bool success);
scoped_refptr<SerialConnectionFactory> factory_;
const std::string path_;
serial::ConnectionOptionsPtr options_;
mojo::InterfaceRequest<serial::Connection> connection_request_;
mojo::InterfaceRequest<serial::DataSink> sink_;
mojo::InterfaceRequest<serial::DataSource> source_;
mojo::InterfacePtrInfo<serial::DataSourceClient> source_client_;
scoped_refptr<SerialIoHandler> io_handler_;
DISALLOW_COPY_AND_ASSIGN(ConnectTask);
};
SerialConnectionFactory::SerialConnectionFactory(
const IoHandlerFactory& io_handler_factory,
scoped_refptr<base::SingleThreadTaskRunner> connect_task_runner)
: io_handler_factory_(io_handler_factory),
connect_task_runner_(connect_task_runner) {
}
void SerialConnectionFactory::CreateConnection(
const std::string& path,
serial::ConnectionOptionsPtr options,
mojo::InterfaceRequest<serial::Connection> connection_request,
mojo::InterfaceRequest<serial::DataSink> sink,
mojo::InterfaceRequest<serial::DataSource> source,
mojo::InterfacePtr<serial::DataSourceClient> source_client) {
scoped_refptr<ConnectTask> task(new ConnectTask(
this, path, std::move(options), std::move(connection_request),
std::move(sink), std::move(source), std::move(source_client)));
task->Run();
}
SerialConnectionFactory::~SerialConnectionFactory() {
}
SerialConnectionFactory::ConnectTask::ConnectTask(
scoped_refptr<SerialConnectionFactory> factory,
const std::string& path,
serial::ConnectionOptionsPtr options,
mojo::InterfaceRequest<serial::Connection> connection_request,
mojo::InterfaceRequest<serial::DataSink> sink,
mojo::InterfaceRequest<serial::DataSource> source,
mojo::InterfacePtr<serial::DataSourceClient> source_client)
: factory_(factory),
path_(path),
options_(std::move(options)),
connection_request_(std::move(connection_request)),
sink_(std::move(sink)),
source_(std::move(source)),
source_client_(source_client.PassInterface()) {
if (!options_) {
options_ = serial::ConnectionOptions::New();
}
FillDefaultConnectionOptions(options_.get());
}
void SerialConnectionFactory::ConnectTask::Run() {
factory_->connect_task_runner_->PostTask(
FROM_HERE,
base::Bind(&SerialConnectionFactory::ConnectTask::Connect, this));
}
SerialConnectionFactory::ConnectTask::~ConnectTask() {
}
void SerialConnectionFactory::ConnectTask::Connect() {
io_handler_ = factory_->io_handler_factory_.Run();
io_handler_->Open(
path_, *options_,
base::Bind(&SerialConnectionFactory::ConnectTask::OnConnected, this));
}
void SerialConnectionFactory::ConnectTask::OnConnected(bool success) {
DCHECK(io_handler_.get());
if (!success) {
return;
}
new SerialConnection(io_handler_, std::move(sink_), std::move(source_),
mojo::MakeProxy(std::move(source_client_)),
std::move(connection_request_));
}
} // namespace device