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.
5 #include "device/bluetooth/bluetooth_adapter.h"
8 #include "base/metrics/histogram_macros.h"
9 #include "base/stl_util.h"
10 #include "device/bluetooth/bluetooth_device.h"
11 #include "device/bluetooth/bluetooth_discovery_session.h"
12 #include "device/bluetooth/bluetooth_discovery_session_outcome.h"
16 BluetoothAdapter::ServiceOptions::ServiceOptions() {
18 BluetoothAdapter::ServiceOptions::~ServiceOptions() {
21 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && !defined(OS_MACOSX) && \
24 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::CreateAdapter(
25 const InitCallback
& init_callback
) {
26 return base::WeakPtr
<BluetoothAdapter
>();
28 #endif // !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
30 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::GetWeakPtrForTesting() {
31 return weak_ptr_factory_
.GetWeakPtr();
34 #if defined(OS_CHROMEOS)
35 void BluetoothAdapter::Shutdown() {
40 void BluetoothAdapter::AddObserver(BluetoothAdapter::Observer
* observer
) {
42 observers_
.AddObserver(observer
);
45 void BluetoothAdapter::RemoveObserver(BluetoothAdapter::Observer
* observer
) {
47 observers_
.RemoveObserver(observer
);
50 void BluetoothAdapter::StartDiscoverySession(
51 const DiscoverySessionCallback
& callback
,
52 const ErrorCallback
& error_callback
) {
53 StartDiscoverySessionWithFilter(nullptr, callback
, error_callback
);
56 void BluetoothAdapter::StartDiscoverySessionWithFilter(
57 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
58 const DiscoverySessionCallback
& callback
,
59 const ErrorCallback
& error_callback
) {
60 BluetoothDiscoveryFilter
* ptr
= discovery_filter
.get();
62 ptr
, base::Bind(&BluetoothAdapter::OnStartDiscoverySession
,
63 weak_ptr_factory_
.GetWeakPtr(),
64 base::Passed(&discovery_filter
), callback
),
65 base::Bind(&BluetoothAdapter::OnStartDiscoverySessionError
,
66 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
69 scoped_ptr
<BluetoothDiscoveryFilter
>
70 BluetoothAdapter::GetMergedDiscoveryFilter() const {
71 return GetMergedDiscoveryFilterHelper(nullptr, false);
74 scoped_ptr
<BluetoothDiscoveryFilter
>
75 BluetoothAdapter::GetMergedDiscoveryFilterMasked(
76 BluetoothDiscoveryFilter
* masked_filter
) const {
77 return GetMergedDiscoveryFilterHelper(masked_filter
, true);
80 BluetoothAdapter::DeviceList
BluetoothAdapter::GetDevices() {
81 ConstDeviceList const_devices
=
82 const_cast<const BluetoothAdapter
*>(this)->GetDevices();
85 for (ConstDeviceList::const_iterator i
= const_devices
.begin();
86 i
!= const_devices
.end(); ++i
)
87 devices
.push_back(const_cast<BluetoothDevice
*>(*i
));
92 BluetoothAdapter::ConstDeviceList
BluetoothAdapter::GetDevices() const {
93 ConstDeviceList devices
;
94 for (DevicesMap::const_iterator iter
= devices_
.begin();
95 iter
!= devices_
.end();
97 devices
.push_back(iter
->second
);
102 BluetoothDevice
* BluetoothAdapter::GetDevice(const std::string
& address
) {
103 return const_cast<BluetoothDevice
*>(
104 const_cast<const BluetoothAdapter
*>(this)->GetDevice(address
));
107 const BluetoothDevice
* BluetoothAdapter::GetDevice(
108 const std::string
& address
) const {
109 std::string canonicalized_address
=
110 BluetoothDevice::CanonicalizeAddress(address
);
111 if (canonicalized_address
.empty())
114 DevicesMap::const_iterator iter
= devices_
.find(canonicalized_address
);
115 if (iter
!= devices_
.end())
121 void BluetoothAdapter::AddPairingDelegate(
122 BluetoothDevice::PairingDelegate
* pairing_delegate
,
123 PairingDelegatePriority priority
) {
124 // Remove the delegate, if it already exists, before inserting to allow a
125 // change of priority.
126 RemovePairingDelegate(pairing_delegate
);
128 // Find the first point with a lower priority, or the end of the list.
129 std::list
<PairingDelegatePair
>::iterator iter
= pairing_delegates_
.begin();
130 while (iter
!= pairing_delegates_
.end() && iter
->second
>= priority
)
133 pairing_delegates_
.insert(iter
, std::make_pair(pairing_delegate
, priority
));
136 void BluetoothAdapter::RemovePairingDelegate(
137 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
138 for (std::list
<PairingDelegatePair
>::iterator iter
=
139 pairing_delegates_
.begin(); iter
!= pairing_delegates_
.end(); ++iter
) {
140 if (iter
->first
== pairing_delegate
) {
141 RemovePairingDelegateInternal(pairing_delegate
);
142 pairing_delegates_
.erase(iter
);
148 BluetoothDevice::PairingDelegate
* BluetoothAdapter::DefaultPairingDelegate() {
149 if (pairing_delegates_
.empty())
152 return pairing_delegates_
.front().first
;
155 BluetoothAdapter::BluetoothAdapter() : weak_ptr_factory_(this) {
158 BluetoothAdapter::~BluetoothAdapter() {
159 STLDeleteValues(&devices_
);
162 void BluetoothAdapter::OnStartDiscoverySession(
163 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
164 const DiscoverySessionCallback
& callback
) {
165 VLOG(1) << "BluetoothAdapter::OnStartDiscoverySession";
166 RecordBluetoothDiscoverySessionStartOutcome(
167 UMABluetoothDiscoverySessionOutcome::SUCCESS
);
169 scoped_ptr
<BluetoothDiscoverySession
> discovery_session(
170 new BluetoothDiscoverySession(scoped_refptr
<BluetoothAdapter
>(this),
171 discovery_filter
.Pass()));
172 discovery_sessions_
.insert(discovery_session
.get());
173 callback
.Run(discovery_session
.Pass());
176 void BluetoothAdapter::OnStartDiscoverySessionError(
177 const ErrorCallback
& callback
,
178 UMABluetoothDiscoverySessionOutcome outcome
) {
179 VLOG(1) << "OnStartDiscoverySessionError: " << static_cast<int>(outcome
);
180 RecordBluetoothDiscoverySessionStartOutcome(outcome
);
184 void BluetoothAdapter::MarkDiscoverySessionsAsInactive() {
185 // As sessions are marked as inactive they will notify the adapter that they
186 // have become inactive, upon which the adapter will remove them from
187 // |discovery_sessions_|. To avoid invalidating the iterator, make a copy
189 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
190 for (std::set
<BluetoothDiscoverySession
*>::iterator
192 iter
!= temp
.end(); ++iter
) {
193 (*iter
)->MarkAsInactive();
197 void BluetoothAdapter::DiscoverySessionBecameInactive(
198 BluetoothDiscoverySession
* discovery_session
) {
199 DCHECK(!discovery_session
->IsActive());
200 discovery_sessions_
.erase(discovery_session
);
203 scoped_ptr
<BluetoothDiscoveryFilter
>
204 BluetoothAdapter::GetMergedDiscoveryFilterHelper(
205 const BluetoothDiscoveryFilter
* masked_filter
,
207 scoped_ptr
<BluetoothDiscoveryFilter
> result
;
208 bool first_merge
= true;
210 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
211 for (const auto& iter
: temp
) {
212 const BluetoothDiscoveryFilter
* curr_filter
= iter
->GetDiscoveryFilter();
214 if (!iter
->IsActive())
217 if (omit
&& curr_filter
== masked_filter
) {
218 // if masked_filter is pointing to empty filter, and there are
219 // multiple empty filters in discovery_sessions_, make sure we'll
220 // process next empty sessions.
228 result
.reset(new BluetoothDiscoveryFilter(
229 BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL
));
230 result
->CopyFrom(*curr_filter
);
235 result
= BluetoothDiscoveryFilter::Merge(result
.get(), curr_filter
);
238 return result
.Pass();
242 void BluetoothAdapter::RecordBluetoothDiscoverySessionStartOutcome(
243 UMABluetoothDiscoverySessionOutcome outcome
) {
244 UMA_HISTOGRAM_ENUMERATION(
245 "Bluetooth.DiscoverySession.Start.Outcome", static_cast<int>(outcome
),
246 static_cast<int>(UMABluetoothDiscoverySessionOutcome::COUNT
));
250 void BluetoothAdapter::RecordBluetoothDiscoverySessionStopOutcome(
251 UMABluetoothDiscoverySessionOutcome outcome
) {
252 UMA_HISTOGRAM_ENUMERATION(
253 "Bluetooth.DiscoverySession.Stop.Outcome", static_cast<int>(outcome
),
254 static_cast<int>(UMABluetoothDiscoverySessionOutcome::COUNT
));
257 } // namespace device