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