Chromium Code Reviews| 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 "extensions/browser/api/bluetooth/bluetooth_event_router.h" | 5 #include "extensions/browser/api/bluetooth/bluetooth_event_router.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 #include "extensions/common/api/bluetooth.h" | 30 #include "extensions/common/api/bluetooth.h" |
| 31 #include "extensions/common/api/bluetooth_private.h" | 31 #include "extensions/common/api/bluetooth_private.h" |
| 32 | 32 |
| 33 namespace extensions { | 33 namespace extensions { |
| 34 | 34 |
| 35 namespace bluetooth = api::bluetooth; | 35 namespace bluetooth = api::bluetooth; |
| 36 namespace bt_private = api::bluetooth_private; | 36 namespace bt_private = api::bluetooth_private; |
| 37 | 37 |
| 38 BluetoothEventRouter::BluetoothEventRouter(content::BrowserContext* context) | 38 BluetoothEventRouter::BluetoothEventRouter(content::BrowserContext* context) |
| 39 : browser_context_(context), | 39 : browser_context_(context), |
| 40 adapter_(NULL), | 40 adapter_(nullptr), |
| 41 num_event_listeners_(0), | 41 num_event_listeners_(0), |
| 42 extension_registry_observer_(this), | 42 extension_registry_observer_(this), |
| 43 weak_ptr_factory_(this) { | 43 weak_ptr_factory_(this) { |
| 44 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 44 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 45 DCHECK(browser_context_); | 45 DCHECK(browser_context_); |
| 46 registrar_.Add(this, | 46 registrar_.Add(this, |
| 47 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 47 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 48 content::Source<content::BrowserContext>(browser_context_)); | 48 content::Source<content::BrowserContext>(browser_context_)); |
| 49 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); | 49 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
| 50 } | 50 } |
| 51 | 51 |
| 52 BluetoothEventRouter::~BluetoothEventRouter() { | 52 BluetoothEventRouter::~BluetoothEventRouter() { |
| 53 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 53 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 54 if (adapter_.get()) { | 54 if (adapter_.get()) { |
| 55 adapter_->RemoveObserver(this); | 55 adapter_->RemoveObserver(this); |
| 56 adapter_ = NULL; | 56 adapter_ = nullptr; |
| 57 } | 57 } |
| 58 CleanUpAllExtensions(); | 58 CleanUpAllExtensions(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 bool BluetoothEventRouter::IsBluetoothSupported() const { | 61 bool BluetoothEventRouter::IsBluetoothSupported() const { |
| 62 return adapter_.get() || | 62 return adapter_.get() || |
| 63 device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable(); | 63 device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 void BluetoothEventRouter::GetAdapter( | 66 void BluetoothEventRouter::GetAdapter( |
| 67 const device::BluetoothAdapterFactory::AdapterCallback& callback) { | 67 const device::BluetoothAdapterFactory::AdapterCallback& callback) { |
| 68 if (adapter_.get()) { | 68 if (adapter_.get()) { |
| 69 callback.Run(scoped_refptr<device::BluetoothAdapter>(adapter_)); | 69 callback.Run(scoped_refptr<device::BluetoothAdapter>(adapter_)); |
| 70 return; | 70 return; |
| 71 } | 71 } |
| 72 | 72 |
| 73 device::BluetoothAdapterFactory::GetAdapter(callback); | 73 device::BluetoothAdapterFactory::GetAdapter(callback); |
| 74 } | 74 } |
| 75 | 75 |
| 76 void BluetoothEventRouter::StartDiscoverySession( | 76 void BluetoothEventRouter::StartDiscoverySession( |
| 77 device::BluetoothAdapter* adapter, | 77 device::BluetoothAdapter* adapter, |
| 78 const std::string& extension_id, | 78 const std::string& extension_id, |
| 79 const base::Closure& callback, | 79 const base::Closure& callback, |
| 80 const base::Closure& error_callback) { | 80 const base::Closure& error_callback) { |
| 81 if (adapter != adapter_.get()) { | 81 if (!adapter_.get() && IsBluetoothSupported()) { |
| 82 GetAdapter(base::Bind( | |
| 83 &BluetoothEventRouter::OnAdapterInitialized, | |
| 84 weak_ptr_factory_.GetWeakPtr(), | |
| 85 base::Bind(&BluetoothEventRouter::StartDiscoverySessionImpl, | |
| 86 weak_ptr_factory_.GetWeakPtr(), make_scoped_refptr(adapter), | |
| 87 extension_id, callback, error_callback))); | |
| 88 return; | |
| 89 } | |
| 90 StartDiscoverySessionImpl(adapter, extension_id, callback, error_callback); | |
| 91 } | |
| 92 | |
| 93 void BluetoothEventRouter::StartDiscoverySessionImpl( | |
| 94 device::BluetoothAdapter* adapter, | |
| 95 const std::string& extension_id, | |
| 96 const base::Closure& callback, | |
| 97 const base::Closure& error_callback) { | |
| 98 if (!adapter_.get() || adapter != adapter_.get()) { | |
| 99 if (adapter_.get()) { | |
| 100 LOG(ERROR) << "Unable to get addapter"; | |
| 101 } else { | |
| 102 LOG(ERROR) << "Adapter mismatch"; | |
| 103 } | |
| 82 error_callback.Run(); | 104 error_callback.Run(); |
| 83 return; | 105 return; |
| 84 } | 106 } |
| 85 DiscoverySessionMap::iterator iter = | 107 DiscoverySessionMap::iterator iter = |
| 86 discovery_session_map_.find(extension_id); | 108 discovery_session_map_.find(extension_id); |
| 87 if (iter != discovery_session_map_.end() && iter->second->IsActive()) { | 109 if (iter != discovery_session_map_.end() && iter->second->IsActive()) { |
| 88 DVLOG(1) << "An active discovery session exists for extension."; | 110 DVLOG(1) << "An active discovery session exists for extension."; |
| 89 error_callback.Run(); | 111 error_callback.Run(); |
| 90 return; | 112 return; |
| 91 } | 113 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 | 176 |
| 155 // extension is already running discovery, update it's discovery filter | 177 // extension is already running discovery, update it's discovery filter |
| 156 iter->second->SetDiscoveryFilter(discovery_filter.Pass(), callback, | 178 iter->second->SetDiscoveryFilter(discovery_filter.Pass(), callback, |
| 157 error_callback); | 179 error_callback); |
| 158 } | 180 } |
| 159 | 181 |
| 160 BluetoothApiPairingDelegate* BluetoothEventRouter::GetPairingDelegate( | 182 BluetoothApiPairingDelegate* BluetoothEventRouter::GetPairingDelegate( |
| 161 const std::string& extension_id) { | 183 const std::string& extension_id) { |
| 162 return ContainsKey(pairing_delegate_map_, extension_id) | 184 return ContainsKey(pairing_delegate_map_, extension_id) |
| 163 ? pairing_delegate_map_[extension_id] | 185 ? pairing_delegate_map_[extension_id] |
| 164 : NULL; | 186 : nullptr; |
| 165 } | 187 } |
| 166 | 188 |
| 167 void BluetoothEventRouter::OnAdapterInitialized( | 189 void BluetoothEventRouter::OnAdapterInitialized( |
| 168 const base::Closure& callback, | 190 const base::Closure& callback, |
| 169 scoped_refptr<device::BluetoothAdapter> adapter) { | 191 scoped_refptr<device::BluetoothAdapter> adapter) { |
| 170 if (!adapter_.get()) { | 192 if (!adapter_.get()) { |
| 171 adapter_ = adapter; | 193 adapter_ = adapter; |
| 172 adapter_->AddObserver(this); | 194 adapter_->AddObserver(this); |
| 173 } | 195 } |
| 174 | 196 |
| 175 callback.Run(); | 197 callback.Run(); |
| 176 } | 198 } |
| 177 | 199 |
| 178 void BluetoothEventRouter::MaybeReleaseAdapter() { | 200 void BluetoothEventRouter::MaybeReleaseAdapter() { |
| 179 if (adapter_.get() && num_event_listeners_ == 0 && | 201 if (adapter_.get() && num_event_listeners_ == 0 && |
| 180 pairing_delegate_map_.empty()) { | 202 pairing_delegate_map_.empty()) { |
| 203 VLOG(1) << "Releasing Adapter."; | |
| 181 adapter_->RemoveObserver(this); | 204 adapter_->RemoveObserver(this); |
| 182 adapter_ = NULL; | 205 adapter_ = nullptr; |
| 183 } | 206 } |
| 184 } | 207 } |
| 185 | 208 |
| 186 void BluetoothEventRouter::AddPairingDelegate(const std::string& extension_id) { | 209 void BluetoothEventRouter::AddPairingDelegate(const std::string& extension_id) { |
| 187 if (!adapter_.get()) { | 210 if (!adapter_.get() && IsBluetoothSupported()) { |
| 188 base::Closure self_callback = | 211 GetAdapter( |
| 189 base::Bind(&BluetoothEventRouter::AddPairingDelegate, | 212 base::Bind(&BluetoothEventRouter::OnAdapterInitialized, |
| 190 weak_ptr_factory_.GetWeakPtr(), | 213 weak_ptr_factory_.GetWeakPtr(), |
| 191 extension_id); | 214 base::Bind(&BluetoothEventRouter::AddPairingDelegateImpl, |
| 192 GetAdapter(base::Bind(&BluetoothEventRouter::OnAdapterInitialized, | 215 weak_ptr_factory_.GetWeakPtr(), extension_id))); |
| 193 weak_ptr_factory_.GetWeakPtr(), | |
| 194 self_callback)); | |
|
stevenjb
2015/10/15 22:13:25
This could potentially generate an infinite loop i
| |
| 195 return; | 216 return; |
| 196 } | 217 } |
| 218 AddPairingDelegateImpl(extension_id); | |
| 219 } | |
| 197 | 220 |
| 221 void BluetoothEventRouter::AddPairingDelegateImpl( | |
| 222 const std::string& extension_id) { | |
| 223 if (!adapter_.get()) { | |
| 224 LOG(ERROR) << "Unable to get adatper."; | |
| 225 return; | |
| 226 } | |
| 198 if (!ContainsKey(pairing_delegate_map_, extension_id)) { | 227 if (!ContainsKey(pairing_delegate_map_, extension_id)) { |
| 199 BluetoothApiPairingDelegate* delegate = | 228 BluetoothApiPairingDelegate* delegate = |
| 200 new BluetoothApiPairingDelegate(extension_id, browser_context_); | 229 new BluetoothApiPairingDelegate(extension_id, browser_context_); |
| 201 DCHECK(adapter_.get()); | 230 DCHECK(adapter_.get()); |
| 202 adapter_->AddPairingDelegate( | 231 adapter_->AddPairingDelegate( |
| 203 delegate, device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH); | 232 delegate, device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH); |
| 204 pairing_delegate_map_[extension_id] = delegate; | 233 pairing_delegate_map_[extension_id] = delegate; |
| 205 } else { | 234 } else { |
| 206 LOG(ERROR) << "Pairing delegate already exists for extension. " | 235 LOG(ERROR) << "Pairing delegate already exists for extension. " |
| 207 << "There should be at most one onPairing listener."; | 236 << "There should be at most one onPairing listener."; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 iter != discovery_session_map_.end(); | 288 iter != discovery_session_map_.end(); |
| 260 ++iter) { | 289 ++iter) { |
| 261 device::BluetoothDiscoverySession* session = iter->second; | 290 device::BluetoothDiscoverySession* session = iter->second; |
| 262 if (session->IsActive()) { | 291 if (session->IsActive()) { |
| 263 active_session_map[iter->first] = session; | 292 active_session_map[iter->first] = session; |
| 264 continue; | 293 continue; |
| 265 } | 294 } |
| 266 delete session; | 295 delete session; |
| 267 } | 296 } |
| 268 discovery_session_map_.swap(active_session_map); | 297 discovery_session_map_.swap(active_session_map); |
| 269 MaybeReleaseAdapter(); | |
|
stevenjb
2015/10/15 22:13:25
This was destroying the adapter before DispatchAda
| |
| 270 } | 298 } |
| 271 | 299 |
| 272 DispatchAdapterStateEvent(); | 300 DispatchAdapterStateEvent(); |
| 301 | |
| 302 // Release the adapter after dispatching the event. | |
| 303 if (!discovering) | |
| 304 MaybeReleaseAdapter(); | |
| 273 } | 305 } |
| 274 | 306 |
| 275 void BluetoothEventRouter::DeviceAdded(device::BluetoothAdapter* adapter, | 307 void BluetoothEventRouter::DeviceAdded(device::BluetoothAdapter* adapter, |
| 276 device::BluetoothDevice* device) { | 308 device::BluetoothDevice* device) { |
| 277 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 309 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 278 if (adapter != adapter_.get()) { | 310 if (adapter != adapter_.get()) { |
| 279 DVLOG(1) << "Ignoring event for adapter " << adapter->GetAddress(); | 311 DVLOG(1) << "Ignoring event for adapter " << adapter->GetAddress(); |
| 280 return; | 312 return; |
| 281 } | 313 } |
| 282 | 314 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 | 352 |
| 321 void BluetoothEventRouter::OnListenerRemoved() { | 353 void BluetoothEventRouter::OnListenerRemoved() { |
| 322 if (num_event_listeners_ > 0) | 354 if (num_event_listeners_ > 0) |
| 323 num_event_listeners_--; | 355 num_event_listeners_--; |
| 324 MaybeReleaseAdapter(); | 356 MaybeReleaseAdapter(); |
| 325 } | 357 } |
| 326 | 358 |
| 327 void BluetoothEventRouter::DispatchAdapterStateEvent() { | 359 void BluetoothEventRouter::DispatchAdapterStateEvent() { |
| 328 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 360 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 329 api::bluetooth::AdapterState state; | 361 api::bluetooth::AdapterState state; |
| 362 CHECK(adapter_.get()); | |
| 330 PopulateAdapterState(*adapter_.get(), &state); | 363 PopulateAdapterState(*adapter_.get(), &state); |
| 331 | 364 |
| 332 scoped_ptr<base::ListValue> args = | 365 scoped_ptr<base::ListValue> args = |
| 333 bluetooth::OnAdapterStateChanged::Create(state); | 366 bluetooth::OnAdapterStateChanged::Create(state); |
| 334 scoped_ptr<Event> event( | 367 scoped_ptr<Event> event( |
| 335 new Event(events::BLUETOOTH_ON_ADAPTER_STATE_CHANGED, | 368 new Event(events::BLUETOOTH_ON_ADAPTER_STATE_CHANGED, |
| 336 bluetooth::OnAdapterStateChanged::kEventName, args.Pass())); | 369 bluetooth::OnAdapterStateChanged::kEventName, args.Pass())); |
| 337 EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); | 370 EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); |
| 338 } | 371 } |
| 339 | 372 |
| 340 void BluetoothEventRouter::DispatchDeviceEvent( | 373 void BluetoothEventRouter::DispatchDeviceEvent( |
| 341 events::HistogramValue histogram_value, | 374 events::HistogramValue histogram_value, |
| 342 const std::string& event_name, | 375 const std::string& event_name, |
| 343 device::BluetoothDevice* device) { | 376 device::BluetoothDevice* device) { |
| 344 bluetooth::Device extension_device; | 377 bluetooth::Device extension_device; |
| 378 CHECK(device); | |
| 345 bluetooth::BluetoothDeviceToApiDevice(*device, &extension_device); | 379 bluetooth::BluetoothDeviceToApiDevice(*device, &extension_device); |
| 346 | 380 |
| 347 scoped_ptr<base::ListValue> args = | 381 scoped_ptr<base::ListValue> args = |
| 348 bluetooth::OnDeviceAdded::Create(extension_device); | 382 bluetooth::OnDeviceAdded::Create(extension_device); |
| 349 scoped_ptr<Event> event(new Event(histogram_value, event_name, args.Pass())); | 383 scoped_ptr<Event> event(new Event(histogram_value, event_name, args.Pass())); |
| 350 EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); | 384 EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); |
| 351 } | 385 } |
| 352 | 386 |
| 353 void BluetoothEventRouter::CleanUpForExtension( | 387 void BluetoothEventRouter::CleanUpForExtension( |
| 354 const std::string& extension_id) { | 388 const std::string& extension_id) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 } | 451 } |
| 418 | 452 |
| 419 void BluetoothEventRouter::OnExtensionUnloaded( | 453 void BluetoothEventRouter::OnExtensionUnloaded( |
| 420 content::BrowserContext* browser_context, | 454 content::BrowserContext* browser_context, |
| 421 const Extension* extension, | 455 const Extension* extension, |
| 422 UnloadedExtensionInfo::Reason reason) { | 456 UnloadedExtensionInfo::Reason reason) { |
| 423 CleanUpForExtension(extension->id()); | 457 CleanUpForExtension(extension->id()); |
| 424 } | 458 } |
| 425 | 459 |
| 426 } // namespace extensions | 460 } // namespace extensions |
| OLD | NEW |