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

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

Powered by Google App Engine
This is Rietveld 408576698