1 // Copyright 2018 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 EXTENSIONS_BROWSER_API_SERIAL_SERIAL_PORT_MANAGER_H_
6 #define EXTENSIONS_BROWSER_API_SERIAL_SERIAL_PORT_MANAGER_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/callback.h"
13 #include "base/threading/thread_checker.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "extensions/browser/api/api_resource_manager.h"
16 #include "extensions/browser/browser_context_keyed_api_factory.h"
17 #include "extensions/common/api/serial.h"
18 #include "mojo/public/cpp/bindings/pending_receiver.h"
19 #include "mojo/public/cpp/bindings/remote.h"
20 #include "services/device/public/mojom/serial.mojom.h"
21 
22 namespace content {
23 class BrowserContext;
24 }
25 
26 namespace extensions {
27 
28 struct Event;
29 class SerialConnection;
30 
31 namespace api {
32 // Per-browser-context dispatcher for events on serial connections.
33 class SerialPortManager : public BrowserContextKeyedAPI {
34  public:
35   using OpenPortCallback =
36       base::OnceCallback<void(mojo::PendingRemote<device::mojom::SerialPort>)>;
37 
38   static SerialPortManager* Get(content::BrowserContext* context);
39 
40   // BrowserContextKeyedAPI implementation.
41   static BrowserContextKeyedAPIFactory<SerialPortManager>* GetFactoryInstance();
42 
43   explicit SerialPortManager(content::BrowserContext* context);
44   ~SerialPortManager() override;
45 
46   void GetDevices(
47       device::mojom::SerialPortManager::GetDevicesCallback callback);
48   void OpenPort(const std::string& path,
49                 device::mojom::SerialConnectionOptionsPtr options,
50                 mojo::PendingRemote<device::mojom::SerialPortClient> client,
51                 OpenPortCallback callback);
52 
53   // Start the poilling process for the connection.
54   void StartConnectionPolling(const std::string& extension_id,
55                               int connection_id);
56 
57   // Allows tests to override how this class binds SerialPortManager receivers.
58   using Binder = base::RepeatingCallback<void(
59       mojo::PendingReceiver<device::mojom::SerialPortManager>)>;
60   static void OverrideBinderForTesting(Binder binder);
61 
62  private:
63   typedef ApiResourceManager<SerialConnection>::ApiResourceData ConnectionData;
64   friend class BrowserContextKeyedAPIFactory<SerialPortManager>;
65 
66   // BrowserContextKeyedAPI implementation.
service_name()67   static const char* service_name() { return "SerialPortManager"; }
68   static const bool kServiceHasOwnInstanceInIncognito = true;
69   static const bool kServiceIsNULLWhileTesting = true;
70 
71   struct ReceiveParams {
72     ReceiveParams();
73     ReceiveParams(const ReceiveParams& other);
74     ~ReceiveParams();
75 
76     void* browser_context_id;
77     std::string extension_id;
78     scoped_refptr<ConnectionData> connections;
79     int connection_id;
80   };
81   static void DispatchReceiveEvent(const ReceiveParams& params,
82                                    std::vector<uint8_t> data,
83                                    serial::ReceiveError error);
84 
85   static void DispatchEvent(const ReceiveParams& params,
86                             std::unique_ptr<extensions::Event> event);
87 
88   void EnsureConnection();
89   void OnGotDevicesToGetPort(
90       const std::string& path,
91       device::mojom::SerialConnectionOptionsPtr options,
92       mojo::PendingRemote<device::mojom::SerialPortClient> client,
93       OpenPortCallback callback,
94       std::vector<device::mojom::SerialPortInfoPtr> devices);
95   void OnPortManagerConnectionError();
96 
97   mojo::Remote<device::mojom::SerialPortManager> port_manager_;
98   content::BrowserThread::ID thread_id_;
99   scoped_refptr<ConnectionData> connections_;
100   content::BrowserContext* const context_;
101 
102   THREAD_CHECKER(thread_checker_);
103   base::WeakPtrFactory<SerialPortManager> weak_factory_{this};
104 
105   DISALLOW_COPY_AND_ASSIGN(SerialPortManager);
106 };
107 
108 }  // namespace api
109 
110 }  // namespace extensions
111 
112 #endif  // EXTENSIONS_BROWSER_API_SERIAL_SERIAL_PORT_MANAGER_H_
113