103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef DEVICE_SERIAL_DATA_SINK_RECEIVER_H_
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define DEVICE_SERIAL_DATA_SINK_RECEIVER_H_
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <queue>
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/callback.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/linked_ptr.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/ref_counted.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/weak_ptr.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/serial/buffer.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/serial/data_stream.mojom.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "mojo/public/cpp/system/data_pipe.h"
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace device {
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class AsyncWaiter;
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class DataSinkReceiver : public base::RefCounted<DataSinkReceiver>,
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         public mojo::InterfaceImpl<serial::DataSink> {
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void(scoped_ptr<ReadOnlyBuffer>)> ReadyCallback;
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void(int32_t error)> CancelCallback;
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void()> ErrorCallback;
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Constructs a DataSinkReceiver. Whenever the pipe is ready for reading, the
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |ready_callback| will be called with the ReadOnlyBuffer to read.
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |ready_callback| will not be called again until the previous ReadOnlyBuffer
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // is destroyed. If a connection error occurs, |error_callback| will be called
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // and the DataSinkReceiver will act as if ShutDown() had been called. If
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |cancel_callback| is valid, it will be called when the DataSinkClient
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // requests cancellation of the in-progress read.
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DataSinkReceiver(const ReadyCallback& ready_callback,
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   const CancelCallback& cancel_callback,
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   const ErrorCallback& error_callback);
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Shuts down this DataSinkReceiver. After shut down, |ready_callback|,
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |cancel_callback| and |error_callback| will never be called.
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ShutDown();
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  class Buffer;
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  class PendingFlush;
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  friend class base::RefCounted<DataSinkReceiver>;
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual ~DataSinkReceiver();
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // mojo::InterfaceImpl<serial::DataSink> overrides.
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void Init(mojo::ScopedDataPipeConsumerHandle handle) OVERRIDE;
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void Cancel(int32_t error) OVERRIDE;
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnConnectionError() OVERRIDE;
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Starts waiting for |handle_| to be ready for reads.
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void StartWaiting();
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Invoked when |handle_| is ready for reads.
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void OnDoneWaiting(MojoResult result);
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Reports a successful read of |bytes_read|.
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void Done(uint32_t bytes_read);
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Reports a partially successful or unsuccessful read of |bytes_read|
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // with an error of |error|.
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void DoneWithError(uint32_t bytes_read, int32_t error);
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Finishes the two-phase data pipe read.
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool DoneInternal(uint32_t bytes_read);
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Sends an ReportBytesSentAndError message to the client.
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ReportBytesSentAndError(uint32_t bytes_read, int32_t error);
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Invoked in response to an ReportBytesSentAndError call to the client with
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // the number of bytes to flush.
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void SetNumBytesToFlush(uint32_t bytes_to_flush);
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Reports a fatal error to the client and shuts down.
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void DispatchFatalError();
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The data connection to the data sender.
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::ScopedDataPipeConsumerHandle handle_;
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The callback to call when |handle_| has data ready to read.
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ReadyCallback ready_callback_;
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The callback to call when the client has requested cancellation.
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const CancelCallback cancel_callback_;
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The callback to call if a fatal error occurs.
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ErrorCallback error_callback_;
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The queue of pending flushes.
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::queue<linked_ptr<PendingFlush> > pending_flushes_;
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // A waiter used to wait until |handle_| is readable if we are waiting.
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<AsyncWaiter> waiter_;
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The buffer passed to |ready_callback_| if one exists. This is not owned,
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // but the Buffer will call Done or DoneWithError before being deleted.
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Buffer* buffer_in_use_;
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Whether we have encountered a fatal error and shut down.
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool shut_down_;
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::WeakPtrFactory<DataSinkReceiver> weak_factory_;
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DataSinkReceiver);
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace device
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif  // DEVICE_SERIAL_DATA_SINK_RECEIVER_H_
115