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_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