• 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_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 
RunAdapterCallbacks()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
IsBluetoothAdapterAvailable()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
GetAdapter(const AdapterCallback & callback)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
SetAdapterForTesting(scoped_refptr<BluetoothAdapter> adapter)98 void BluetoothAdapterFactory::SetAdapterForTesting(
99     scoped_refptr<BluetoothAdapter> adapter) {
100   default_adapter.Get() = adapter->GetWeakPtrForTesting();
101 }
102 
103 // static
HasSharedInstanceForTesting()104 bool BluetoothAdapterFactory::HasSharedInstanceForTesting() {
105   return default_adapter.Get();
106 }
107 
108 }  // namespace device
109