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

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

Powered by Google App Engine
This is Rietveld 408576698