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 EXTENSIONS_BROWSER_API_BLUETOOTH_SOCKET_BLUETOOTH_SOCKET_EVENT_DISPATCHER_H_
6 #define EXTENSIONS_BROWSER_API_BLUETOOTH_SOCKET_BLUETOOTH_SOCKET_EVENT_DISPATCHER_H_
7 
8 #include "content/public/browser/browser_thread.h"
9 #include "extensions/browser/api/api_resource_manager.h"
10 #include "extensions/browser/api/bluetooth_socket/bluetooth_api_socket.h"
11 #include "extensions/browser/browser_context_keyed_api_factory.h"
12 
13 namespace content {
14 class BrowserContext;
15 }
16 
17 namespace device {
18 class BluetoothDevice;
19 class BluetoothSocket;
20 }
21 
22 namespace extensions {
23 struct Event;
24 class BluetoothApiSocket;
25 }
26 
27 namespace extensions {
28 namespace api {
29 
30 // Dispatch events related to "bluetooth" sockets from callback on native socket
31 // instances. There is one instance per browser context.
32 class BluetoothSocketEventDispatcher
33     : public BrowserContextKeyedAPI,
34       public base::SupportsWeakPtr<BluetoothSocketEventDispatcher> {
35  public:
36   explicit BluetoothSocketEventDispatcher(content::BrowserContext* context);
37   ~BluetoothSocketEventDispatcher() override;
38 
39   // Socket is active, start receiving data from it.
40   void OnSocketConnect(const std::string& extension_id, int socket_id);
41 
42   // Socket is active again, start accepting connections from it.
43   void OnSocketListen(const std::string& extension_id, int socket_id);
44 
45   // Socket is active again, start receiving data from it.
46   void OnSocketResume(const std::string& extension_id, int socket_id);
47 
48   // BrowserContextKeyedAPI implementation.
49   static BrowserContextKeyedAPIFactory<BluetoothSocketEventDispatcher>*
50       GetFactoryInstance();
51 
52   // Convenience method to get the SocketEventDispatcher for a profile.
53   static BluetoothSocketEventDispatcher* Get(content::BrowserContext* context);
54 
55  private:
56   typedef ApiResourceManager<BluetoothApiSocket>::ApiResourceData SocketData;
57   friend class BrowserContextKeyedAPIFactory<BluetoothSocketEventDispatcher>;
58   // BrowserContextKeyedAPI implementation.
service_name()59   static const char* service_name() { return "BluetoothSocketEventDispatcher"; }
60   static const bool kServiceHasOwnInstanceInIncognito = true;
61   static const bool kServiceIsNULLWhileTesting = true;
62 
63   // base::Bind supports methods with up to 6 parameters. SocketParams is used
64   // as a workaround that limitation for invoking StartReceive() and
65   // StartAccept().
66   struct SocketParams {
67     SocketParams();
68     SocketParams(const SocketParams& other);
69     ~SocketParams();
70 
71     content::BrowserThread::ID thread_id;
72     void* browser_context_id;
73     std::string extension_id;
74     scoped_refptr<SocketData> sockets;
75     int socket_id;
76   };
77 
78   // Start a receive and register a callback.
79   static void StartReceive(const SocketParams& params);
80 
81   // Called when socket receive data.
82   static void ReceiveCallback(const SocketParams& params,
83                               int bytes_read,
84                               scoped_refptr<net::IOBuffer> io_buffer);
85 
86   // Called when socket receive data.
87   static void ReceiveErrorCallback(const SocketParams& params,
88                                    BluetoothApiSocket::ErrorReason error_reason,
89                                    const std::string& error);
90 
91   // Start an accept and register a callback.
92   static void StartAccept(const SocketParams& params);
93 
94   // Called when socket accepts a client connection.
95   static void AcceptCallback(const SocketParams& params,
96                              const device::BluetoothDevice* device,
97                              scoped_refptr<device::BluetoothSocket> socket);
98 
99   // Called when socket encounters an error while accepting a client connection.
100   static void AcceptErrorCallback(const SocketParams& params,
101                                   BluetoothApiSocket::ErrorReason error_reason,
102                                   const std::string& error);
103 
104   // Post an extension event from IO to UI thread
105   static void PostEvent(const SocketParams& params,
106                         std::unique_ptr<Event> event);
107 
108   // Dispatch an extension event on to EventRouter instance on UI thread.
109   static void DispatchEvent(void* browser_context_id,
110                             const std::string& extension_id,
111                             std::unique_ptr<Event> event);
112 
113   // Usually FILE thread (except for unit testing).
114   content::BrowserThread::ID thread_id_;
115   content::BrowserContext* const browser_context_;
116   scoped_refptr<SocketData> sockets_;
117 };
118 
119 }  // namespace api
120 }  // namespace extensions
121 
122 #endif  // EXTENSIONS_BROWSER_API_BLUETOOTH_SOCKET_BLUETOOTH_SOCKET_EVENT_DISPATCHER_H_
123