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   static SerialPortManager* Get(content::BrowserContext* context);
36 
37   // BrowserContextKeyedAPI implementation.
38   static BrowserContextKeyedAPIFactory<SerialPortManager>* GetFactoryInstance();
39 
40   explicit SerialPortManager(content::BrowserContext* context);
41   ~SerialPortManager() override;
42 
43   void GetDevices(
44       device::mojom::SerialPortManager::GetDevicesCallback callback);
45 
46   void GetPort(const std::string& path,
47                mojo::PendingReceiver<device::mojom::SerialPort> receiver);
48 
49   // Start the poilling process for the connection.
50   void StartConnectionPolling(const std::string& extension_id,
51                               int connection_id);
52 
53   // Allows tests to override how this class binds SerialPortManager receivers.
54   using Binder = base::RepeatingCallback<void(
55       mojo::PendingReceiver<device::mojom::SerialPortManager>)>;
56   static void OverrideBinderForTesting(Binder binder);
57 
58  private:
59   typedef ApiResourceManager<SerialConnection>::ApiResourceData ConnectionData;
60   friend class BrowserContextKeyedAPIFactory<SerialPortManager>;
61 
62   // BrowserContextKeyedAPI implementation.
service_name()63   static const char* service_name() { return "SerialPortManager"; }
64   static const bool kServiceHasOwnInstanceInIncognito = true;
65   static const bool kServiceIsNULLWhileTesting = true;
66 
67   struct ReceiveParams {
68     ReceiveParams();
69     ReceiveParams(const ReceiveParams& other);
70     ~ReceiveParams();
71 
72     void* browser_context_id;
73     std::string extension_id;
74     scoped_refptr<ConnectionData> connections;
75     int connection_id;
76   };
77   static void DispatchReceiveEvent(const ReceiveParams& params,
78                                    std::vector<uint8_t> data,
79                                    serial::ReceiveError error);
80 
81   static void DispatchEvent(const ReceiveParams& params,
82                             std::unique_ptr<extensions::Event> event);
83 
84   void EnsureConnection();
85   void OnGotDevicesToGetPort(
86       const std::string& path,
87       mojo::PendingReceiver<device::mojom::SerialPort> receiver,
88       std::vector<device::mojom::SerialPortInfoPtr> devices);
89   void OnPortManagerConnectionError();
90 
91   mojo::Remote<device::mojom::SerialPortManager> port_manager_;
92   content::BrowserThread::ID thread_id_;
93   scoped_refptr<ConnectionData> connections_;
94   content::BrowserContext* const context_;
95 
96   THREAD_CHECKER(thread_checker_);
97   base::WeakPtrFactory<SerialPortManager> weak_factory_{this};
98 
99   DISALLOW_COPY_AND_ASSIGN(SerialPortManager);
100 };
101 
102 }  // namespace api
103 
104 }  // namespace extensions
105 
106 #endif  // EXTENSIONS_BROWSER_API_SERIAL_SERIAL_PORT_MANAGER_H_
107