// 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 "base/bind.h" #include "base/location.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::DATA_BITS_NONE) options->data_bits = serial::DATA_BITS_EIGHT; if (options->stop_bits == serial::STOP_BITS_NONE) options->stop_bits = serial::STOP_BITS_ONE; if (options->parity_bit == serial::PARITY_BIT_NONE) options->parity_bit = serial::PARITY_BIT_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::InterfacePtr 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, options.Pass(), connection_request.Pass(), sink.Pass(), source.Pass(), source_client.Pass())); 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_(options.Pass()), connection_request_(connection_request.Pass()), sink_(sink.Pass()), source_(source.Pass()), source_client_(source_client.Pass()) { 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_, sink_.Pass(), source_.Pass(), source_client_.Pass(), connection_request_.Pass()); } } // namespace device