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 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::GetWeakPtrForTesting() {
28 return weak_ptr_factory_
.GetWeakPtr();
31 #if defined(OS_CHROMEOS)
32 void BluetoothAdapter::Shutdown() {
37 void BluetoothAdapter::AddObserver(BluetoothAdapter::Observer
* observer
) {
39 observers_
.AddObserver(observer
);
42 void BluetoothAdapter::RemoveObserver(BluetoothAdapter::Observer
* observer
) {
44 observers_
.RemoveObserver(observer
);
47 void BluetoothAdapter::StartDiscoverySession(
48 const DiscoverySessionCallback
& callback
,
49 const ErrorCallback
& error_callback
) {
50 StartDiscoverySessionWithFilter(nullptr, callback
, error_callback
);
53 void BluetoothAdapter::StartDiscoverySessionWithFilter(
54 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
55 const DiscoverySessionCallback
& callback
,
56 const ErrorCallback
& error_callback
) {
57 AddDiscoverySession(discovery_filter
.get(),
58 base::Bind(&BluetoothAdapter::OnStartDiscoverySession
,
59 weak_ptr_factory_
.GetWeakPtr(),
60 base::Passed(&discovery_filter
), callback
),
64 scoped_ptr
<BluetoothDiscoveryFilter
>
65 BluetoothAdapter::GetMergedDiscoveryFilter() const {
66 return GetMergedDiscoveryFilterHelper(nullptr, false);
69 scoped_ptr
<BluetoothDiscoveryFilter
>
70 BluetoothAdapter::GetMergedDiscoveryFilterMasked(
71 BluetoothDiscoveryFilter
* masked_filter
) const {
72 return GetMergedDiscoveryFilterHelper(masked_filter
, true);
75 BluetoothAdapter::DeviceList
BluetoothAdapter::GetDevices() {
76 ConstDeviceList const_devices
=
77 const_cast<const BluetoothAdapter
*>(this)->GetDevices();
80 for (ConstDeviceList::const_iterator i
= const_devices
.begin();
81 i
!= const_devices
.end(); ++i
)
82 devices
.push_back(const_cast<BluetoothDevice
*>(*i
));
87 BluetoothAdapter::ConstDeviceList
BluetoothAdapter::GetDevices() const {
88 ConstDeviceList devices
;
89 for (DevicesMap::const_iterator iter
= devices_
.begin();
90 iter
!= devices_
.end();
92 devices
.push_back(iter
->second
);
97 BluetoothDevice
* BluetoothAdapter::GetDevice(const std::string
& address
) {
98 return const_cast<BluetoothDevice
*>(
99 const_cast<const BluetoothAdapter
*>(this)->GetDevice(address
));
102 const BluetoothDevice
* BluetoothAdapter::GetDevice(
103 const std::string
& address
) const {
104 std::string canonicalized_address
=
105 BluetoothDevice::CanonicalizeAddress(address
);
106 if (canonicalized_address
.empty())
109 DevicesMap::const_iterator iter
= devices_
.find(canonicalized_address
);
110 if (iter
!= devices_
.end())
116 void BluetoothAdapter::AddPairingDelegate(
117 BluetoothDevice::PairingDelegate
* pairing_delegate
,
118 PairingDelegatePriority priority
) {
119 // Remove the delegate, if it already exists, before inserting to allow a
120 // change of priority.
121 RemovePairingDelegate(pairing_delegate
);
123 // Find the first point with a lower priority, or the end of the list.
124 std::list
<PairingDelegatePair
>::iterator iter
= pairing_delegates_
.begin();
125 while (iter
!= pairing_delegates_
.end() && iter
->second
>= priority
)
128 pairing_delegates_
.insert(iter
, std::make_pair(pairing_delegate
, priority
));
131 void BluetoothAdapter::RemovePairingDelegate(
132 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
133 for (std::list
<PairingDelegatePair
>::iterator iter
=
134 pairing_delegates_
.begin(); iter
!= pairing_delegates_
.end(); ++iter
) {
135 if (iter
->first
== pairing_delegate
) {
136 RemovePairingDelegateInternal(pairing_delegate
);
137 pairing_delegates_
.erase(iter
);
143 BluetoothDevice::PairingDelegate
* BluetoothAdapter::DefaultPairingDelegate() {
144 if (pairing_delegates_
.empty())
147 return pairing_delegates_
.front().first
;
150 BluetoothAdapter::BluetoothAdapter() : weak_ptr_factory_(this) {
153 BluetoothAdapter::~BluetoothAdapter() {
154 STLDeleteValues(&devices_
);
157 void BluetoothAdapter::OnStartDiscoverySession(
158 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
159 const DiscoverySessionCallback
& callback
) {
160 VLOG(1) << "Discovery session started!";
161 scoped_ptr
<BluetoothDiscoverySession
> discovery_session(
162 new BluetoothDiscoverySession(scoped_refptr
<BluetoothAdapter
>(this),
163 discovery_filter
.Pass()));
164 discovery_sessions_
.insert(discovery_session
.get());
165 callback
.Run(discovery_session
.Pass());
168 void BluetoothAdapter::MarkDiscoverySessionsAsInactive() {
169 // As sessions are marked as inactive they will notify the adapter that they
170 // have become inactive, upon which the adapter will remove them from
171 // |discovery_sessions_|. To avoid invalidating the iterator, make a copy
173 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
174 for (std::set
<BluetoothDiscoverySession
*>::iterator
176 iter
!= temp
.end(); ++iter
) {
177 (*iter
)->MarkAsInactive();
181 void BluetoothAdapter::DiscoverySessionBecameInactive(
182 BluetoothDiscoverySession
* discovery_session
) {
183 DCHECK(!discovery_session
->IsActive());
184 discovery_sessions_
.erase(discovery_session
);
187 scoped_ptr
<BluetoothDiscoveryFilter
>
188 BluetoothAdapter::GetMergedDiscoveryFilterHelper(
189 const BluetoothDiscoveryFilter
* masked_filter
,
191 scoped_ptr
<BluetoothDiscoveryFilter
> result
;
192 bool first_merge
= true;
194 std::set
<BluetoothDiscoverySession
*> temp(discovery_sessions_
);
195 for (const auto& iter
: temp
) {
196 const BluetoothDiscoveryFilter
* curr_filter
= iter
->GetDiscoveryFilter();
198 if (!iter
->IsActive())
201 if (omit
&& curr_filter
== masked_filter
) {
202 // if masked_filter is pointing to empty filter, and there are
203 // multiple empty filters in discovery_sessions_, make sure we'll
204 // process next empty sessions.
212 result
.reset(new BluetoothDiscoveryFilter(
213 BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL
));
214 result
->CopyFrom(*curr_filter
);
219 result
= BluetoothDiscoveryFilter::Merge(result
.get(), curr_filter
);
222 return result
.Pass();
225 } // namespace device