• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
RunAdapterCallbacks()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
IsBluetoothAdapterAvailable()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
GetAdapter(const AdapterCallback & callback)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
MaybeGetAdapter()102 scoped_refptr<BluetoothAdapter> BluetoothAdapterFactory::MaybeGetAdapter() {
103   return scoped_refptr<BluetoothAdapter>(default_adapter.Get().get());
104 }
105 
106 }  // namespace device
107