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 24namespace { 25 26using device::BluetoothAdapter; 27using 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. 33base::LazyInstance<base::WeakPtr<device::BluetoothAdapter> >::Leaky 34 default_adapter = LAZY_INSTANCE_INITIALIZER; 35 36typedef 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. 42base::LazyInstance<AdapterCallbackList> adapter_callbacks = 43 LAZY_INSTANCE_INITIALIZER; 44 45#if defined(OS_WIN) 46void 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 61namespace device { 62 63// static 64bool 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 76void 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 102scoped_refptr<BluetoothAdapter> BluetoothAdapterFactory::MaybeGetAdapter() { 103 return scoped_refptr<BluetoothAdapter>(default_adapter.Get().get()); 104} 105 106} // namespace device 107