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 19namespace device { 20 21namespace { 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. 27base::LazyInstance<base::WeakPtr<BluetoothAdapter> >::Leaky default_adapter = 28 LAZY_INSTANCE_INITIALIZER; 29 30#if defined(OS_WIN) 31typedef 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. 37base::LazyInstance<AdapterCallbackList> adapter_callbacks = 38 LAZY_INSTANCE_INITIALIZER; 39 40void 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 56bool 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 71void 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 98void BluetoothAdapterFactory::SetAdapterForTesting( 99 scoped_refptr<BluetoothAdapter> adapter) { 100 default_adapter.Get() = adapter->GetWeakPtrForTesting(); 101} 102 103// static 104bool BluetoothAdapterFactory::HasSharedInstanceForTesting() { 105 return default_adapter.Get(); 106} 107 108} // namespace device 109