Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: chrome/browser/extensions/api/bluetooth/bluetooth_socket_event_dispatcher.cc

Issue 180163009: chrome.bluetooth API improvements. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix ChromeOS Full build. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "chrome/browser/extensions/api/bluetooth/bluetooth_socket_event_dispatc her.h"
6
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h"
9 #include "chrome/common/extensions/api/bluetooth.h"
10 #include "extensions/browser/event_router.h"
11 #include "extensions/browser/extension_system.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h"
14
15 namespace {
16
17 namespace bluetooth = extensions::api::bluetooth;
18 using extensions::BluetoothApiSocket;
19
20 int kDefaultBufferSize = 4096;
21
22 bluetooth::ReceiveError MapErrorReason(BluetoothApiSocket::ErrorReason value) {
23 switch (value) {
24 case BluetoothApiSocket::kDisconnected:
25 return bluetooth::RECEIVE_ERROR_DISCONNECTED;
26 case BluetoothApiSocket::kIOPending:
27 // kIOPending is not relevant to apps, as BluetoothSocketEventDispatcher
28 // handles this specific error.
29 // fallthrough
30 default:
31 return bluetooth::RECEIVE_ERROR_SYSTEM_ERROR;
32 }
33 }
34
35 } // namespace
36
37 namespace extensions {
38 namespace api {
39
40 using content::BrowserThread;
41
42 BluetoothSocketEventDispatcher::BluetoothSocketEventDispatcher(
43 content::BrowserContext* context,
44 scoped_refptr<SocketData> socket_data)
45 : thread_id_(BluetoothApiSocket::kThreadId),
46 browser_context_id_(context),
47 socket_data_(socket_data) {}
48
49 BluetoothSocketEventDispatcher::~BluetoothSocketEventDispatcher() {}
50
51 BluetoothSocketEventDispatcher::ReceiveParams::ReceiveParams() {}
52
53 BluetoothSocketEventDispatcher::ReceiveParams::~ReceiveParams() {}
54
55 void BluetoothSocketEventDispatcher::OnSocketResume(
56 const std::string& extension_id,
57 int socket_id) {
58 DCHECK(BrowserThread::CurrentlyOn(thread_id_));
59
60 ReceiveParams params;
61 params.extension_id = extension_id;
62 params.socket_id = socket_id;
63 StartReceive(params);
64 }
65
66 void BluetoothSocketEventDispatcher::StartReceive(const ReceiveParams& params) {
67 DCHECK(BrowserThread::CurrentlyOn(thread_id_));
68
69 BluetoothApiSocket* socket =
70 socket_data_->Get(params.extension_id, params.socket_id);
71 if (!socket) {
72 // This can happen if the socket is closed while our callback is active.
73 return;
74 }
75 DCHECK(params.extension_id == socket->owner_extension_id())
76 << "Socket has wrong owner.";
77
78 // Don't start another read if the socket has been paused.
79 if (socket->paused())
80 return;
81
82 int buffer_size = socket->buffer_size();
83 if (buffer_size <= 0)
84 buffer_size = kDefaultBufferSize;
85 socket->Receive(
86 buffer_size,
87 base::Bind(
88 &BluetoothSocketEventDispatcher::ReceiveCallback, this, params),
89 base::Bind(
90 &BluetoothSocketEventDispatcher::ReceiveErrorCallback, this, params));
91 }
92
93 void BluetoothSocketEventDispatcher::ReceiveCallback(
94 const ReceiveParams& params,
95 int bytes_read,
96 scoped_refptr<net::IOBuffer> io_buffer) {
97 DCHECK(BrowserThread::CurrentlyOn(thread_id_));
98
99 // Dispatch "onReceive" event.
100 bluetooth::ReceiveInfo receive_info;
101 receive_info.socket_id = params.socket_id;
102 receive_info.data = std::string(io_buffer->data(), bytes_read);
103 scoped_ptr<base::ListValue> args = bluetooth::OnReceive::Create(receive_info);
104 scoped_ptr<Event> event(
105 new Event(bluetooth::OnReceive::kEventName, args.Pass()));
106 PostEvent(params, event.Pass());
107
108 // Post a task to delay the read until the socket is available, as
109 // calling StartReceive at this point would error with ERR_IO_PENDING.
110 BrowserThread::PostTask(
111 thread_id_,
112 FROM_HERE,
113 base::Bind(&BluetoothSocketEventDispatcher::StartReceive, this, params));
114 }
115
116 void BluetoothSocketEventDispatcher::ReceiveErrorCallback(
117 const ReceiveParams& params,
118 BluetoothApiSocket::ErrorReason error_reason,
119 const std::string& error) {
120 DCHECK(BrowserThread::CurrentlyOn(thread_id_));
121
122 if (error_reason == BluetoothApiSocket::kIOPending) {
123 // This happens when resuming a socket which already had an active "read"
124 // callback. We can safely ignore this error, as the application should not
125 // care.
126 return;
127 }
128
129 // Dispatch "onReceiveError" event but don't start another read to avoid
130 // potential infinite reads if we have a persistent network error.
131 bluetooth::ReceiveErrorInfo receive_error_info;
132 receive_error_info.socket_id = params.socket_id;
133 receive_error_info.error_message = error;
134 receive_error_info.error = MapErrorReason(error_reason);
135 scoped_ptr<base::ListValue> args =
136 bluetooth::OnReceiveError::Create(receive_error_info);
137 scoped_ptr<Event> event(
138 new Event(bluetooth::OnReceiveError::kEventName, args.Pass()));
139 PostEvent(params, event.Pass());
140
141 // Since we got an error, the socket is now "paused" until the application
142 // "resumes" it.
143 BluetoothApiSocket* socket =
144 socket_data_->Get(params.extension_id, params.socket_id);
145 if (socket) {
146 socket->set_paused(true);
147 }
148 }
149
150 void BluetoothSocketEventDispatcher::PostEvent(const ReceiveParams& params,
151 scoped_ptr<Event> event) {
152 DCHECK(BrowserThread::CurrentlyOn(thread_id_));
153
154 BrowserThread::PostTask(
155 BrowserThread::UI,
156 FROM_HERE,
157 base::Bind(&BluetoothSocketEventDispatcher::DispatchEvent,
158 this,
159 params.extension_id,
160 base::Passed(event.Pass())));
161 }
162
163 void BluetoothSocketEventDispatcher::DispatchEvent(
164 const std::string& extension_id,
165 scoped_ptr<Event> event) {
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
167
168 content::BrowserContext* context =
169 reinterpret_cast<content::BrowserContext*>(browser_context_id_);
170 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context))
171 return;
172
173 EventRouter* router = ExtensionSystem::Get(context)->event_router();
174 if (router)
175 router->DispatchEventToExtension(extension_id, event.Pass());
176 }
177
178 } // namespace api
179 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/bluetooth/bluetooth_socket_event_dispatcher.h ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698