15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_MACOSX) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/mac/mac_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace device { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Shared default adapter instance. We don't want to keep this class around 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// if nobody is using it, so use a WeakPtr and create the object when needed. 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Since Google C++ Style (and clang's static analyzer) forbids us having 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// exit-time destructors, we use a leaky lazy instance for it. 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::LazyInstance<base::WeakPtr<BluetoothAdapter> >::Leaky default_adapter = 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch LAZY_INSTANCE_INITIALIZER; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_WIN) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<BluetoothAdapterFactory::AdapterCallback> 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AdapterCallbackList; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// List of adapter callbacks to be called once the adapter is initialized. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Since Google C++ Style (and clang's static analyzer) forbids us having 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// exit-time destructors we use a lazy instance for it. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::LazyInstance<AdapterCallbackList> adapter_callbacks = 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RunAdapterCallbacks() { 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(default_adapter.Get()); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<BluetoothAdapter> adapter(default_adapter.Get().get()); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<BluetoothAdapterFactory::AdapterCallback>::const_iterator 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter = adapter_callbacks.Get().begin(); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != adapter_callbacks.Get().end(); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->Run(adapter); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adapter_callbacks.Get().clear(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // defined(OS_WIN) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() { 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // SetAdapterForTesting() may be used to provide a test or mock adapter 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // instance even on platforms that would otherwise not support it. 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (default_adapter.Get()) 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(OS_CHROMEOS) || defined(OS_WIN) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#elif defined(OS_MACOSX) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::mac::IsOSLionOrLater(); 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) { 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(IsBluetoothAdapterAvailable()); 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_WIN) 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!default_adapter.Get()) { 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch default_adapter.Get() = 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch BluetoothAdapter::CreateAdapter(base::Bind(&RunAdapterCallbacks)); 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(!default_adapter.Get()->IsInitialized()); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!default_adapter.Get()->IsInitialized()) 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_callbacks.Get().push_back(callback); 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#else // !defined(OS_WIN) 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!default_adapter.Get()) { 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch default_adapter.Get() = 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch BluetoothAdapter::CreateAdapter(BluetoothAdapter::InitCallback()); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(default_adapter.Get()->IsInitialized()); 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif // defined(OS_WIN) 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (default_adapter.Get()->IsInitialized()) 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get())); 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothAdapterFactory::SetAdapterForTesting( 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<BluetoothAdapter> adapter) { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) default_adapter.Get() = adapter->GetWeakPtrForTesting(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool BluetoothAdapterFactory::HasSharedInstanceForTesting() { 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return default_adapter.Get(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace device 109