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_MACOSX) 16 #include "base/mac/mac_util.h" 17 #endif 18 19 namespace device { 20 21 namespace { 22 23 // Shared default adapter instance. We don't want to keep this class around 24 // if nobody is using it, so use a WeakPtr and create the object when needed. 25 // Since Google C++ Style (and clang's static analyzer) forbids us having 26 // exit-time destructors, we use a leaky lazy instance for it. 27 base::LazyInstance<base::WeakPtr<BluetoothAdapter> >::Leaky default_adapter = 28 LAZY_INSTANCE_INITIALIZER; 29 30 #if defined(OS_WIN) 31 typedef std::vector<BluetoothAdapterFactory::AdapterCallback> 32 AdapterCallbackList; 33 34 // List of adapter callbacks to be called once the adapter is initialized. 35 // Since Google C++ Style (and clang's static analyzer) forbids us having 36 // exit-time destructors we use a lazy instance for it. 37 base::LazyInstance<AdapterCallbackList> adapter_callbacks = 38 LAZY_INSTANCE_INITIALIZER; 39 40 void RunAdapterCallbacks() { 41 DCHECK(default_adapter.Get()); 42 scoped_refptr<BluetoothAdapter> adapter(default_adapter.Get().get()); 43 for (std::vector<BluetoothAdapterFactory::AdapterCallback>::const_iterator 44 iter = adapter_callbacks.Get().begin(); 45 iter != adapter_callbacks.Get().end(); 46 ++iter) { 47 iter->Run(adapter); 48 } 49 adapter_callbacks.Get().clear(); 50 } 51 #endif // defined(OS_WIN) 52 53 } // namespace 54 55 // static 56 bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() { 57 // SetAdapterForTesting() may be used to provide a test or mock adapter 58 // instance even on platforms that would otherwise not support it. 59 if (default_adapter.Get()) 60 return true; 61 #if defined(OS_CHROMEOS) || defined(OS_WIN) 62 return true; 63 #elif defined(OS_MACOSX) 64 return base::mac::IsOSLionOrLater(); 65 #else 66 return false; 67 #endif 68 } 69 70 // static 71 void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) { 72 DCHECK(IsBluetoothAdapterAvailable()); 73 74 #if defined(OS_WIN) 75 if (!default_adapter.Get()) { 76 default_adapter.Get() = 77 BluetoothAdapter::CreateAdapter(base::Bind(&RunAdapterCallbacks)); 78 DCHECK(!default_adapter.Get()->IsInitialized()); 79 } 80 81 if (!default_adapter.Get()->IsInitialized()) 82 adapter_callbacks.Get().push_back(callback); 83 #else // !defined(OS_WIN) 84 if (!default_adapter.Get()) { 85 default_adapter.Get() = 86 BluetoothAdapter::CreateAdapter(BluetoothAdapter::InitCallback()); 87 } 88 89 DCHECK(default_adapter.Get()->IsInitialized()); 90 #endif // defined(OS_WIN) 91 92 if (default_adapter.Get()->IsInitialized()) 93 callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get())); 94 95 } 96 97 // static 98 void BluetoothAdapterFactory::SetAdapterForTesting( 99 scoped_refptr<BluetoothAdapter> adapter) { 100 default_adapter.Get() = adapter->GetWeakPtrForTesting(); 101 } 102 103 // static 104 bool BluetoothAdapterFactory::HasSharedInstanceForTesting() { 105 return default_adapter.Get(); 106 } 107 108 } // namespace device 109