Upload upstream chromium 69.0.3497
[platform/framework/web/chromium-efl.git] / device / serial / serial_io_handler.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef DEVICE_SERIAL_SERIAL_IO_HANDLER_H_
6 #define DEVICE_SERIAL_SERIAL_IO_HANDLER_H_
7
8 #include <stdint.h>
9
10 #include <memory>
11
12 #include "base/callback.h"
13 #include "base/files/file.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/sequence_checker.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "build/build_config.h"
20 #include "device/serial/buffer.h"
21 #include "services/device/public/mojom/serial.mojom.h"
22
23 namespace device {
24
25 // Provides a simplified interface for performing asynchronous I/O on serial
26 // devices by hiding platform-specific MessageLoop interfaces. Pending I/O
27 // operations hold a reference to this object until completion so that memory
28 // doesn't disappear out from under the OS.
29 class SerialIoHandler : public base::RefCountedThreadSafe<SerialIoHandler> {
30  public:
31   // Constructs an instance of some platform-specific subclass.
32   static scoped_refptr<SerialIoHandler> Create(
33       scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
34
35   typedef base::OnceCallback<void(bool success)> OpenCompleteCallback;
36
37   // Initiates an asynchronous Open of the device.
38   virtual void Open(const std::string& port,
39                     const mojom::SerialConnectionOptions& options,
40                     OpenCompleteCallback callback);
41
42 #if defined(OS_CHROMEOS)
43   // Signals that the port has been opened.
44   void OnPathOpened(
45       scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
46       base::ScopedFD fd);
47
48   // Signals that the permission broker failed to open the port.
49   void OnPathOpenError(
50       scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
51       const std::string& error_name,
52       const std::string& error_message);
53
54   // Reports the open error from the permission broker.
55   void ReportPathOpenError(const std::string& error_name,
56                            const std::string& error_message);
57 #endif  // defined(OS_CHROMEOS)
58
59   // Performs an async Read operation. Behavior is undefined if this is called
60   // while a Read is already pending. Otherwise, the Done or DoneWithError
61   // method on |buffer| will eventually be called with a result.
62   void Read(std::unique_ptr<WritableBuffer> buffer);
63
64   // Performs an async Write operation. Behavior is undefined if this is called
65   // while a Write is already pending. Otherwise, the Done or DoneWithError
66   // method on |buffer| will eventually be called with a result.
67   void Write(std::unique_ptr<ReadOnlyBuffer> buffer);
68
69   // Indicates whether or not a read is currently pending.
70   bool IsReadPending() const;
71
72   // Indicates whether or not a write is currently pending.
73   bool IsWritePending() const;
74
75   // Attempts to cancel a pending read operation.
76   void CancelRead(mojom::SerialReceiveError reason);
77
78   // Attempts to cancel a pending write operation.
79   void CancelWrite(mojom::SerialSendError reason);
80
81   // Flushes input and output buffers.
82   virtual bool Flush() const = 0;
83
84   // Reads current control signals (DCD, CTS, etc.) into an existing
85   // DeviceControlSignals structure. Returns |true| iff the signals were
86   // successfully read.
87   virtual mojom::SerialDeviceControlSignalsPtr GetControlSignals() const = 0;
88
89   // Sets one or more control signals (DTR and/or RTS). Returns |true| iff
90   // the signals were successfully set. Unininitialized flags in the
91   // HostControlSignals structure are left unchanged.
92   virtual bool SetControlSignals(
93       const mojom::SerialHostControlSignals& control_signals) = 0;
94
95   // Performs platform-specific port configuration. Returns |true| iff
96   // configuration was successful.
97   bool ConfigurePort(const mojom::SerialConnectionOptions& options);
98
99   // Performs a platform-specific port configuration query. Fills values in an
100   // existing ConnectionInfo. Returns |true| iff port configuration was
101   // successfully retrieved.
102   virtual mojom::SerialConnectionInfoPtr GetPortInfo() const = 0;
103
104   // Initiates a BREAK signal. Places the transmission line in a break state
105   // until the |ClearBreak| is called.
106   virtual bool SetBreak() = 0;
107
108   // Terminates the BREAK signal. Places the transmission line in a nonbreak
109   // state.
110   virtual bool ClearBreak() = 0;
111
112  protected:
113   explicit SerialIoHandler(
114       scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
115   virtual ~SerialIoHandler();
116
117   // Performs a platform-specific read operation. This must guarantee that
118   // ReadCompleted is called when the underlying async operation is completed
119   // or the SerialIoHandler instance will leak.
120   // NOTE: Implementations of ReadImpl should never call ReadCompleted directly.
121   // Use QueueReadCompleted instead to avoid reentrancy.
122   virtual void ReadImpl() = 0;
123
124   // Performs a platform-specific write operation. This must guarantee that
125   // WriteCompleted is called when the underlying async operation is completed
126   // or the SerialIoHandler instance will leak.
127   // NOTE: Implementations of WriteImpl should never call WriteCompleted
128   // directly. Use QueueWriteCompleted instead to avoid reentrancy.
129   virtual void WriteImpl() = 0;
130
131   // Platform-specific read cancelation.
132   virtual void CancelReadImpl() = 0;
133
134   // Platform-specific write cancelation.
135   virtual void CancelWriteImpl() = 0;
136
137   // Platform-specific port configuration applies options_ to the device.
138   virtual bool ConfigurePortImpl() = 0;
139
140   // Performs platform-specific, one-time port configuration on open.
141   virtual bool PostOpen();
142
143   // Called by the implementation to signal that the active read has completed.
144   // WARNING: Calling this method can destroy the SerialIoHandler instance
145   // if the associated I/O operation was the only thing keeping it alive.
146   void ReadCompleted(int bytes_read, mojom::SerialReceiveError error);
147
148   // Called by the implementation to signal that the active write has completed.
149   // WARNING: Calling this method may destroy the SerialIoHandler instance
150   // if the associated I/O operation was the only thing keeping it alive.
151   void WriteCompleted(int bytes_written, mojom::SerialSendError error);
152
153   // Queues a ReadCompleted call on the current thread. This is used to allow
154   // ReadImpl to immediately signal completion with 0 bytes and an error,
155   // without being reentrant.
156   void QueueReadCompleted(int bytes_read, mojom::SerialReceiveError error);
157
158   // Queues a WriteCompleted call on the current thread. This is used to allow
159   // WriteImpl to immediately signal completion with 0 bytes and an error,
160   // without being reentrant.
161   void QueueWriteCompleted(int bytes_written, mojom::SerialSendError error);
162
163   const base::File& file() const { return file_; }
164
165   char* pending_read_buffer() const {
166     return pending_read_buffer_ ? pending_read_buffer_->GetData() : NULL;
167   }
168
169   uint32_t pending_read_buffer_len() const {
170     return pending_read_buffer_ ? pending_read_buffer_->GetSize() : 0;
171   }
172
173   mojom::SerialReceiveError read_cancel_reason() const {
174     return read_cancel_reason_;
175   }
176
177   bool read_canceled() const { return read_canceled_; }
178
179   const uint8_t* pending_write_buffer() const {
180     return pending_write_buffer_ ? pending_write_buffer_->GetData() : NULL;
181   }
182
183   uint32_t pending_write_buffer_len() const {
184     return pending_write_buffer_ ? pending_write_buffer_->GetSize() : 0;
185   }
186
187   mojom::SerialSendError write_cancel_reason() const {
188     return write_cancel_reason_;
189   }
190
191   bool write_canceled() const { return write_canceled_; }
192
193   const mojom::SerialConnectionOptions& options() const { return options_; }
194
195   // Possibly fixes up a serial port path name in a platform-specific manner.
196   static std::string MaybeFixUpPortName(const std::string& port_name);
197
198   base::SingleThreadTaskRunner* ui_thread_task_runner() const {
199     return ui_thread_task_runner_.get();
200   }
201
202   const std::string& port() const { return port_; }
203
204   SEQUENCE_CHECKER(sequence_checker_);
205
206  private:
207   friend class base::RefCountedThreadSafe<SerialIoHandler>;
208
209   void MergeConnectionOptions(const mojom::SerialConnectionOptions& options);
210
211   // Continues an Open operation on the FILE thread.
212   void StartOpen(const std::string& port,
213                  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
214
215   // Finalizes an Open operation (continued from StartOpen) on the IO thread.
216   void FinishOpen(base::File file);
217
218   void Close();
219
220   // Continues a Close operation on the FILE thread.
221   static void DoClose(base::File port);
222
223   // File for the opened serial device. This value is only modified from the IO
224   // thread.
225   base::File file_;
226
227   // Currently applied connection options.
228   mojom::SerialConnectionOptions options_;
229
230   std::unique_ptr<WritableBuffer> pending_read_buffer_;
231   mojom::SerialReceiveError read_cancel_reason_;
232   bool read_canceled_;
233
234   std::unique_ptr<ReadOnlyBuffer> pending_write_buffer_;
235   mojom::SerialSendError write_cancel_reason_;
236   bool write_canceled_;
237
238   // Callback to handle the completion of a pending Open() request.
239   OpenCompleteCallback open_complete_;
240
241   // On Chrome OS, PermissionBrokerClient should be called on the UI thread.
242   scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_;
243
244   std::string port_;
245
246   DISALLOW_COPY_AND_ASSIGN(SerialIoHandler);
247 };
248
249 }  // namespace device
250
251 #endif  // DEVICE_SERIAL_SERIAL_IO_HANDLER_H_