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 3 // found in the LICENSE file. 4 5 #include "device/bluetooth/bluetooth_adapter_factory.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/lazy_instance.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/weak_ptr.h" 13 #include "device/bluetooth/bluetooth_adapter.h" 14 15 #if defined(OS_CHROMEOS) 16 #include "device/bluetooth/bluetooth_adapter_chromeos.h" 17 #elif defined(OS_WIN) 18 #include "device/bluetooth/bluetooth_adapter_win.h" 19 #elif defined(OS_MACOSX) 20 #include "base/mac/mac_util.h" 21 #include "device/bluetooth/bluetooth_adapter_mac.h" 22 #endif 23 24 namespace { 25 26 using device::BluetoothAdapter; 27 using device::BluetoothAdapterFactory; 28 29 // Shared default adapter instance, we don't want to keep this class around 30 // if nobody is using it so use a WeakPtr and create the object when needed; 31 // since Google C++ Style (and clang's static analyzer) forbids us having 32 // exit-time destructors we use a leaky lazy instance for it. 33 base::LazyInstance<base::WeakPtr<device::BluetoothAdapter> >::Leaky 34 default_adapter = LAZY_INSTANCE_INITIALIZER; 35 36 typedef std::vector<BluetoothAdapterFactory::AdapterCallback> 37 AdapterCallbackList; 38 39 // List of adapter callbacks to be called once the adapter is initialized. 40 // Since Google C++ Style (and clang's static analyzer) forbids us having 41 // exit-time destructors we use a lazy instance for it. 42 base::LazyInstance<AdapterCallbackList> adapter_callbacks = 43 LAZY_INSTANCE_INITIALIZER; 44 45 #if defined(OS_WIN) 46 void RunAdapterCallbacks() { 47 CHECK(default_adapter.Get().get()); 48 scoped_refptr<BluetoothAdapter> adapter(default_adapter.Get().get()); 49 for (std::vector<BluetoothAdapterFactory::AdapterCallback>::const_iterator 50 iter = adapter_callbacks.Get().begin(); 51 iter != adapter_callbacks.Get().end(); 52 ++iter) { 53 iter->Run(adapter); 54 } 55 adapter_callbacks.Get().clear(); 56 } 57 #endif // defined(OS_WIN) 58 59 } // namespace 60 61 namespace device { 62 63 // static 64 bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() { 65 #if defined(OS_CHROMEOS) 66 return true; 67 #elif defined(OS_WIN) 68 return true; 69 #elif defined(OS_MACOSX) 70 return base::mac::IsOSLionOrLater(); 71 #endif 72 return false; 73 } 74 75 // static 76 void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) { 77 if (!default_adapter.Get().get()) { 78 #if defined(OS_CHROMEOS) 79 chromeos::BluetoothAdapterChromeOS* new_adapter = 80 new chromeos::BluetoothAdapterChromeOS(); 81 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); 82 #elif defined(OS_WIN) 83 BluetoothAdapterWin* new_adapter = new BluetoothAdapterWin( 84 base::Bind(&RunAdapterCallbacks)); 85 new_adapter->Init(); 86 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); 87 #elif defined(OS_MACOSX) 88 BluetoothAdapterMac* new_adapter = new BluetoothAdapterMac(); 89 new_adapter->Init(); 90 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); 91 #endif 92 } 93 94 if (default_adapter.Get()->IsInitialized()) { 95 callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get())); 96 } else { 97 adapter_callbacks.Get().push_back(callback); 98 } 99 } 100 101 // static 102 scoped_refptr<BluetoothAdapter> BluetoothAdapterFactory::MaybeGetAdapter() { 103 return scoped_refptr<BluetoothAdapter>(default_adapter.Get().get()); 104 } 105 106 } // namespace device 107