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