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