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_ANDROID) && !defined(OS_CHROMEOS) && !defined(OS_MACOSX) && \
22 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::CreateAdapter(
23 const InitCallback
& init_callback
) {
24 return base::WeakPtr
<BluetoothAdapter
>();
26 #endif // !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
28 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::GetWeakPtrForTesting() {
29 return weak_ptr_factory_
.GetWeakPtr();
32 #if defined(OS_CHROMEOS)
33 void BluetoothAdapter::Shutdown() {
38 void BluetoothAdapter::AddObserver(BluetoothAdapter::Observer
* observer
) {
40 observers_
.AddObserver(observer
);
43 void BluetoothAdapter::RemoveObserver(BluetoothAdapter::Observer
* observer
) {
45 observers_
.RemoveObserver(observer
);
48 void BluetoothAdapter::StartDiscoverySession(
49 const DiscoverySessionCallback
& callback
,
50 const ErrorCallback
& error_callback
) {
51 StartDiscoverySessionWithFilter(nullptr, callback
, error_callback
);
54 void BluetoothAdapter::StartDiscoverySessionWithFilter(
55 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
56 const DiscoverySessionCallback
& callback
,
57 const ErrorCallback
& error_callback
) {
58 BluetoothDiscoveryFilter
* ptr
= discovery_filter
.get();
59 AddDiscoverySession(ptr
,
60 base::Bind(&BluetoothAdapter::OnStartDiscoverySession
,
61 weak_ptr_factory_
.GetWeakPtr(),
62 base::Passed(&discovery_filter
), callback
),
66 scoped_ptr
<BluetoothDiscoveryFilter
>
67 BluetoothAdapter::GetMergedDiscoveryFilter() const {
68 return GetMergedDiscoveryFilterHelper(nullptr, false);
71 scoped_ptr
<BluetoothDiscoveryFilter
>
72 BluetoothAdapter::GetMergedDiscoveryFilterMasked(
73 BluetoothDiscoveryFilter
* masked_filter
) const {
74 return GetMergedDiscoveryFilterHelper(masked_filter
, true);
77 BluetoothAdapter::DeviceList
BluetoothAdapter::GetDevices() {
78 ConstDeviceList const_devices
=
79 const_cast<const BluetoothAdapter
*>(this)->GetDevices();
82 for (ConstDeviceList::const_iterator i
= const_devices
.begin();
83 i
!= const_devices
.end(); ++i
)
84 devices
.push_back(const_cast<BluetoothDevice
*>(*i
));
89 BluetoothAdapter::ConstDeviceList
BluetoothAdapter::GetDevices() const {
90 ConstDeviceList devices
;
91 for (DevicesMap::const_iterator iter
= devices_
.begin();
92 iter
!= devices_
.end();
94 devices
.push_back(iter
->second
);
99 BluetoothDevice
* BluetoothAdapter::GetDevice(const std::string
& address
) {
100 return const_cast<BluetoothDevice
*>(
101 const_cast<const BluetoothAdapter
*>(this)->GetDevice(address
));
104 const BluetoothDevice
* BluetoothAdapter::GetDevice(
105 const std::string
& address
) const {
106 std::string canonicalized_address
=
107 BluetoothDevice::CanonicalizeAddress(address
);
108 if (canonicalized_address
.empty())
111 DevicesMap::const_iterator iter
= devices_
.find(canonicalized_address
);
112 if (iter
!= devices_
.end())
118 void BluetoothAdapter::AddPairingDelegate(
119 BluetoothDevice::PairingDelegate
* pairing_delegate
,
120 PairingDelegatePriority priority
) {
121 // Remove the delegate, if it already exists, before inserting to allow a
122 // change of priority.
123 RemovePairingDelegate(pairing_delegate
);
125 // Find the first point with a lower priority, or the end of the list.
126 std::list
<PairingDelegatePair
>::iterator iter
= pairing_delegates_
.begin();
127 while (iter
!= pairing_delegates_
.end() && iter
->second
>= priority
)
130 pairing_delegates_
.insert(iter
, std::make_pair(pairing_delegate
, priority
));
133 void BluetoothAdapter::RemovePairingDelegate(
134 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
135 for (std::list
<PairingDelegatePair
>::iterator iter
=
136 pairing_delegates_
.begin(); iter
!= pairing_delegates_
.end(); ++iter
) {
137 if (iter
->first
== pairing_delegate
) {
138 RemovePairingDelegateInternal(pairing_delegate
);
139 pairing_delegates_
.erase(iter
);
145 BluetoothDevice::PairingDelegate
* BluetoothAdapter::DefaultPairingDelegate() {
146 if (pairing_delegates_
.empty())
149 return pairing_delegates_
.front().first
;
152 BluetoothAdapter::BluetoothAdapter() : weak_ptr_factory_(this) {
155 BluetoothAdapter::~BluetoothAdapter() {
156 STLDeleteValues(&devices_
);
159 void BluetoothAdapter::OnStartDiscoverySession(
160 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
161 const DiscoverySessionCallback
& callback
) {
162 VLOG(1) << "Discovery session started!";
163 scoped_ptr
<BluetoothDiscoverySession
> discovery_session(
164 new BluetoothDiscoverySession(scoped_refptr
<BluetoothAdapter
>(this),
165 discovery_filter
.Pass()));
166 discovery_sessions_
.insert(discovery_session
.get());
167 callback
.Run(discovery_session
.Pass());
170 void BluetoothAdapter::MarkDiscoverySessionsAsInactive() {
171 // As sessions are marked as inactive they will notify the adapter that they
172 // have become inactive, upon which the adapter will remove them from
173 // |discovery_sessions_|. To avoid invalidating the iterator, make a copy
175 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
176 for (std::set
<BluetoothDiscoverySession
*>::iterator
178 iter
!= temp
.end(); ++iter
) {
179 (*iter
)->MarkAsInactive();
183 void BluetoothAdapter::DiscoverySessionBecameInactive(
184 BluetoothDiscoverySession
* discovery_session
) {
185 DCHECK(!discovery_session
->IsActive());
186 discovery_sessions_
.erase(discovery_session
);
189 scoped_ptr
<BluetoothDiscoveryFilter
>
190 BluetoothAdapter::GetMergedDiscoveryFilterHelper(
191 const BluetoothDiscoveryFilter
* masked_filter
,
193 scoped_ptr
<BluetoothDiscoveryFilter
> result
;
194 bool first_merge
= true;
196 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
197 for (const auto& iter
: temp
) {
198 const BluetoothDiscoveryFilter
* curr_filter
= iter
->GetDiscoveryFilter();
200 if (!iter
->IsActive())
203 if (omit
&& curr_filter
== masked_filter
) {
204 // if masked_filter is pointing to empty filter, and there are
205 // multiple empty filters in discovery_sessions_, make sure we'll
206 // process next empty sessions.
214 result
.reset(new BluetoothDiscoveryFilter(
215 BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL
));
216 result
->CopyFrom(*curr_filter
);
221 result
= BluetoothDiscoveryFilter::Merge(result
.get(), curr_filter
);
224 return result
.Pass();
227 } // namespace device