// 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 #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 { public: ConnectTask(scoped_refptr factory, const std::string& path, serial::ConnectionOptionsPtr options, mojo::InterfaceRequest connection_request, mojo::InterfaceRequest sink, mojo::InterfaceRequest source, mojo::InterfacePtr source_client); void Run(); private: friend class base::RefCountedThreadSafe; virtual ~ConnectTask(); void Connect(); void OnConnected(bool success); scoped_refptr factory_; const std::string path_; serial::ConnectionOptionsPtr options_; mojo::InterfaceRequest connection_request_; mojo::InterfaceRequest sink_; mojo::InterfaceRequest source_; mojo::InterfacePtrInfo source_client_; scoped_refptr io_handler_; DISALLOW_COPY_AND_ASSIGN(ConnectTask); }; SerialConnectionFactory::SerialConnectionFactory( const IoHandlerFactory& io_handler_factory, scoped_refptr 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 connection_request, mojo::InterfaceRequest sink, mojo::InterfaceRequest source, mojo::InterfacePtr source_client) { scoped_refptr 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 factory, const std::string& path, serial::ConnectionOptionsPtr options, mojo::InterfaceRequest connection_request, mojo::InterfaceRequest sink, mojo::InterfaceRequest source, mojo::InterfacePtr 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