// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "device/bluetooth/bluetooth_adapter_factory.h" #include #include "base/bind.h" #include "base/lazy_instance.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "device/bluetooth/bluetooth_adapter.h" #if defined(OS_MACOSX) #include "base/mac/mac_util.h" #endif namespace device { namespace { // Shared default adapter instance. We don't want to keep this class around // if nobody is using it, so use a WeakPtr and create the object when needed. // Since Google C++ Style (and clang's static analyzer) forbids us having // exit-time destructors, we use a leaky lazy instance for it. base::LazyInstance >::Leaky default_adapter = LAZY_INSTANCE_INITIALIZER; #if defined(OS_WIN) typedef std::vector AdapterCallbackList; // List of adapter callbacks to be called once the adapter is initialized. // Since Google C++ Style (and clang's static analyzer) forbids us having // exit-time destructors we use a lazy instance for it. base::LazyInstance adapter_callbacks = LAZY_INSTANCE_INITIALIZER; void RunAdapterCallbacks() { DCHECK(default_adapter.Get()); scoped_refptr adapter(default_adapter.Get().get()); for (std::vector::const_iterator iter = adapter_callbacks.Get().begin(); iter != adapter_callbacks.Get().end(); ++iter) { iter->Run(adapter); } adapter_callbacks.Get().clear(); } #endif // defined(OS_WIN) } // namespace // static bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() { // SetAdapterForTesting() may be used to provide a test or mock adapter // instance even on platforms that would otherwise not support it. if (default_adapter.Get()) return true; #if defined(OS_CHROMEOS) || defined(OS_WIN) return true; #elif defined(OS_MACOSX) return base::mac::IsOSLionOrLater(); #else return false; #endif } // static void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) { DCHECK(IsBluetoothAdapterAvailable()); #if defined(OS_WIN) if (!default_adapter.Get()) { default_adapter.Get() = BluetoothAdapter::CreateAdapter(base::Bind(&RunAdapterCallbacks)); DCHECK(!default_adapter.Get()->IsInitialized()); } if (!default_adapter.Get()->IsInitialized()) adapter_callbacks.Get().push_back(callback); #else // !defined(OS_WIN) if (!default_adapter.Get()) { default_adapter.Get() = BluetoothAdapter::CreateAdapter(BluetoothAdapter::InitCallback()); } DCHECK(default_adapter.Get()->IsInitialized()); #endif // defined(OS_WIN) if (default_adapter.Get()->IsInitialized()) callback.Run(scoped_refptr(default_adapter.Get().get())); } // static void BluetoothAdapterFactory::SetAdapterForTesting( scoped_refptr adapter) { default_adapter.Get() = adapter->GetWeakPtrForTesting(); } // static bool BluetoothAdapterFactory::HasSharedInstanceForTesting() { return default_adapter.Get(); } } // namespace device