| OLD | NEW |
| 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/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" | 12 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" |
| 13 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" | 13 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" |
| 14 #include "chrome/browser/profiles/profile_manager.h" | 14 #include "chrome/browser/profiles/profile_manager.h" |
| 15 #include "chrome/common/extensions/api/bluetooth.h" | 15 #include "chrome/common/extensions/api/bluetooth.h" |
| 16 #include "chrome/common/extensions/api/bluetooth/bluetooth_manifest_data.h" | |
| 17 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 18 #include "device/bluetooth/bluetooth_adapter.h" | 17 #include "device/bluetooth/bluetooth_adapter.h" |
| 19 #include "device/bluetooth/bluetooth_device.h" | 18 #include "device/bluetooth/bluetooth_device.h" |
| 20 #include "device/bluetooth/bluetooth_profile.h" | |
| 21 #include "device/bluetooth/bluetooth_service_record.h" | |
| 22 #include "device/bluetooth/bluetooth_socket.h" | |
| 23 #include "extensions/browser/event_router.h" | 19 #include "extensions/browser/event_router.h" |
| 24 #include "extensions/common/permissions/permissions_data.h" | |
| 25 #include "net/base/io_buffer.h" | |
| 26 | 20 |
| 27 using content::BrowserContext; | 21 using content::BrowserContext; |
| 28 using content::BrowserThread; | 22 using content::BrowserThread; |
| 29 | 23 |
| 30 using device::BluetoothAdapter; | 24 using device::BluetoothAdapter; |
| 31 using device::BluetoothDevice; | 25 using device::BluetoothDevice; |
| 32 using device::BluetoothProfile; | |
| 33 using device::BluetoothServiceRecord; | |
| 34 using device::BluetoothSocket; | |
| 35 | 26 |
| 36 using extensions::BluetoothApiSocket; | |
| 37 | |
| 38 namespace AddProfile = extensions::api::bluetooth::AddProfile; | |
| 39 namespace bluetooth = extensions::api::bluetooth; | 27 namespace bluetooth = extensions::api::bluetooth; |
| 40 namespace Connect = extensions::api::bluetooth::Connect; | |
| 41 namespace Disconnect = extensions::api::bluetooth::Disconnect; | |
| 42 namespace GetDevice = extensions::api::bluetooth::GetDevice; | 28 namespace GetDevice = extensions::api::bluetooth::GetDevice; |
| 43 namespace GetDevices = extensions::api::bluetooth::GetDevices; | 29 namespace GetDevices = extensions::api::bluetooth::GetDevices; |
| 44 namespace RemoveProfile = extensions::api::bluetooth::RemoveProfile; | |
| 45 namespace Send = extensions::api::bluetooth::Send; | |
| 46 | 30 |
| 47 namespace { | 31 namespace { |
| 48 | 32 |
| 49 const char kInvalidDevice[] = "Invalid device"; | 33 const char kInvalidDevice[] = "Invalid device"; |
| 50 const char kInvalidUuid[] = "Invalid UUID"; | |
| 51 const char kPermissionDenied[] = "Permission to add profile denied."; | |
| 52 const char kProfileAlreadyRegistered[] = | |
| 53 "This profile has already been registered"; | |
| 54 const char kProfileNotFound[] = "Profile not found: invalid uuid"; | |
| 55 const char kProfileRegistrationFailed[] = "Profile registration failed"; | |
| 56 const char kStartDiscoveryFailed[] = "Starting discovery failed"; | 34 const char kStartDiscoveryFailed[] = "Starting discovery failed"; |
| 57 const char kStopDiscoveryFailed[] = "Failed to stop discovery"; | 35 const char kStopDiscoveryFailed[] = "Failed to stop discovery"; |
| 58 | 36 |
| 59 extensions::BluetoothEventRouter* GetEventRouter(BrowserContext* context) { | 37 extensions::BluetoothEventRouter* GetEventRouter(BrowserContext* context) { |
| 60 // Note: |context| is valid on UI thread only. | 38 // Note: |context| is valid on UI thread only. |
| 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 62 return extensions::BluetoothAPI::Get(context)->event_router(); | 40 return extensions::BluetoothAPI::Get(context)->event_router(); |
| 63 } | 41 } |
| 64 | 42 |
| 65 static void DispatchConnectionEventWorker( | |
| 66 void* browser_context_id, | |
| 67 const std::string& extension_id, | |
| 68 const device::BluetoothUUID& profile_uuid, | |
| 69 const device::BluetoothDevice* device, | |
| 70 scoped_refptr<device::BluetoothSocket> socket) { | |
| 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 72 | |
| 73 content::BrowserContext* context = | |
| 74 reinterpret_cast<content::BrowserContext*>(browser_context_id); | |
| 75 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) | |
| 76 return; | |
| 77 | |
| 78 extensions::BluetoothAPI* bluetooth_api = | |
| 79 extensions::BluetoothAPI::Get(context); | |
| 80 if (!bluetooth_api) | |
| 81 return; | |
| 82 | |
| 83 bluetooth_api->DispatchConnectionEvent( | |
| 84 extension_id, profile_uuid, device, socket); | |
| 85 } | |
| 86 | |
| 87 } // namespace | 43 } // namespace |
| 88 | 44 |
| 89 namespace extensions { | 45 namespace extensions { |
| 90 | 46 |
| 91 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothAPI> > | 47 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothAPI> > |
| 92 g_factory = LAZY_INSTANCE_INITIALIZER; | 48 g_factory = LAZY_INSTANCE_INITIALIZER; |
| 93 | 49 |
| 94 // static | 50 // static |
| 95 BrowserContextKeyedAPIFactory<BluetoothAPI>* | 51 BrowserContextKeyedAPIFactory<BluetoothAPI>* |
| 96 BluetoothAPI::GetFactoryInstance() { | 52 BluetoothAPI::GetFactoryInstance() { |
| 97 return g_factory.Pointer(); | 53 return g_factory.Pointer(); |
| 98 } | 54 } |
| 99 | 55 |
| 100 // static | 56 // static |
| 101 BluetoothAPI* BluetoothAPI::Get(BrowserContext* context) { | 57 BluetoothAPI* BluetoothAPI::Get(BrowserContext* context) { |
| 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 103 return GetFactoryInstance()->Get(context); | 59 return GetFactoryInstance()->Get(context); |
| 104 } | 60 } |
| 105 | 61 |
| 106 BluetoothAPI::ConnectionParams::ConnectionParams() {} | |
| 107 | |
| 108 BluetoothAPI::ConnectionParams::~ConnectionParams() {} | |
| 109 | |
| 110 BluetoothAPI::BluetoothAPI(content::BrowserContext* context) | 62 BluetoothAPI::BluetoothAPI(content::BrowserContext* context) |
| 111 : browser_context_(context) { | 63 : browser_context_(context) { |
| 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 113 EventRouter* event_router = EventRouter::Get(browser_context_); | 65 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 114 event_router->RegisterObserver(this, | 66 event_router->RegisterObserver(this, |
| 115 bluetooth::OnAdapterStateChanged::kEventName); | 67 bluetooth::OnAdapterStateChanged::kEventName); |
| 116 event_router->RegisterObserver(this, bluetooth::OnDeviceAdded::kEventName); | 68 event_router->RegisterObserver(this, bluetooth::OnDeviceAdded::kEventName); |
| 117 event_router->RegisterObserver(this, bluetooth::OnDeviceChanged::kEventName); | 69 event_router->RegisterObserver(this, bluetooth::OnDeviceChanged::kEventName); |
| 118 event_router->RegisterObserver(this, bluetooth::OnDeviceRemoved::kEventName); | 70 event_router->RegisterObserver(this, bluetooth::OnDeviceRemoved::kEventName); |
| 119 } | 71 } |
| 120 | 72 |
| 121 BluetoothAPI::~BluetoothAPI() {} | 73 BluetoothAPI::~BluetoothAPI() {} |
| 122 | 74 |
| 123 BluetoothEventRouter* BluetoothAPI::event_router() { | 75 BluetoothEventRouter* BluetoothAPI::event_router() { |
| 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 125 if (!event_router_) { | 77 if (!event_router_) { |
| 126 event_router_.reset(new BluetoothEventRouter(browser_context_)); | 78 event_router_.reset(new BluetoothEventRouter(browser_context_)); |
| 127 } | 79 } |
| 128 return event_router_.get(); | 80 return event_router_.get(); |
| 129 } | 81 } |
| 130 | 82 |
| 131 scoped_refptr<BluetoothAPI::SocketData> BluetoothAPI::socket_data() { | |
| 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 133 if (!socket_data_) { | |
| 134 ApiResourceManager<BluetoothApiSocket>* socket_manager = | |
| 135 ApiResourceManager<BluetoothApiSocket>::Get(browser_context_); | |
| 136 DCHECK(socket_manager) | |
| 137 << "There is no socket manager. " | |
| 138 "If this assertion is failing during a test, then it is likely that " | |
| 139 "TestExtensionSystem is failing to provide an instance of " | |
| 140 "ApiResourceManager<BluetoothApiSocket>."; | |
| 141 | |
| 142 socket_data_ = socket_manager->data_; | |
| 143 } | |
| 144 return socket_data_; | |
| 145 } | |
| 146 | |
| 147 void BluetoothAPI::Shutdown() { | 83 void BluetoothAPI::Shutdown() { |
| 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 149 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 85 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
| 150 } | 86 } |
| 151 | 87 |
| 152 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) { | 88 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) { |
| 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 154 if (event_router()->IsBluetoothSupported()) | 90 if (event_router()->IsBluetoothSupported()) |
| 155 event_router()->OnListenerAdded(); | 91 event_router()->OnListenerAdded(); |
| 156 } | 92 } |
| 157 | 93 |
| 158 void BluetoothAPI::OnListenerRemoved(const EventListenerInfo& details) { | 94 void BluetoothAPI::OnListenerRemoved(const EventListenerInfo& details) { |
| 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 160 if (event_router()->IsBluetoothSupported()) | 96 if (event_router()->IsBluetoothSupported()) |
| 161 event_router()->OnListenerRemoved(); | 97 event_router()->OnListenerRemoved(); |
| 162 } | 98 } |
| 163 | 99 |
| 164 void BluetoothAPI::DispatchConnectionEvent( | |
| 165 const std::string& extension_id, | |
| 166 const device::BluetoothUUID& uuid, | |
| 167 const device::BluetoothDevice* device, | |
| 168 scoped_refptr<device::BluetoothSocket> socket) { | |
| 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 170 | |
| 171 if (!event_router()->HasProfile(uuid)) | |
| 172 return; | |
| 173 | |
| 174 extensions::BluetoothAPI::ConnectionParams params; | |
| 175 params.browser_context_id = browser_context_; | |
| 176 params.thread_id = BluetoothApiSocket::kThreadId; | |
| 177 params.extension_id = extension_id; | |
| 178 params.uuid = uuid; | |
| 179 params.device_address = device->GetAddress(); | |
| 180 params.socket = socket; | |
| 181 params.socket_data = socket_data(); | |
| 182 BrowserThread::PostTask( | |
| 183 params.thread_id, FROM_HERE, base::Bind(&RegisterSocket, params)); | |
| 184 } | |
| 185 | |
| 186 // static | |
| 187 void BluetoothAPI::RegisterSocket( | |
| 188 const BluetoothAPI::ConnectionParams& params) { | |
| 189 DCHECK(BrowserThread::CurrentlyOn(params.thread_id)); | |
| 190 | |
| 191 BluetoothApiSocket* api_socket = new BluetoothApiSocket( | |
| 192 params.extension_id, params.socket, params.device_address, params.uuid); | |
| 193 int socket_id = params.socket_data->Add(api_socket); | |
| 194 | |
| 195 BrowserThread::PostTask(BrowserThread::UI, | |
| 196 FROM_HERE, | |
| 197 base::Bind(&RegisterSocketUI, params, socket_id)); | |
| 198 } | |
| 199 | |
| 200 // static | |
| 201 void BluetoothAPI::RegisterSocketUI(const ConnectionParams& params, | |
| 202 int socket_id) { | |
| 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 204 | |
| 205 content::BrowserContext* context = | |
| 206 reinterpret_cast<content::BrowserContext*>(params.browser_context_id); | |
| 207 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) | |
| 208 return; | |
| 209 | |
| 210 BluetoothAPI::Get(context)->event_router()->GetAdapter( | |
| 211 base::Bind(&RegisterSocketWithAdapterUI, params, socket_id)); | |
| 212 } | |
| 213 | |
| 214 void BluetoothAPI::RegisterSocketWithAdapterUI( | |
| 215 const ConnectionParams& params, | |
| 216 int socket_id, | |
| 217 scoped_refptr<device::BluetoothAdapter> adapter) { | |
| 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 219 | |
| 220 content::BrowserContext* context = | |
| 221 reinterpret_cast<content::BrowserContext*>(params.browser_context_id); | |
| 222 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) | |
| 223 return; | |
| 224 | |
| 225 BluetoothDevice* device = adapter->GetDevice(params.device_address); | |
| 226 if (!device) | |
| 227 return; | |
| 228 | |
| 229 api::bluetooth::Socket result_socket; | |
| 230 bluetooth::BluetoothDeviceToApiDevice(*device, &result_socket.device); | |
| 231 result_socket.uuid = params.uuid.canonical_value(); | |
| 232 result_socket.id = socket_id; | |
| 233 | |
| 234 scoped_ptr<base::ListValue> args = | |
| 235 bluetooth::OnConnection::Create(result_socket); | |
| 236 scoped_ptr<Event> event( | |
| 237 new Event(bluetooth::OnConnection::kEventName, args.Pass())); | |
| 238 | |
| 239 EventRouter* router = EventRouter::Get(context); | |
| 240 if (router) | |
| 241 router->DispatchEventToExtension(params.extension_id, event.Pass()); | |
| 242 } | |
| 243 | |
| 244 namespace api { | 100 namespace api { |
| 245 | 101 |
| 246 BluetoothGetAdapterStateFunction::~BluetoothGetAdapterStateFunction() {} | 102 BluetoothGetAdapterStateFunction::~BluetoothGetAdapterStateFunction() {} |
| 247 | 103 |
| 248 bool BluetoothGetAdapterStateFunction::DoWork( | 104 bool BluetoothGetAdapterStateFunction::DoWork( |
| 249 scoped_refptr<BluetoothAdapter> adapter) { | 105 scoped_refptr<BluetoothAdapter> adapter) { |
| 250 bluetooth::AdapterState state; | 106 bluetooth::AdapterState state; |
| 251 PopulateAdapterState(*adapter.get(), &state); | 107 PopulateAdapterState(*adapter.get(), &state); |
| 252 results_ = bluetooth::GetAdapterState::Results::Create(state); | 108 results_ = bluetooth::GetAdapterState::Results::Create(state); |
| 253 SendResponse(true); | 109 SendResponse(true); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 SetResult(extension_device.ToValue().release()); | 153 SetResult(extension_device.ToValue().release()); |
| 298 SendResponse(true); | 154 SendResponse(true); |
| 299 } else { | 155 } else { |
| 300 SetError(kInvalidDevice); | 156 SetError(kInvalidDevice); |
| 301 SendResponse(false); | 157 SendResponse(false); |
| 302 } | 158 } |
| 303 | 159 |
| 304 return false; | 160 return false; |
| 305 } | 161 } |
| 306 | 162 |
| 307 BluetoothAddProfileFunction::BluetoothAddProfileFunction() {} | |
| 308 | |
| 309 BluetoothAddProfileFunction::~BluetoothAddProfileFunction() {} | |
| 310 | |
| 311 bool BluetoothAddProfileFunction::RunAsync() { | |
| 312 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 313 scoped_ptr<AddProfile::Params> params(AddProfile::Params::Create(*args_)); | |
| 314 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | |
| 315 | |
| 316 device::BluetoothUUID uuid(params->profile.uuid); | |
| 317 | |
| 318 if (!uuid.IsValid()) { | |
| 319 SetError(kInvalidUuid); | |
| 320 return false; | |
| 321 } | |
| 322 | |
| 323 BluetoothPermissionRequest param(params->profile.uuid); | |
| 324 if (!BluetoothManifestData::CheckRequest(GetExtension(), param)) { | |
| 325 error_ = kPermissionDenied; | |
| 326 return false; | |
| 327 } | |
| 328 | |
| 329 uuid_ = uuid; | |
| 330 | |
| 331 if (GetEventRouter(browser_context())->HasProfile(uuid_)) { | |
| 332 SetError(kProfileAlreadyRegistered); | |
| 333 return false; | |
| 334 } | |
| 335 | |
| 336 BluetoothProfile::Options options; | |
| 337 if (params->profile.name.get()) | |
| 338 options.name = *params->profile.name.get(); | |
| 339 if (params->profile.channel.get()) | |
| 340 options.channel = *params->profile.channel.get(); | |
| 341 if (params->profile.psm.get()) | |
| 342 options.psm = *params->profile.psm.get(); | |
| 343 if (params->profile.require_authentication.get()) { | |
| 344 options.require_authentication = | |
| 345 *params->profile.require_authentication.get(); | |
| 346 } | |
| 347 if (params->profile.require_authorization.get()) { | |
| 348 options.require_authorization = | |
| 349 *params->profile.require_authorization.get(); | |
| 350 } | |
| 351 if (params->profile.auto_connect.get()) | |
| 352 options.auto_connect = *params->profile.auto_connect.get(); | |
| 353 if (params->profile.version.get()) | |
| 354 options.version = *params->profile.version.get(); | |
| 355 if (params->profile.features.get()) | |
| 356 options.features = *params->profile.features.get(); | |
| 357 | |
| 358 RegisterProfile( | |
| 359 options, | |
| 360 base::Bind(&BluetoothAddProfileFunction::OnProfileRegistered, this)); | |
| 361 | |
| 362 return true; | |
| 363 } | |
| 364 | |
| 365 void BluetoothAddProfileFunction::RegisterProfile( | |
| 366 const BluetoothProfile::Options& options, | |
| 367 const BluetoothProfile::ProfileCallback& callback) { | |
| 368 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 369 BluetoothProfile::Register(uuid_, options, callback); | |
| 370 } | |
| 371 | |
| 372 void BluetoothAddProfileFunction::OnProfileRegistered( | |
| 373 BluetoothProfile* bluetooth_profile) { | |
| 374 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 375 if (!bluetooth_profile) { | |
| 376 SetError(kProfileRegistrationFailed); | |
| 377 SendResponse(false); | |
| 378 return; | |
| 379 } | |
| 380 | |
| 381 if (GetEventRouter(browser_context())->HasProfile(uuid_)) { | |
| 382 bluetooth_profile->Unregister(); | |
| 383 SetError(kProfileAlreadyRegistered); | |
| 384 SendResponse(false); | |
| 385 return; | |
| 386 } | |
| 387 | |
| 388 bluetooth_profile->SetConnectionCallback( | |
| 389 base::Bind(&DispatchConnectionEventWorker, | |
| 390 browser_context(), | |
| 391 extension_id(), | |
| 392 uuid_)); | |
| 393 GetEventRouter(browser_context()) | |
| 394 ->AddProfile(uuid_, extension_id(), bluetooth_profile); | |
| 395 SendResponse(true); | |
| 396 } | |
| 397 | |
| 398 BluetoothRemoveProfileFunction::~BluetoothRemoveProfileFunction() {} | |
| 399 | |
| 400 bool BluetoothRemoveProfileFunction::RunSync() { | |
| 401 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 402 scoped_ptr<RemoveProfile::Params> params( | |
| 403 RemoveProfile::Params::Create(*args_)); | |
| 404 | |
| 405 device::BluetoothUUID uuid(params->profile.uuid); | |
| 406 | |
| 407 if (!uuid.IsValid()) { | |
| 408 SetError(kInvalidUuid); | |
| 409 return false; | |
| 410 } | |
| 411 | |
| 412 if (!GetEventRouter(browser_context())->HasProfile(uuid)) { | |
| 413 SetError(kProfileNotFound); | |
| 414 return false; | |
| 415 } | |
| 416 | |
| 417 GetEventRouter(browser_context())->RemoveProfile(uuid); | |
| 418 return true; | |
| 419 } | |
| 420 | |
| 421 BluetoothConnectFunction::~BluetoothConnectFunction() {} | |
| 422 | |
| 423 bool BluetoothConnectFunction::DoWork(scoped_refptr<BluetoothAdapter> adapter) { | |
| 424 scoped_ptr<Connect::Params> params(Connect::Params::Create(*args_)); | |
| 425 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | |
| 426 const bluetooth::ConnectOptions& options = params->options; | |
| 427 | |
| 428 device::BluetoothUUID uuid(options.profile.uuid); | |
| 429 | |
| 430 if (!uuid.IsValid()) { | |
| 431 SetError(kInvalidUuid); | |
| 432 SendResponse(false); | |
| 433 return false; | |
| 434 } | |
| 435 | |
| 436 BluetoothDevice* device = adapter->GetDevice(options.device.address); | |
| 437 if (!device) { | |
| 438 SetError(kInvalidDevice); | |
| 439 SendResponse(false); | |
| 440 return false; | |
| 441 } | |
| 442 | |
| 443 BluetoothProfile* bluetooth_profile = | |
| 444 GetEventRouter(browser_context())->GetProfile(uuid); | |
| 445 if (!bluetooth_profile) { | |
| 446 SetError(kProfileNotFound); | |
| 447 SendResponse(false); | |
| 448 return false; | |
| 449 } | |
| 450 | |
| 451 device->ConnectToProfile( | |
| 452 bluetooth_profile, | |
| 453 base::Bind(&BluetoothConnectFunction::OnConnectedCallback, | |
| 454 this, | |
| 455 adapter, | |
| 456 device->GetAddress()), | |
| 457 base::Bind(&BluetoothConnectFunction::OnErrorCallback, this)); | |
| 458 | |
| 459 return true; | |
| 460 } | |
| 461 | |
| 462 void BluetoothConnectFunction::OnConnectedCallback( | |
| 463 scoped_refptr<device::BluetoothAdapter> adapter, | |
| 464 const std::string& device_address) { | |
| 465 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 466 | |
| 467 // TODO(tengs): Remove this once we have an API for starting the connection | |
| 468 // monitor. | |
| 469 BluetoothDevice* device = adapter->GetDevice(device_address); | |
| 470 if (!device) { | |
| 471 SetError(kInvalidDevice); | |
| 472 SendResponse(false); | |
| 473 return; | |
| 474 } | |
| 475 // Start the connection monitor, and return success even if this fails, | |
| 476 // as the connection was still opened successfully. | |
| 477 device->StartConnectionMonitor( | |
| 478 base::Bind(&BluetoothConnectFunction::OnMonitorStartedCallback, this), | |
| 479 base::Bind(&BluetoothConnectFunction::OnMonitorStartedCallback, this)); | |
| 480 } | |
| 481 | |
| 482 void BluetoothConnectFunction::OnMonitorStartedCallback() { | |
| 483 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 484 SendResponse(true); | |
| 485 } | |
| 486 | |
| 487 void BluetoothConnectFunction::OnErrorCallback(const std::string& error) { | |
| 488 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 489 SetError(error); | |
| 490 SendResponse(false); | |
| 491 } | |
| 492 | |
| 493 bool BluetoothDisconnectFunction::RunAsync() { | |
| 494 // TODO(keybuk): Remove. | |
| 495 SetError("Removed. Use chrome.bluetoothSocket.disconnect() instead."); | |
| 496 return false; | |
| 497 } | |
| 498 | |
| 499 bool BluetoothSendFunction::RunAsync() { | |
| 500 // TODO(keybuk): Remove. | |
| 501 SetError("Removed. Use chrome.bluetoothSocket.send() instead."); | |
| 502 return false; | |
| 503 } | |
| 504 | |
| 505 bool BluetoothUpdateSocketFunction::RunAsync() { | |
| 506 // TODO(keybuk): Remove. | |
| 507 SetError("Removed. Use chrome.bluetoothSocket.update() instead."); | |
| 508 return false; | |
| 509 } | |
| 510 | |
| 511 bool BluetoothSetSocketPausedFunction::RunAsync() { | |
| 512 // TODO(keybuk): Remove. | |
| 513 SetError("Removed. Use chrome.bluetoothSocket.setPaused() instead."); | |
| 514 return false; | |
| 515 } | |
| 516 | |
| 517 bool BluetoothGetSocketFunction::RunAsync() { | |
| 518 // TODO(keybuk): Remove. | |
| 519 SetError("Removed. Use chrome.bluetoothSocket.getInfo() instead."); | |
| 520 return false; | |
| 521 } | |
| 522 | |
| 523 bool BluetoothGetSocketsFunction::RunAsync() { | |
| 524 // TODO(keybuk): Remove. | |
| 525 SetError("Removed. Use chrome.bluetoothSocket.getSockets() instead."); | |
| 526 return false; | |
| 527 } | |
| 528 | |
| 529 void BluetoothStartDiscoveryFunction::OnSuccessCallback() { | 163 void BluetoothStartDiscoveryFunction::OnSuccessCallback() { |
| 530 SendResponse(true); | 164 SendResponse(true); |
| 531 } | 165 } |
| 532 | 166 |
| 533 void BluetoothStartDiscoveryFunction::OnErrorCallback() { | 167 void BluetoothStartDiscoveryFunction::OnErrorCallback() { |
| 534 SetError(kStartDiscoveryFailed); | 168 SetError(kStartDiscoveryFailed); |
| 535 SendResponse(false); | 169 SendResponse(false); |
| 536 } | 170 } |
| 537 | 171 |
| 538 bool BluetoothStartDiscoveryFunction::DoWork( | 172 bool BluetoothStartDiscoveryFunction::DoWork( |
| (...skipping 22 matching lines...) Expand all Loading... |
| 561 adapter, | 195 adapter, |
| 562 extension_id(), | 196 extension_id(), |
| 563 base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this), | 197 base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this), |
| 564 base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this)); | 198 base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this)); |
| 565 | 199 |
| 566 return true; | 200 return true; |
| 567 } | 201 } |
| 568 | 202 |
| 569 } // namespace api | 203 } // namespace api |
| 570 } // namespace extensions | 204 } // namespace extensions |
| OLD | NEW |