OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/sockets_tcp_server/tcp_server_socket_eve
nt_dispatcher.h" | 5 #include "extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_disp
atcher.h" |
6 | 6 |
7 #include "chrome/browser/extensions/api/socket/tcp_socket.h" | 7 #include "extensions/browser/api/socket/tcp_socket.h" |
8 #include "extensions/browser/event_router.h" | 8 #include "extensions/browser/event_router.h" |
9 #include "extensions/browser/extension_system.h" | 9 #include "extensions/browser/extension_system.h" |
10 #include "extensions/browser/extensions_browser_client.h" | 10 #include "extensions/browser/extensions_browser_client.h" |
11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
12 | 12 |
13 namespace extensions { | 13 namespace extensions { |
14 namespace api { | 14 namespace core_api { |
15 | 15 |
16 using content::BrowserThread; | 16 using content::BrowserThread; |
17 | 17 |
18 static base::LazyInstance< | 18 static base::LazyInstance< |
19 BrowserContextKeyedAPIFactory<TCPServerSocketEventDispatcher> > g_factory = | 19 BrowserContextKeyedAPIFactory<TCPServerSocketEventDispatcher> > g_factory = |
20 LAZY_INSTANCE_INITIALIZER; | 20 LAZY_INSTANCE_INITIALIZER; |
21 | 21 |
22 // static | 22 // static |
23 BrowserContextKeyedAPIFactory<TCPServerSocketEventDispatcher>* | 23 BrowserContextKeyedAPIFactory<TCPServerSocketEventDispatcher>* |
24 TCPServerSocketEventDispatcher::GetFactoryInstance() { | 24 TCPServerSocketEventDispatcher::GetFactoryInstance() { |
25 return g_factory.Pointer(); | 25 return g_factory.Pointer(); |
26 } | 26 } |
27 | 27 |
28 // static | 28 // static |
29 TCPServerSocketEventDispatcher* TCPServerSocketEventDispatcher::Get( | 29 TCPServerSocketEventDispatcher* TCPServerSocketEventDispatcher::Get( |
30 content::BrowserContext* context) { | 30 content::BrowserContext* context) { |
31 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 31 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
32 | 32 |
33 return BrowserContextKeyedAPIFactory<TCPServerSocketEventDispatcher>::Get( | 33 return BrowserContextKeyedAPIFactory<TCPServerSocketEventDispatcher>::Get( |
34 context); | 34 context); |
35 } | 35 } |
36 | 36 |
37 TCPServerSocketEventDispatcher::TCPServerSocketEventDispatcher( | 37 TCPServerSocketEventDispatcher::TCPServerSocketEventDispatcher( |
38 content::BrowserContext* context) | 38 content::BrowserContext* context) |
39 : thread_id_(Socket::kThreadId), browser_context_(context) { | 39 : thread_id_(Socket::kThreadId), browser_context_(context) { |
40 ApiResourceManager<ResumableTCPServerSocket>* server_manager = | 40 ApiResourceManager<ResumableTCPServerSocket>* server_manager = |
41 ApiResourceManager<ResumableTCPServerSocket>::Get(browser_context_); | 41 ApiResourceManager<ResumableTCPServerSocket>::Get(browser_context_); |
42 DCHECK(server_manager) << "There is no server socket manager. " | 42 DCHECK(server_manager) |
43 "If this assertion is failing during a test, then it is likely that " | 43 << "There is no server socket manager. " |
44 "TestExtensionSystem is failing to provide an instance of " | 44 "If this assertion is failing during a test, then it is likely that " |
45 "ApiResourceManager<ResumableTCPServerSocket>."; | 45 "TestExtensionSystem is failing to provide an instance of " |
| 46 "ApiResourceManager<ResumableTCPServerSocket>."; |
46 server_sockets_ = server_manager->data_; | 47 server_sockets_ = server_manager->data_; |
47 | 48 |
48 ApiResourceManager<ResumableTCPSocket>* client_manager = | 49 ApiResourceManager<ResumableTCPSocket>* client_manager = |
49 ApiResourceManager<ResumableTCPSocket>::Get(browser_context_); | 50 ApiResourceManager<ResumableTCPSocket>::Get(browser_context_); |
50 DCHECK(client_manager) << "There is no client socket manager. " | 51 DCHECK(client_manager) |
51 "If this assertion is failing during a test, then it is likely that " | 52 << "There is no client socket manager. " |
52 "TestExtensionSystem is failing to provide an instance of " | 53 "If this assertion is failing during a test, then it is likely that " |
53 "ApiResourceManager<ResumableTCPSocket>."; | 54 "TestExtensionSystem is failing to provide an instance of " |
| 55 "ApiResourceManager<ResumableTCPSocket>."; |
54 client_sockets_ = client_manager->data_; | 56 client_sockets_ = client_manager->data_; |
55 } | 57 } |
56 | 58 |
57 TCPServerSocketEventDispatcher::~TCPServerSocketEventDispatcher() {} | 59 TCPServerSocketEventDispatcher::~TCPServerSocketEventDispatcher() {} |
58 | 60 |
59 TCPServerSocketEventDispatcher::AcceptParams::AcceptParams() {} | 61 TCPServerSocketEventDispatcher::AcceptParams::AcceptParams() {} |
60 | 62 |
61 TCPServerSocketEventDispatcher::AcceptParams::~AcceptParams() {} | 63 TCPServerSocketEventDispatcher::AcceptParams::~AcceptParams() {} |
62 | 64 |
63 void TCPServerSocketEventDispatcher::OnServerSocketListen( | 65 void TCPServerSocketEventDispatcher::OnServerSocketListen( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 void TCPServerSocketEventDispatcher::StartAccept(const AcceptParams& params) { | 98 void TCPServerSocketEventDispatcher::StartAccept(const AcceptParams& params) { |
97 DCHECK(BrowserThread::CurrentlyOn(params.thread_id)); | 99 DCHECK(BrowserThread::CurrentlyOn(params.thread_id)); |
98 | 100 |
99 ResumableTCPServerSocket* socket = | 101 ResumableTCPServerSocket* socket = |
100 params.server_sockets->Get(params.extension_id, params.socket_id); | 102 params.server_sockets->Get(params.extension_id, params.socket_id); |
101 if (!socket) { | 103 if (!socket) { |
102 // This can happen if the socket is closed while our callback is active. | 104 // This can happen if the socket is closed while our callback is active. |
103 return; | 105 return; |
104 } | 106 } |
105 DCHECK(params.extension_id == socket->owner_extension_id()) | 107 DCHECK(params.extension_id == socket->owner_extension_id()) |
106 << "Socket has wrong owner."; | 108 << "Socket has wrong owner."; |
107 | 109 |
108 // Don't start another accept if the socket has been paused. | 110 // Don't start another accept if the socket has been paused. |
109 if (socket->paused()) | 111 if (socket->paused()) |
110 return; | 112 return; |
111 | 113 |
112 socket->Accept(base::Bind(&TCPServerSocketEventDispatcher::AcceptCallback, | 114 socket->Accept( |
113 params)); | 115 base::Bind(&TCPServerSocketEventDispatcher::AcceptCallback, params)); |
114 } | 116 } |
115 | 117 |
116 // static | 118 // static |
117 void TCPServerSocketEventDispatcher::AcceptCallback( | 119 void TCPServerSocketEventDispatcher::AcceptCallback( |
118 const AcceptParams& params, | 120 const AcceptParams& params, |
119 int result_code, | 121 int result_code, |
120 net::TCPClientSocket *socket) { | 122 net::TCPClientSocket* socket) { |
121 DCHECK(BrowserThread::CurrentlyOn(params.thread_id)); | 123 DCHECK(BrowserThread::CurrentlyOn(params.thread_id)); |
122 | 124 |
123 if (result_code >= 0) { | 125 if (result_code >= 0) { |
124 ResumableTCPSocket *client_socket = | 126 ResumableTCPSocket* client_socket = |
125 new ResumableTCPSocket(socket, params.extension_id, true); | 127 new ResumableTCPSocket(socket, params.extension_id, true); |
126 client_socket->set_paused(true); | 128 client_socket->set_paused(true); |
127 int client_socket_id = params.client_sockets->Add(client_socket); | 129 int client_socket_id = params.client_sockets->Add(client_socket); |
128 | 130 |
129 // Dispatch "onAccept" event. | 131 // Dispatch "onAccept" event. |
130 sockets_tcp_server::AcceptInfo accept_info; | 132 sockets_tcp_server::AcceptInfo accept_info; |
131 accept_info.socket_id = params.socket_id; | 133 accept_info.socket_id = params.socket_id; |
132 accept_info.client_socket_id = client_socket_id; | 134 accept_info.client_socket_id = client_socket_id; |
133 scoped_ptr<base::ListValue> args = | 135 scoped_ptr<base::ListValue> args = |
134 sockets_tcp_server::OnAccept::Create(accept_info); | 136 sockets_tcp_server::OnAccept::Create(accept_info); |
135 scoped_ptr<Event> event( | 137 scoped_ptr<Event> event( |
136 new Event(sockets_tcp_server::OnAccept::kEventName, args.Pass())); | 138 new Event(sockets_tcp_server::OnAccept::kEventName, args.Pass())); |
137 PostEvent(params, event.Pass()); | 139 PostEvent(params, event.Pass()); |
138 | 140 |
139 // Post a task to delay the "accept" until the socket is available, as | 141 // Post a task to delay the "accept" until the socket is available, as |
140 // calling StartAccept at this point would error with ERR_IO_PENDING. | 142 // calling StartAccept at this point would error with ERR_IO_PENDING. |
141 BrowserThread::PostTask( | 143 BrowserThread::PostTask( |
142 params.thread_id, FROM_HERE, | 144 params.thread_id, |
| 145 FROM_HERE, |
143 base::Bind(&TCPServerSocketEventDispatcher::StartAccept, params)); | 146 base::Bind(&TCPServerSocketEventDispatcher::StartAccept, params)); |
144 } else { | 147 } else { |
145 // Dispatch "onAcceptError" event but don't start another accept to avoid | 148 // Dispatch "onAcceptError" event but don't start another accept to avoid |
146 // potential infinite "accepts" if we have a persistent network error. | 149 // potential infinite "accepts" if we have a persistent network error. |
147 sockets_tcp_server::AcceptErrorInfo accept_error_info; | 150 sockets_tcp_server::AcceptErrorInfo accept_error_info; |
148 accept_error_info.socket_id = params.socket_id; | 151 accept_error_info.socket_id = params.socket_id; |
149 accept_error_info.result_code = result_code; | 152 accept_error_info.result_code = result_code; |
150 scoped_ptr<base::ListValue> args = | 153 scoped_ptr<base::ListValue> args = |
151 sockets_tcp_server::OnAcceptError::Create(accept_error_info); | 154 sockets_tcp_server::OnAcceptError::Create(accept_error_info); |
152 scoped_ptr<Event> event( | 155 scoped_ptr<Event> event( |
153 new Event(sockets_tcp_server::OnAcceptError::kEventName, args.Pass())); | 156 new Event(sockets_tcp_server::OnAcceptError::kEventName, args.Pass())); |
154 PostEvent(params, event.Pass()); | 157 PostEvent(params, event.Pass()); |
155 | 158 |
156 // Since we got an error, the socket is now "paused" until the application | 159 // Since we got an error, the socket is now "paused" until the application |
157 // "resumes" it. | 160 // "resumes" it. |
158 ResumableTCPServerSocket* socket = | 161 ResumableTCPServerSocket* socket = |
159 params.server_sockets->Get(params.extension_id, params.socket_id); | 162 params.server_sockets->Get(params.extension_id, params.socket_id); |
160 if (socket) { | 163 if (socket) { |
161 socket->set_paused(true); | 164 socket->set_paused(true); |
162 } | 165 } |
163 } | 166 } |
(...skipping 21 matching lines...) Expand all Loading... |
185 | 188 |
186 content::BrowserContext* context = | 189 content::BrowserContext* context = |
187 reinterpret_cast<content::BrowserContext*>(browser_context_id); | 190 reinterpret_cast<content::BrowserContext*>(browser_context_id); |
188 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) | 191 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) |
189 return; | 192 return; |
190 EventRouter* router = ExtensionSystem::Get(context)->event_router(); | 193 EventRouter* router = ExtensionSystem::Get(context)->event_router(); |
191 if (router) | 194 if (router) |
192 router->DispatchEventToExtension(extension_id, event.Pass()); | 195 router->DispatchEventToExtension(extension_id, event.Pass()); |
193 } | 196 } |
194 | 197 |
195 } // namespace api | 198 } // namespace core_api |
196 } // namespace extensions | 199 } // namespace extensions |
OLD | NEW |