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