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_SOCKETS_UDP_UDP_SOCKET_EVENT_DISPATCHER_H_
6 #define EXTENSIONS_BROWSER_API_SOCKETS_UDP_UDP_SOCKET_EVENT_DISPATCHER_H_
7 
8 #include <stdint.h>
9 
10 #include <string>
11 
12 #include "content/public/browser/browser_thread.h"
13 #include "extensions/browser/api/api_resource_manager.h"
14 #include "extensions/browser/api/sockets_udp/sockets_udp_api.h"
15 
16 namespace content {
17 class BrowserContext;
18 }
19 
20 namespace extensions {
21 struct Event;
22 class ResumableUDPSocket;
23 }
24 
25 namespace extensions {
26 namespace api {
27 
28 // Dispatch events related to "sockets.udp" sockets from callback on native
29 // socket instances. There is one instance per profile.
30 class UDPSocketEventDispatcher
31     : public BrowserContextKeyedAPI,
32       public base::SupportsWeakPtr<UDPSocketEventDispatcher> {
33  public:
34   explicit UDPSocketEventDispatcher(content::BrowserContext* context);
35   ~UDPSocketEventDispatcher() override;
36 
37   // Socket is active, start receving from it.
38   void OnSocketBind(const std::string& extension_id, int socket_id);
39 
40   // Socket is active again, start receiving data from it.
41   void OnSocketResume(const std::string& extension_id, int socket_id);
42 
43   // BrowserContextKeyedAPI implementation.
44   static BrowserContextKeyedAPIFactory<UDPSocketEventDispatcher>*
45       GetFactoryInstance();
46 
47   // Convenience method to get the SocketEventDispatcher for a profile.
48   static UDPSocketEventDispatcher* Get(content::BrowserContext* context);
49 
50  private:
51   typedef ApiResourceManager<ResumableUDPSocket>::ApiResourceData SocketData;
52   friend class BrowserContextKeyedAPIFactory<UDPSocketEventDispatcher>;
53   // BrowserContextKeyedAPI implementation.
service_name()54   static const char* service_name() { return "UDPSocketEventDispatcher"; }
55   static const bool kServiceHasOwnInstanceInIncognito = true;
56   static const bool kServiceIsNULLWhileTesting = true;
57 
58   // base::Bind supports methods with up to 6 parameters. ReceiveParams is used
59   // as a workaround that limitation for invoking StartReceive.
60   struct ReceiveParams {
61     ReceiveParams();
62     ReceiveParams(const ReceiveParams& other);
63     ~ReceiveParams();
64 
65     content::BrowserThread::ID thread_id;
66     void* browser_context_id;
67     std::string extension_id;
68     scoped_refptr<SocketData> sockets;
69     int socket_id;
70   };
71 
72   // Start a receive and register a callback.
73   static void StartReceive(const ReceiveParams& params);
74 
75   // Called when socket receive data.
76   static void ReceiveCallback(const ReceiveParams& params,
77                               int bytes_read,
78                               scoped_refptr<net::IOBuffer> io_buffer,
79                               bool socket_destroying,
80                               const std::string& address,
81                               uint16_t port);
82 
83   // Post an extension event from IO to UI thread
84   static void PostEvent(const ReceiveParams& params,
85                         std::unique_ptr<Event> event);
86 
87   // Dispatch an extension event on to EventRouter instance on UI thread.
88   static void DispatchEvent(void* browser_context_id,
89                             const std::string& extension_id,
90                             std::unique_ptr<Event> event);
91 
92   // Usually IO thread (except for unit testing).
93   content::BrowserThread::ID thread_id_;
94   content::BrowserContext* const browser_context_;
95   scoped_refptr<SocketData> sockets_;
96 };
97 
98 }  // namespace api
99 }  // namespace extensions
100 
101 #endif  // EXTENSIONS_BROWSER_API_SOCKETS_UDP_UDP_SOCKET_EVENT_DISPATCHER_H_
102