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

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

Issue 180163009: chrome.bluetooth API improvements. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix threading ownership related to ApiResourceManager<BluetoothApiSocket> and BluetoothSocketEventD… Created 6 years, 9 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/bluetooth/bluetooth_api.h" 5 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" 11 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h"
12 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" 12 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h"
13 #include "chrome/browser/extensions/api/bluetooth/bluetooth_socket_event_dispatc her.h"
13 #include "chrome/browser/extensions/event_names.h" 14 #include "chrome/browser/extensions/event_names.h"
15 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/common/extensions/api/bluetooth.h" 16 #include "chrome/common/extensions/api/bluetooth.h"
15 #include "chrome/common/extensions/api/bluetooth/bluetooth_manifest_data.h" 17 #include "chrome/common/extensions/api/bluetooth/bluetooth_manifest_data.h"
16 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
17 #include "device/bluetooth/bluetooth_adapter.h" 19 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_device.h" 20 #include "device/bluetooth/bluetooth_device.h"
19 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" 21 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h"
20 #include "device/bluetooth/bluetooth_profile.h" 22 #include "device/bluetooth/bluetooth_profile.h"
21 #include "device/bluetooth/bluetooth_service_record.h" 23 #include "device/bluetooth/bluetooth_service_record.h"
22 #include "device/bluetooth/bluetooth_socket.h" 24 #include "device/bluetooth/bluetooth_socket.h"
23 #include "device/bluetooth/bluetooth_utils.h" 25 #include "device/bluetooth/bluetooth_utils.h"
24 #include "extensions/browser/event_router.h" 26 #include "extensions/browser/event_router.h"
25 #include "extensions/browser/extension_system.h" 27 #include "extensions/browser/extension_system.h"
26 #include "extensions/common/permissions/permissions_data.h" 28 #include "extensions/common/permissions/permissions_data.h"
27 #include "net/base/io_buffer.h" 29 #include "net/base/io_buffer.h"
28 30
29 using content::BrowserContext; 31 using content::BrowserContext;
32 using content::BrowserThread;
33
30 using device::BluetoothAdapter; 34 using device::BluetoothAdapter;
31 using device::BluetoothDevice; 35 using device::BluetoothDevice;
32 using device::BluetoothProfile; 36 using device::BluetoothProfile;
33 using device::BluetoothServiceRecord; 37 using device::BluetoothServiceRecord;
34 using device::BluetoothSocket; 38 using device::BluetoothSocket;
35 39
36 namespace { 40 using extensions::BluetoothApiSocket;
37 41
38 extensions::ExtensionBluetoothEventRouter* GetEventRouter( 42 namespace AddProfile = extensions::api::bluetooth::AddProfile;
39 BrowserContext* context) { 43 namespace bluetooth = extensions::api::bluetooth;
40 return extensions::BluetoothAPI::Get(context)->bluetooth_event_router(); 44 namespace Connect = extensions::api::bluetooth::Connect;
41 } 45 namespace Disconnect = extensions::api::bluetooth::Disconnect;
42 46 namespace GetDevices = extensions::api::bluetooth::GetDevices;
43 } // namespace 47 namespace GetProfiles = extensions::api::bluetooth::GetProfiles;
48 namespace RemoveProfile = extensions::api::bluetooth::RemoveProfile;
49 namespace SetOutOfBandPairingData =
50 extensions::api::bluetooth::SetOutOfBandPairingData;
51 namespace Send = extensions::api::bluetooth::Send;
44 52
45 namespace { 53 namespace {
46 54
47 const char kCouldNotGetLocalOutOfBandPairingData[] = 55 const char kCouldNotGetLocalOutOfBandPairingData[] =
48 "Could not get local Out Of Band Pairing Data"; 56 "Could not get local Out Of Band Pairing Data";
49 const char kCouldNotSetOutOfBandPairingData[] =
50 "Could not set Out Of Band Pairing Data";
51 const char kFailedToConnect[] = "Connection failed";
52 const char kInvalidDevice[] = "Invalid device"; 57 const char kInvalidDevice[] = "Invalid device";
53 const char kInvalidUuid[] = "Invalid UUID"; 58 const char kInvalidUuid[] = "Invalid UUID";
54 const char kPermissionDenied[] = "Permission to add profile denied."; 59 const char kPermissionDenied[] = "Permission to add profile denied.";
55 const char kProfileAlreadyRegistered[] = 60 const char kProfileAlreadyRegistered[] =
56 "This profile has already been registered"; 61 "This profile has already been registered";
57 const char kProfileNotFound[] = "Profile not found: invalid uuid"; 62 const char kProfileNotFound[] = "Profile not found: invalid uuid";
58 const char kProfileRegistrationFailed[] = "Profile registration failed"; 63 const char kProfileRegistrationFailed[] = "Profile registration failed";
59 const char kServiceDiscoveryFailed[] = "Service discovery failed";
60 const char kSocketNotFoundError[] = "Socket not found: invalid socket id"; 64 const char kSocketNotFoundError[] = "Socket not found: invalid socket id";
61 const char kStartDiscoveryFailed[] = "Starting discovery failed"; 65 const char kStartDiscoveryFailed[] = "Starting discovery failed";
62 const char kStopDiscoveryFailed[] = "Failed to stop discovery"; 66 const char kStopDiscoveryFailed[] = "Failed to stop discovery";
63 67
68 extensions::ExtensionBluetoothEventRouter* GetEventRouter(
69 BrowserContext* context) {
70 // Note: |context| is valid on UI thread only.
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72 return extensions::BluetoothAPI::Get(context)->event_router();
73 }
74
75 linked_ptr<bluetooth::Socket> CreateSocketInfo(int socket_id,
76 BluetoothApiSocket* socket) {
77 DCHECK(BrowserThread::CurrentlyOn(BluetoothApiSocket::kThreadId));
78 linked_ptr<bluetooth::Socket> socket_info(new bluetooth::Socket());
79 // This represents what we know about the socket, and does not call through
80 // to the system.
81 socket_info->id = socket_id;
82 if (!socket->name().empty()) {
83 socket_info->name.reset(new std::string(socket->name()));
84 }
85 socket_info->persistent = socket->persistent();
86 if (socket->buffer_size() > 0) {
87 socket_info->buffer_size.reset(new int(socket->buffer_size()));
88 }
89 socket_info->paused = socket->paused();
90 socket_info->device.address = socket->device_address();
91 socket_info->profile.uuid = socket->profile_uuid();
92
93 return socket_info;
94 }
95
96 void SetSocketProperties(extensions::BluetoothApiSocket* socket,
97 bluetooth::SocketProperties* properties) {
98 if (properties->name.get()) {
99 socket->set_name(*properties->name.get());
100 }
101 if (properties->persistent.get()) {
102 socket->set_persistent(*properties->persistent.get());
103 }
104 if (properties->buffer_size.get()) {
105 // buffer size is validated when issuing the actual Recv operation
106 // on the socket.
107 socket->set_buffer_size(*properties->buffer_size.get());
108 }
109 }
110
111 static void DispatchConnectionEventWorker(
112 void* browser_context_id,
113 const std::string& extension_id,
114 const std::string& profile_uuid,
115 const device::BluetoothDevice* device,
116 scoped_refptr<device::BluetoothSocket> socket) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118
119 content::BrowserContext* context =
120 reinterpret_cast<content::BrowserContext*>(browser_context_id);
121 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context))
122 return;
123
124 extensions::BluetoothAPI* bluetooth_api =
125 extensions::BluetoothAPI::Get(context);
126 if (!bluetooth_api)
127 return;
128
129 bluetooth_api->DispatchConnectionEvent(
130 extension_id, profile_uuid, device, socket);
131 }
132
64 } // namespace 133 } // namespace
65 134
66 namespace AddProfile = extensions::api::bluetooth::AddProfile;
67 namespace bluetooth = extensions::api::bluetooth;
68 namespace Connect = extensions::api::bluetooth::Connect;
69 namespace Disconnect = extensions::api::bluetooth::Disconnect;
70 namespace GetDevices = extensions::api::bluetooth::GetDevices;
71 namespace GetProfiles = extensions::api::bluetooth::GetProfiles;
72 namespace GetServices = extensions::api::bluetooth::GetServices;
73 namespace Read = extensions::api::bluetooth::Read;
74 namespace RemoveProfile = extensions::api::bluetooth::RemoveProfile;
75 namespace SetOutOfBandPairingData =
76 extensions::api::bluetooth::SetOutOfBandPairingData;
77 namespace Write = extensions::api::bluetooth::Write;
78
79 namespace extensions { 135 namespace extensions {
80 136
81 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothAPI> > 137 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothAPI> >
82 g_factory = LAZY_INSTANCE_INITIALIZER; 138 g_factory = LAZY_INSTANCE_INITIALIZER;
83 139
84 // static 140 // static
85 BrowserContextKeyedAPIFactory<BluetoothAPI>* 141 BrowserContextKeyedAPIFactory<BluetoothAPI>*
86 BluetoothAPI::GetFactoryInstance() { 142 BluetoothAPI::GetFactoryInstance() {
87 return g_factory.Pointer(); 143 return g_factory.Pointer();
88 } 144 }
89 145
90 // static 146 // static
91 BluetoothAPI* BluetoothAPI::Get(BrowserContext* context) { 147 BluetoothAPI* BluetoothAPI::Get(BrowserContext* context) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 return GetFactoryInstance()->Get(context); 149 return GetFactoryInstance()->Get(context);
93 } 150 }
94 151
95 BluetoothAPI::BluetoothAPI(BrowserContext* context) 152 BluetoothAPI::ConnectionParams::ConnectionParams() {}
153
154 BluetoothAPI::ConnectionParams::~ConnectionParams() {}
155
156 BluetoothAPI::BluetoothAPI(content::BrowserContext* context)
96 : browser_context_(context) { 157 : browser_context_(context) {
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver( 159 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver(
98 this, bluetooth::OnAdapterStateChanged::kEventName); 160 this, bluetooth::OnAdapterStateChanged::kEventName);
99 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver( 161 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver(
100 this, bluetooth::OnDeviceAdded::kEventName); 162 this, bluetooth::OnDeviceAdded::kEventName);
101 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver( 163 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver(
102 this, bluetooth::OnDeviceChanged::kEventName); 164 this, bluetooth::OnDeviceChanged::kEventName);
103 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver( 165 ExtensionSystem::Get(browser_context_)->event_router()->RegisterObserver(
104 this, bluetooth::OnDeviceRemoved::kEventName); 166 this, bluetooth::OnDeviceRemoved::kEventName);
105 } 167 }
106 168
107 BluetoothAPI::~BluetoothAPI() { 169 BluetoothAPI::~BluetoothAPI() {}
170
171 ExtensionBluetoothEventRouter* BluetoothAPI::event_router() {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
173 if (!event_router_) {
174 event_router_.reset(new ExtensionBluetoothEventRouter(browser_context_));
175 }
176 return event_router_.get();
108 } 177 }
109 178
110 ExtensionBluetoothEventRouter* BluetoothAPI::bluetooth_event_router() { 179 scoped_refptr<BluetoothAPI::SocketData> BluetoothAPI::socket_data() {
111 if (!bluetooth_event_router_) 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 bluetooth_event_router_.reset( 181 if (!socket_data_) {
113 new ExtensionBluetoothEventRouter(browser_context_)); 182 ApiResourceManager<BluetoothApiSocket>* socket_manager =
183 ApiResourceManager<BluetoothApiSocket>::Get(browser_context_);
184 DCHECK(socket_manager)
185 << "There is no socket manager. "
186 "If this assertion is failing during a test, then it is likely that "
187 "TestExtensionSystem is failing to provide an instance of "
188 "ApiResourceManager<BluetoothApiSocket>.";
114 189
115 return bluetooth_event_router_.get(); 190 socket_data_ = socket_manager->data_;
191 }
192 return socket_data_;
193 }
194
195 scoped_refptr<api::BluetoothSocketEventDispatcher>
196 BluetoothAPI::socket_event_dispatcher() {
197 if (!socket_event_dispatcher_) {
198 socket_event_dispatcher_ = new api::BluetoothSocketEventDispatcher(
199 browser_context_, socket_data());
200 }
201 return socket_event_dispatcher_;
116 } 202 }
117 203
118 void BluetoothAPI::Shutdown() { 204 void BluetoothAPI::Shutdown() {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 ExtensionSystem::Get(browser_context_)->event_router()->UnregisterObserver( 206 ExtensionSystem::Get(browser_context_)->event_router()->UnregisterObserver(
120 this); 207 this);
121 } 208 }
122 209
123 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) { 210 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) {
124 if (bluetooth_event_router()->IsBluetoothSupported()) 211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 bluetooth_event_router()->OnListenerAdded(); 212 if (event_router()->IsBluetoothSupported())
213 event_router()->OnListenerAdded();
126 } 214 }
127 215
128 void BluetoothAPI::OnListenerRemoved(const EventListenerInfo& details) { 216 void BluetoothAPI::OnListenerRemoved(const EventListenerInfo& details) {
129 if (bluetooth_event_router()->IsBluetoothSupported()) 217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
130 bluetooth_event_router()->OnListenerRemoved(); 218 if (event_router()->IsBluetoothSupported())
219 event_router()->OnListenerRemoved();
220 }
221
222 void BluetoothAPI::DispatchConnectionEvent(
223 const std::string& extension_id,
224 const std::string& profile_uuid,
225 const device::BluetoothDevice* device,
226 scoped_refptr<device::BluetoothSocket> socket) {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
228
229 if (!event_router()->HasProfile(profile_uuid))
230 return;
231
232 extensions::BluetoothAPI::ConnectionParams params;
233 params.browser_context_id = browser_context_;
234 params.thread_id = BluetoothApiSocket::kThreadId;
235 params.extension_id = extension_id;
236 params.profile_uuid = profile_uuid;
237 params.device_address = device->GetAddress();
238 params.socket = socket;
239 params.socket_data = socket_data();
240 BrowserThread::PostTask(
241 params.thread_id, FROM_HERE, base::Bind(&RegisterSocket, params));
242 }
243
244 // static
245 void BluetoothAPI::RegisterSocket(
246 const BluetoothAPI::ConnectionParams& params) {
247 DCHECK(BrowserThread::CurrentlyOn(params.thread_id));
248
249 BluetoothApiSocket* api_socket = new BluetoothApiSocket(params.extension_id,
250 params.socket,
251 params.device_address,
252 params.profile_uuid);
253 int socket_id = params.socket_data->Add(api_socket);
254 api::bluetooth::Socket result_socket;
255 result_socket.device.address = params.device_address;
256 result_socket.profile.uuid = params.profile_uuid;
257 result_socket.id = socket_id;
258
259 scoped_ptr<base::ListValue> args =
260 bluetooth::OnConnection::Create(result_socket);
261 scoped_ptr<Event> event(
262 new Event(bluetooth::OnConnection::kEventName, args.Pass()));
263
264 PostEvent(params, event.Pass());
265 }
266
267 // static
268 void BluetoothAPI::PostEvent(const BluetoothAPI::ConnectionParams& params,
269 scoped_ptr<extensions::Event> event) {
270 DCHECK(BrowserThread::CurrentlyOn(params.thread_id));
271
272 BrowserThread::PostTask(BrowserThread::UI,
273 FROM_HERE,
274 base::Bind(&DispatchEvent,
275 params.browser_context_id,
276 params.extension_id,
277 base::Passed(event.Pass())));
278 }
279
280 // static
281 void BluetoothAPI::DispatchEvent(void* browser_context_id,
282 const std::string& extension_id,
283 scoped_ptr<extensions::Event> event) {
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285
286 content::BrowserContext* context =
287 reinterpret_cast<content::BrowserContext*>(browser_context_id);
288 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context))
289 return;
290
291 EventRouter* router = ExtensionSystem::Get(context)->event_router();
292 if (router)
293 router->DispatchEventToExtension(extension_id, event.Pass());
131 } 294 }
132 295
133 namespace api { 296 namespace api {
134 297
135 BluetoothAddProfileFunction::BluetoothAddProfileFunction() { 298 BluetoothSocketApiFunction::BluetoothSocketApiFunction() {}
299
300 BluetoothSocketApiFunction::~BluetoothSocketApiFunction() {}
301
302 bool BluetoothSocketApiFunction::PrePrepare() {
303 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
304
305 set_work_thread_id(BluetoothApiSocket::kThreadId);
306 socket_data_ = BluetoothAPI::Get(browser_context())->socket_data();
307 socket_event_dispatcher_ =
308 BluetoothAPI::Get(browser_context())->socket_event_dispatcher();
309 return socket_data_ && socket_event_dispatcher_;
136 } 310 }
137 311
312 bool BluetoothSocketApiFunction::Respond() { return error_.empty(); }
313
314 BluetoothGetAdapterStateFunction::~BluetoothGetAdapterStateFunction() {}
315
316 bool BluetoothGetAdapterStateFunction::DoWork(
317 scoped_refptr<BluetoothAdapter> adapter) {
318 bluetooth::AdapterState state;
319 PopulateAdapterState(*adapter.get(), &state);
320 results_ = bluetooth::GetAdapterState::Results::Create(state);
321 SendResponse(true);
322 return true;
323 }
324
325 BluetoothGetDevicesFunction::~BluetoothGetDevicesFunction() {}
326
327 bool BluetoothGetDevicesFunction::DoWork(
328 scoped_refptr<BluetoothAdapter> adapter) {
329 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
330
331 base::ListValue* device_list = new base::ListValue;
332 SetResult(device_list);
333
334 BluetoothAdapter::DeviceList devices = adapter->GetDevices();
335 for (BluetoothAdapter::DeviceList::const_iterator iter = devices.begin();
336 iter != devices.end();
337 ++iter) {
338 const BluetoothDevice* device = *iter;
339 DCHECK(device);
340
341 bluetooth::Device extension_device;
342 bluetooth::BluetoothDeviceToApiDevice(*device, &extension_device);
343
344 device_list->Append(extension_device.ToValue().release());
345 }
346
347 SendResponse(true);
348
349 return true;
350 }
351
352 BluetoothAddProfileFunction::BluetoothAddProfileFunction() {}
353
354 BluetoothAddProfileFunction::~BluetoothAddProfileFunction() {}
355
138 bool BluetoothAddProfileFunction::RunImpl() { 356 bool BluetoothAddProfileFunction::RunImpl() {
357 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
139 scoped_ptr<AddProfile::Params> params(AddProfile::Params::Create(*args_)); 358 scoped_ptr<AddProfile::Params> params(AddProfile::Params::Create(*args_));
140 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 359 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
141 360
142 if (!BluetoothDevice::IsUUIDValid(params->profile.uuid)) { 361 if (!BluetoothDevice::IsUUIDValid(params->profile.uuid)) {
143 SetError(kInvalidUuid); 362 SetError(kInvalidUuid);
144 return false; 363 return false;
145 } 364 }
146 365
147 BluetoothPermissionRequest param(params->profile.uuid); 366 BluetoothPermissionRequest param(params->profile.uuid);
148 if (!BluetoothManifestData::CheckRequest(GetExtension(), param)) { 367 if (!BluetoothManifestData::CheckRequest(GetExtension(), param)) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 RegisterProfile( 401 RegisterProfile(
183 options, 402 options,
184 base::Bind(&BluetoothAddProfileFunction::OnProfileRegistered, this)); 403 base::Bind(&BluetoothAddProfileFunction::OnProfileRegistered, this));
185 404
186 return true; 405 return true;
187 } 406 }
188 407
189 void BluetoothAddProfileFunction::RegisterProfile( 408 void BluetoothAddProfileFunction::RegisterProfile(
190 const BluetoothProfile::Options& options, 409 const BluetoothProfile::Options& options,
191 const BluetoothProfile::ProfileCallback& callback) { 410 const BluetoothProfile::ProfileCallback& callback) {
411 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
192 BluetoothProfile::Register(uuid_, options, callback); 412 BluetoothProfile::Register(uuid_, options, callback);
193 } 413 }
194 414
195 void BluetoothAddProfileFunction::OnProfileRegistered( 415 void BluetoothAddProfileFunction::OnProfileRegistered(
196 BluetoothProfile* bluetooth_profile) { 416 BluetoothProfile* bluetooth_profile) {
417 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
197 if (!bluetooth_profile) { 418 if (!bluetooth_profile) {
198 SetError(kProfileRegistrationFailed); 419 SetError(kProfileRegistrationFailed);
199 SendResponse(false); 420 SendResponse(false);
200 return; 421 return;
201 } 422 }
202 423
203 if (GetEventRouter(browser_context())->HasProfile(uuid_)) { 424 if (GetEventRouter(browser_context())->HasProfile(uuid_)) {
204 bluetooth_profile->Unregister(); 425 bluetooth_profile->Unregister();
205 SetError(kProfileAlreadyRegistered); 426 SetError(kProfileAlreadyRegistered);
206 SendResponse(false); 427 SendResponse(false);
207 return; 428 return;
208 } 429 }
209 430
210 bluetooth_profile->SetConnectionCallback( 431 bluetooth_profile->SetConnectionCallback(
211 base::Bind(&ExtensionBluetoothEventRouter::DispatchConnectionEvent, 432 base::Bind(&DispatchConnectionEventWorker,
212 base::Unretained(GetEventRouter(browser_context())), 433 browser_context(),
213 extension_id(), 434 extension_id(),
214 uuid_)); 435 uuid_));
215 GetEventRouter(browser_context()) 436 GetEventRouter(browser_context())
216 ->AddProfile(uuid_, extension_id(), bluetooth_profile); 437 ->AddProfile(uuid_, extension_id(), bluetooth_profile);
217 SendResponse(true); 438 SendResponse(true);
218 } 439 }
219 440
441 BluetoothRemoveProfileFunction::~BluetoothRemoveProfileFunction() {}
442
220 bool BluetoothRemoveProfileFunction::RunImpl() { 443 bool BluetoothRemoveProfileFunction::RunImpl() {
444 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
221 scoped_ptr<RemoveProfile::Params> params( 445 scoped_ptr<RemoveProfile::Params> params(
222 RemoveProfile::Params::Create(*args_)); 446 RemoveProfile::Params::Create(*args_));
223 447
224 if (!BluetoothDevice::IsUUIDValid(params->profile.uuid)) { 448 if (!BluetoothDevice::IsUUIDValid(params->profile.uuid)) {
225 SetError(kInvalidUuid); 449 SetError(kInvalidUuid);
226 return false; 450 return false;
227 } 451 }
228 452
229 std::string uuid = 453 std::string uuid =
230 device::bluetooth_utils::CanonicalUuid(params->profile.uuid); 454 device::bluetooth_utils::CanonicalUuid(params->profile.uuid);
231 455
232 if (!GetEventRouter(browser_context())->HasProfile(uuid)) { 456 if (!GetEventRouter(browser_context())->HasProfile(uuid)) {
233 SetError(kProfileNotFound); 457 SetError(kProfileNotFound);
234 return false; 458 return false;
235 } 459 }
236 460
237 GetEventRouter(browser_context())->RemoveProfile(uuid); 461 GetEventRouter(browser_context())->RemoveProfile(uuid);
238 return true; 462 return true;
239 } 463 }
240 464
241 // TODO(youngki): Implement. 465 BluetoothGetProfilesFunction::~BluetoothGetProfilesFunction() {}
466
242 bool BluetoothGetProfilesFunction::DoWork( 467 bool BluetoothGetProfilesFunction::DoWork(
243 scoped_refptr<device::BluetoothAdapter> adapter) { 468 scoped_refptr<device::BluetoothAdapter> adapter) {
469 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
244 scoped_ptr<GetProfiles::Params> params(GetProfiles::Params::Create(*args_)); 470 scoped_ptr<GetProfiles::Params> params(GetProfiles::Params::Create(*args_));
245 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 471 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
246 const bluetooth::GetProfilesOptions& options = params->options; 472 const bluetooth::GetProfilesOptions& options = params->options;
247 473
248 BluetoothDevice* device = adapter->GetDevice(options.device.address); 474 BluetoothDevice* device = adapter->GetDevice(options.device.address);
249 if (!device) { 475 if (!device) {
250 SetError(kInvalidDevice); 476 SetError(kInvalidDevice);
251 SendResponse(false); 477 SendResponse(false);
252 return false; 478 return false;
253 } 479 }
254 480
255 BluetoothDevice::ServiceList service_list = device->GetServices(); 481 BluetoothDevice::ServiceList service_list = device->GetServices();
256 482
257 base::ListValue* profiles = new base::ListValue; 483 std::vector<linked_ptr<bluetooth::Profile> > profiles;
258 for (BluetoothDevice::ServiceList::const_iterator iter = service_list.begin(); 484 for (BluetoothDevice::ServiceList::const_iterator iter = service_list.begin();
259 iter != service_list.end(); 485 iter != service_list.end();
260 ++iter) { 486 ++iter) {
261 bluetooth::Profile api_profile; 487 linked_ptr<bluetooth::Profile> api_profile(new bluetooth::Profile());
262 api_profile.uuid = *iter; 488 api_profile->uuid = *iter;
263 profiles->Append(api_profile.ToValue().release()); 489 // TODO(rpaquay): Add other fields.
490 profiles.push_back(api_profile);
264 } 491 }
265 492
266 SetResult(profiles); 493 results_ = bluetooth::GetProfiles::Results::Create(profiles);
267 SendResponse(true); 494 SendResponse(true);
268 495
269 return true; 496 return true;
270 } 497 }
271 498
272 bool BluetoothGetAdapterStateFunction::DoWork( 499 BluetoothConnectFunction::~BluetoothConnectFunction() {}
273 scoped_refptr<BluetoothAdapter> adapter) {
274 bluetooth::AdapterState state;
275 PopulateAdapterState(*adapter.get(), &state);
276 SetResult(state.ToValue().release());
277 SendResponse(true);
278 return true;
279 }
280
281 bool BluetoothGetDevicesFunction::DoWork(
282 scoped_refptr<BluetoothAdapter> adapter) {
283 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
284
285 base::ListValue* device_list = new base::ListValue;
286 SetResult(device_list);
287
288 BluetoothAdapter::DeviceList devices = adapter->GetDevices();
289 for (BluetoothAdapter::DeviceList::const_iterator iter = devices.begin();
290 iter != devices.end();
291 ++iter) {
292 const BluetoothDevice* device = *iter;
293 DCHECK(device);
294
295 bluetooth::Device extension_device;
296 bluetooth::BluetoothDeviceToApiDevice(*device, &extension_device);
297
298 device_list->Append(extension_device.ToValue().release());
299 }
300
301 SendResponse(true);
302
303 return true;
304 }
305
306 void BluetoothGetServicesFunction::GetServiceRecordsCallback(
307 base::ListValue* services,
308 const BluetoothDevice::ServiceRecordList& records) {
309 for (BluetoothDevice::ServiceRecordList::const_iterator i = records.begin();
310 i != records.end(); ++i) {
311 const BluetoothServiceRecord& record = **i;
312 bluetooth::ServiceRecord api_record;
313 api_record.name = record.name();
314 if (!record.uuid().empty())
315 api_record.uuid.reset(new std::string(record.uuid()));
316 services->Append(api_record.ToValue().release());
317 }
318
319 SendResponse(true);
320 }
321
322 void BluetoothGetServicesFunction::OnErrorCallback() {
323 SetError(kServiceDiscoveryFailed);
324 SendResponse(false);
325 }
326
327 bool BluetoothGetServicesFunction::DoWork(
328 scoped_refptr<BluetoothAdapter> adapter) {
329 scoped_ptr<GetServices::Params> params(GetServices::Params::Create(*args_));
330 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
331 const bluetooth::GetServicesOptions& options = params->options;
332
333 BluetoothDevice* device = adapter->GetDevice(options.device_address);
334 if (!device) {
335 SetError(kInvalidDevice);
336 SendResponse(false);
337 return false;
338 }
339
340 base::ListValue* services = new base::ListValue;
341 SetResult(services);
342
343 device->GetServiceRecords(
344 base::Bind(&BluetoothGetServicesFunction::GetServiceRecordsCallback,
345 this,
346 services),
347 base::Bind(&BluetoothGetServicesFunction::OnErrorCallback,
348 this));
349
350 return true;
351 }
352
353 void BluetoothConnectFunction::OnSuccessCallback() {
354 SendResponse(true);
355 }
356
357 void BluetoothConnectFunction::OnErrorCallback() {
358 SetError(kFailedToConnect);
359 SendResponse(false);
360 }
361 500
362 bool BluetoothConnectFunction::DoWork(scoped_refptr<BluetoothAdapter> adapter) { 501 bool BluetoothConnectFunction::DoWork(scoped_refptr<BluetoothAdapter> adapter) {
502 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
363 scoped_ptr<Connect::Params> params(Connect::Params::Create(*args_)); 503 scoped_ptr<Connect::Params> params(Connect::Params::Create(*args_));
364 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 504 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
365 const bluetooth::ConnectOptions& options = params->options; 505 const bluetooth::ConnectOptions& options = params->options;
366 506
367 if (!BluetoothDevice::IsUUIDValid(options.profile.uuid)) { 507 if (!BluetoothDevice::IsUUIDValid(options.profile.uuid)) {
368 SetError(kInvalidUuid); 508 SetError(kInvalidUuid);
369 SendResponse(false); 509 SendResponse(false);
370 return false; 510 return false;
371 } 511 }
372 512
(...skipping 10 matching lines...) Expand all
383 BluetoothProfile* bluetooth_profile = 523 BluetoothProfile* bluetooth_profile =
384 GetEventRouter(browser_context())->GetProfile(uuid); 524 GetEventRouter(browser_context())->GetProfile(uuid);
385 if (!bluetooth_profile) { 525 if (!bluetooth_profile) {
386 SetError(kProfileNotFound); 526 SetError(kProfileNotFound);
387 SendResponse(false); 527 SendResponse(false);
388 return false; 528 return false;
389 } 529 }
390 530
391 device->ConnectToProfile( 531 device->ConnectToProfile(
392 bluetooth_profile, 532 bluetooth_profile,
533 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
534 BrowserThread::GetMessageLoopProxyForThread(
535 BluetoothApiSocket::kThreadId),
536 NULL,
537 net::NetLog::Source(),
393 base::Bind(&BluetoothConnectFunction::OnSuccessCallback, this), 538 base::Bind(&BluetoothConnectFunction::OnSuccessCallback, this),
394 base::Bind(&BluetoothConnectFunction::OnErrorCallback, this)); 539 base::Bind(&BluetoothConnectFunction::OnErrorCallback, this));
395 540
396 return true; 541 return true;
397 } 542 }
398 543
399 bool BluetoothDisconnectFunction::RunImpl() { 544 void BluetoothConnectFunction::OnSuccessCallback() {
400 scoped_ptr<Disconnect::Params> params(Disconnect::Params::Create(*args_)); 545 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
401 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 546 SendResponse(true);
402 const bluetooth::DisconnectOptions& options = params->options; 547 }
403 return GetEventRouter(browser_context())->ReleaseSocket(options.socket.id); 548
404 } 549 void BluetoothConnectFunction::OnErrorCallback(const std::string& error) {
405 550 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
406 BluetoothReadFunction::BluetoothReadFunction() : success_(false) {} 551 SetError(error);
407 BluetoothReadFunction::~BluetoothReadFunction() {} 552 SendResponse(false);
408 553 }
409 bool BluetoothReadFunction::Prepare() { 554
410 scoped_ptr<Read::Params> params(Read::Params::Create(*args_)); 555 BluetoothDisconnectFunction::BluetoothDisconnectFunction() {}
411 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 556
412 const bluetooth::ReadOptions& options = params->options; 557 BluetoothDisconnectFunction::~BluetoothDisconnectFunction() {}
413 558
414 socket_ = GetEventRouter(browser_context())->GetSocket(options.socket.id); 559 bool BluetoothDisconnectFunction::Prepare() {
415 if (socket_.get() == NULL) { 560 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
416 SetError(kSocketNotFoundError); 561 params_ = Disconnect::Params::Create(*args_);
417 return false; 562 EXTENSION_FUNCTION_VALIDATE(params_.get() != NULL);
418 } 563 return true;
419 564 }
420 success_ = false; 565
421 return true; 566 void BluetoothDisconnectFunction::AsyncWorkStart() {
422 } 567 DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
423 568 BluetoothApiSocket* socket =
424 void BluetoothReadFunction::Work() { 569 socket_data_->Get(extension_id(), params_->options.socket_id);
425 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 570 if (!socket) {
426 571 error_ = kSocketNotFoundError;
427 if (!socket_.get()) 572 return;
428 return; 573 }
429 574 socket->Disconnect(base::Bind(&BluetoothDisconnectFunction::OnSuccess, this));
430 scoped_refptr<net::GrowableIOBuffer> buffer(new net::GrowableIOBuffer); 575 }
431 success_ = socket_->Receive(buffer.get()); 576
432 if (success_) 577 void BluetoothDisconnectFunction::OnSuccess() {
433 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer->StartOfBuffer(), 578 DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
434 buffer->offset())); 579 socket_data_->Remove(extension_id(), params_->options.socket_id);
435 else 580 results_ = bluetooth::Disconnect::Results::Create();
436 SetError(socket_->GetLastErrorMessage()); 581 AsyncWorkCompleted();
437 } 582 }
438 583
439 bool BluetoothReadFunction::Respond() { 584 BluetoothSendFunction::BluetoothSendFunction() : io_buffer_size_(0) {}
440 return success_; 585
441 } 586 BluetoothSendFunction::~BluetoothSendFunction() {}
442 587
443 BluetoothWriteFunction::BluetoothWriteFunction() 588 bool BluetoothSendFunction::Prepare() {
444 : success_(false), 589 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
445 data_to_write_(NULL) { 590 params_ = Send::Params::Create(*args_);
446 } 591 EXTENSION_FUNCTION_VALIDATE(params_.get() != NULL);
447 592 io_buffer_size_ = params_->options.data.size();
448 BluetoothWriteFunction::~BluetoothWriteFunction() {} 593 io_buffer_ = new net::WrappedIOBuffer(params_->options.data.data());
449 594 return true;
450 bool BluetoothWriteFunction::Prepare() { 595 }
451 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer 596
452 // support is added 597 void BluetoothSendFunction::AsyncWorkStart() {
453 base::DictionaryValue* options; 598 DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
454 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); 599 BluetoothApiSocket* socket =
455 600 socket_data_->Get(extension_id(), params_->options.socket_id);
456 base::DictionaryValue* socket; 601 if (!socket) {
457 EXTENSION_FUNCTION_VALIDATE(options->GetDictionary("socket", &socket)); 602 error_ = kSocketNotFoundError;
458 603 return;
459 int socket_id; 604 }
460 EXTENSION_FUNCTION_VALIDATE(socket->GetInteger("id", &socket_id));
461
462 socket_ = GetEventRouter(browser_context())->GetSocket(socket_id);
463 if (socket_.get() == NULL) {
464 SetError(kSocketNotFoundError);
465 return false;
466 }
467
468 base::BinaryValue* tmp_data;
469 EXTENSION_FUNCTION_VALIDATE(options->GetBinary("data", &tmp_data));
470 data_to_write_ = tmp_data;
471
472 success_ = false;
473 return socket_.get() != NULL;
474 }
475
476 void BluetoothWriteFunction::Work() {
477 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
478
479 if (socket_.get() == NULL)
480 return;
481
482 scoped_refptr<net::WrappedIOBuffer> wrapped_io_buffer(
483 new net::WrappedIOBuffer(data_to_write_->GetBuffer()));
484 scoped_refptr<net::DrainableIOBuffer> drainable_io_buffer( 605 scoped_refptr<net::DrainableIOBuffer> drainable_io_buffer(
485 new net::DrainableIOBuffer(wrapped_io_buffer.get(), 606 new net::DrainableIOBuffer(io_buffer_.get(), io_buffer_size_));
486 data_to_write_->GetSize())); 607 socket->Send(drainable_io_buffer,
487 success_ = socket_->Send(drainable_io_buffer.get()); 608 base::Bind(&BluetoothSendFunction::OnSendSuccess, this),
488 if (success_) { 609 base::Bind(&BluetoothSendFunction::OnSendError, this));
489 if (drainable_io_buffer->BytesConsumed() > 0) 610 }
490 SetResult(new base::FundamentalValue( 611
491 drainable_io_buffer->BytesConsumed())); 612 void BluetoothSendFunction::OnSendSuccess(int bytes_sent) {
492 else 613 DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
493 results_.reset(); 614 results_ = Send::Results::Create(bytes_sent);
494 } else { 615 AsyncWorkCompleted();
495 SetError(socket_->GetLastErrorMessage()); 616 }
496 } 617
497 } 618 void BluetoothSendFunction::OnSendError(const std::string& message) {
498 619 DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
499 bool BluetoothWriteFunction::Respond() { 620 error_ = message;
500 return success_; 621 AsyncWorkCompleted();
622 }
623
624 BluetoothUpdateSocketFunction::BluetoothUpdateSocketFunction() {}
625
626 BluetoothUpdateSocketFunction::~BluetoothUpdateSocketFunction() {}
627
628 bool BluetoothUpdateSocketFunction::Prepare() {
629 params_ = bluetooth::UpdateSocket::Params::Create(*args_);
630 EXTENSION_FUNCTION_VALIDATE(params_.get());
631 return true;
632 }
633
634 void BluetoothUpdateSocketFunction::Work() {
635 BluetoothApiSocket* socket =
636 socket_data_->Get(extension_id(), params_->socket_id);
637 if (!socket) {
638 error_ = kSocketNotFoundError;
639 return;
640 }
641
642 SetSocketProperties(socket, &params_.get()->properties);
643 results_ = bluetooth::UpdateSocket::Results::Create();
644 }
645
646 BluetoothSetSocketPausedFunction::BluetoothSetSocketPausedFunction() {}
647
648 BluetoothSetSocketPausedFunction::~BluetoothSetSocketPausedFunction() {}
649
650 bool BluetoothSetSocketPausedFunction::Prepare() {
651 params_ = bluetooth::SetSocketPaused::Params::Create(*args_);
652 EXTENSION_FUNCTION_VALIDATE(params_.get());
653 return true;
654 }
655
656 void BluetoothSetSocketPausedFunction::Work() {
657 BluetoothApiSocket* socket =
658 socket_data_->Get(extension_id(), params_->socket_id);
659 if (!socket) {
660 error_ = kSocketNotFoundError;
661 return;
662 }
663
664 if (socket->paused() != params_->paused) {
665 socket->set_paused(params_->paused);
666 if (!params_->paused) {
667 socket_event_dispatcher_->OnSocketResume(extension_->id(),
668 params_->socket_id);
669 }
670 }
671
672 results_ = bluetooth::SetSocketPaused::Results::Create();
673 }
674
675 BluetoothGetSocketFunction::BluetoothGetSocketFunction() {}
676
677 BluetoothGetSocketFunction::~BluetoothGetSocketFunction() {}
678
679 bool BluetoothGetSocketFunction::Prepare() {
680 params_ = bluetooth::GetSocket::Params::Create(*args_);
681 EXTENSION_FUNCTION_VALIDATE(params_.get());
682 return true;
683 }
684
685 void BluetoothGetSocketFunction::Work() {
686 BluetoothApiSocket* socket =
687 socket_data_->Get(extension_id(), params_->socket_id);
688 if (!socket) {
689 error_ = kSocketNotFoundError;
690 return;
691 }
692
693 linked_ptr<bluetooth::Socket> socket_info =
694 CreateSocketInfo(params_->socket_id, socket);
695 results_ = bluetooth::GetSocket::Results::Create(*socket_info);
696 }
697
698 BluetoothGetSocketsFunction::BluetoothGetSocketsFunction() {}
699
700 BluetoothGetSocketsFunction::~BluetoothGetSocketsFunction() {}
701
702 bool BluetoothGetSocketsFunction::Prepare() { return true; }
703
704 void BluetoothGetSocketsFunction::Work() {
705 std::vector<linked_ptr<bluetooth::Socket> > socket_infos;
706 base::hash_set<int>* resource_ids =
707 socket_data_->GetResourceIds(extension_id());
708 if (resource_ids != NULL) {
709 for (base::hash_set<int>::iterator it = resource_ids->begin();
710 it != resource_ids->end();
711 ++it) {
712 int socket_id = *it;
713 BluetoothApiSocket* socket = socket_data_->Get(extension_id(), socket_id);
714 if (socket) {
715 socket_infos.push_back(CreateSocketInfo(socket_id, socket));
716 }
717 }
718 }
719 results_ = bluetooth::GetSockets::Results::Create(socket_infos);
501 } 720 }
502 721
503 void BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback() { 722 void BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback() {
504 SendResponse(true); 723 SendResponse(true);
505 } 724 }
506 725
507 void BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback() { 726 void BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback(
508 SetError(kCouldNotSetOutOfBandPairingData); 727 const std::string& error) {
728 SetError(error);
509 SendResponse(false); 729 SendResponse(false);
510 } 730 }
511 731
512 bool BluetoothSetOutOfBandPairingDataFunction::DoWork( 732 bool BluetoothSetOutOfBandPairingDataFunction::DoWork(
513 scoped_refptr<BluetoothAdapter> adapter) { 733 scoped_refptr<BluetoothAdapter> adapter) {
514 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer 734 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer
515 // support is added 735 // support is added
516 base::DictionaryValue* options; 736 base::DictionaryValue* options;
517 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); 737 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options));
518 std::string address; 738 std::string address;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 adapter, 854 adapter,
635 extension_id(), 855 extension_id(),
636 base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this), 856 base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this),
637 base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this)); 857 base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this));
638 858
639 return true; 859 return true;
640 } 860 }
641 861
642 } // namespace api 862 } // namespace api
643 } // namespace extensions 863 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698