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/stl_util.h"
9 #include "device/bluetooth/bluetooth_device.h"
10 #include "device/bluetooth/bluetooth_discovery_session.h"
14 BluetoothAdapter::ServiceOptions::ServiceOptions() {
16 BluetoothAdapter::ServiceOptions::~ServiceOptions() {
19 #if !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
21 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::CreateAdapter(
22 const InitCallback
& init_callback
) {
23 return base::WeakPtr
<BluetoothAdapter
>();
25 #endif // !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
27 #if defined(OS_CHROMEOS)
28 void BluetoothAdapter::Shutdown() {
33 BluetoothAdapter::BluetoothAdapter()
34 : weak_ptr_factory_(this) {
37 BluetoothAdapter::~BluetoothAdapter() {
38 STLDeleteValues(&devices_
);
41 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::GetWeakPtrForTesting() {
42 return weak_ptr_factory_
.GetWeakPtr();
45 void BluetoothAdapter::StartDiscoverySessionWithFilter(
46 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
47 const DiscoverySessionCallback
& callback
,
48 const ErrorCallback
& error_callback
) {
49 AddDiscoverySession(discovery_filter
.get(),
50 base::Bind(&BluetoothAdapter::OnStartDiscoverySession
,
51 weak_ptr_factory_
.GetWeakPtr(),
52 base::Passed(&discovery_filter
), callback
),
56 void BluetoothAdapter::StartDiscoverySession(
57 const DiscoverySessionCallback
& callback
,
58 const ErrorCallback
& error_callback
) {
59 StartDiscoverySessionWithFilter(nullptr, callback
, error_callback
);
62 scoped_ptr
<BluetoothDiscoveryFilter
>
63 BluetoothAdapter::GetMergedDiscoveryFilterHelper(
64 const BluetoothDiscoveryFilter
* masked_filter
,
66 scoped_ptr
<BluetoothDiscoveryFilter
> result
;
67 bool first_merge
= true;
69 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
70 for (const auto& iter
: temp
) {
71 const BluetoothDiscoveryFilter
* curr_filter
= iter
->GetDiscoveryFilter();
73 if (!iter
->IsActive())
76 if (omit
&& curr_filter
== masked_filter
) {
77 // if masked_filter is pointing to empty filter, and there are
78 // multiple empty filters in discovery_sessions_, make sure we'll
79 // process next empty sessions.
87 result
.reset(new BluetoothDiscoveryFilter(
88 BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL
));
89 result
->CopyFrom(*curr_filter
);
94 result
= BluetoothDiscoveryFilter::Merge(result
.get(), curr_filter
);
100 scoped_ptr
<BluetoothDiscoveryFilter
>
101 BluetoothAdapter::GetMergedDiscoveryFilter() const {
102 return GetMergedDiscoveryFilterHelper(nullptr, false);
105 scoped_ptr
<BluetoothDiscoveryFilter
>
106 BluetoothAdapter::GetMergedDiscoveryFilterMasked(
107 BluetoothDiscoveryFilter
* masked_filter
) const {
108 return GetMergedDiscoveryFilterHelper(masked_filter
, true);
111 BluetoothAdapter::DeviceList
BluetoothAdapter::GetDevices() {
112 ConstDeviceList const_devices
=
113 const_cast<const BluetoothAdapter
*>(this)->GetDevices();
116 for (ConstDeviceList::const_iterator i
= const_devices
.begin();
117 i
!= const_devices
.end(); ++i
)
118 devices
.push_back(const_cast<BluetoothDevice
*>(*i
));
123 BluetoothAdapter::ConstDeviceList
BluetoothAdapter::GetDevices() const {
124 ConstDeviceList devices
;
125 for (DevicesMap::const_iterator iter
= devices_
.begin();
126 iter
!= devices_
.end();
128 devices
.push_back(iter
->second
);
133 BluetoothDevice
* BluetoothAdapter::GetDevice(const std::string
& address
) {
134 return const_cast<BluetoothDevice
*>(
135 const_cast<const BluetoothAdapter
*>(this)->GetDevice(address
));
138 const BluetoothDevice
* BluetoothAdapter::GetDevice(
139 const std::string
& address
) const {
140 std::string canonicalized_address
=
141 BluetoothDevice::CanonicalizeAddress(address
);
142 if (canonicalized_address
.empty())
145 DevicesMap::const_iterator iter
= devices_
.find(canonicalized_address
);
146 if (iter
!= devices_
.end())
152 void BluetoothAdapter::AddPairingDelegate(
153 BluetoothDevice::PairingDelegate
* pairing_delegate
,
154 PairingDelegatePriority priority
) {
155 // Remove the delegate, if it already exists, before inserting to allow a
156 // change of priority.
157 RemovePairingDelegate(pairing_delegate
);
159 // Find the first point with a lower priority, or the end of the list.
160 std::list
<PairingDelegatePair
>::iterator iter
= pairing_delegates_
.begin();
161 while (iter
!= pairing_delegates_
.end() && iter
->second
>= priority
)
164 pairing_delegates_
.insert(iter
, std::make_pair(pairing_delegate
, priority
));
167 void BluetoothAdapter::RemovePairingDelegate(
168 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
169 for (std::list
<PairingDelegatePair
>::iterator iter
=
170 pairing_delegates_
.begin(); iter
!= pairing_delegates_
.end(); ++iter
) {
171 if (iter
->first
== pairing_delegate
) {
172 RemovePairingDelegateInternal(pairing_delegate
);
173 pairing_delegates_
.erase(iter
);
179 BluetoothDevice::PairingDelegate
* BluetoothAdapter::DefaultPairingDelegate() {
180 if (pairing_delegates_
.empty())
183 return pairing_delegates_
.front().first
;
186 void BluetoothAdapter::OnStartDiscoverySession(
187 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
188 const DiscoverySessionCallback
& callback
) {
189 VLOG(1) << "Discovery session started!";
190 scoped_ptr
<BluetoothDiscoverySession
> discovery_session(
191 new BluetoothDiscoverySession(scoped_refptr
<BluetoothAdapter
>(this),
192 discovery_filter
.Pass()));
193 discovery_sessions_
.insert(discovery_session
.get());
194 callback
.Run(discovery_session
.Pass());
197 void BluetoothAdapter::MarkDiscoverySessionsAsInactive() {
198 // As sessions are marked as inactive they will notify the adapter that they
199 // have become inactive, upon which the adapter will remove them from
200 // |discovery_sessions_|. To avoid invalidating the iterator, make a copy
202 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
203 for (std::set
<BluetoothDiscoverySession
*>::iterator
205 iter
!= temp
.end(); ++iter
) {
206 (*iter
)->MarkAsInactive();
210 void BluetoothAdapter::DiscoverySessionBecameInactive(
211 BluetoothDiscoverySession
* discovery_session
) {
212 DCHECK(!discovery_session
->IsActive());
213 discovery_sessions_
.erase(discovery_session
);
216 } // namespace device