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 void RunAdapterCallbacks() { 46 CHECK(default_adapter.Get().get()); 47 scoped_refptr<BluetoothAdapter> adapter(default_adapter.Get().get()); 48 for (std::vector<BluetoothAdapterFactory::AdapterCallback>::const_iterator 49 iter = adapter_callbacks.Get().begin(); 50 iter != adapter_callbacks.Get().end(); 51 ++iter) { 52 iter->Run(adapter); 53 } 54 adapter_callbacks.Get().clear(); 55 } 56 57 } // namespace 58 59 namespace device { 60 61 // static 62 bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() { 63 #if defined(OS_CHROMEOS) 64 return true; 65 #elif defined(OS_WIN) 66 return true; 67 #elif defined(OS_MACOSX) 68 return base::mac::IsOSLionOrLater(); 69 #endif 70 return false; 71 } 72 73 // static 74 void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) { 75 if (!default_adapter.Get().get()) { 76 #if defined(OS_CHROMEOS) 77 chromeos::BluetoothAdapterChromeOS* new_adapter = 78 new chromeos::BluetoothAdapterChromeOS(); 79 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); 80 #elif defined(OS_WIN) 81 BluetoothAdapterWin* new_adapter = new BluetoothAdapterWin( 82 base::Bind(&RunAdapterCallbacks)); 83 new_adapter->Init(); 84 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); 85 #elif defined(OS_MACOSX) 86 BluetoothAdapterMac* new_adapter = new BluetoothAdapterMac(); 87 new_adapter->Init(); 88 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); 89 #endif 90 } 91 92 if (default_adapter.Get()->IsInitialized()) { 93 callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get())); 94 } else { 95 adapter_callbacks.Get().push_back(callback); 96 } 97 } 98 99 // static 100 scoped_refptr<BluetoothAdapter> BluetoothAdapterFactory::MaybeGetAdapter() { 101 return scoped_refptr<BluetoothAdapter>(default_adapter.Get().get()); 102 } 103 104 } // namespace device 105