Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / device / bluetooth / bluetooth_discovery_session.cc
blobe30f86ccd6132beaae306190debeb2db69a1e19f
1 // Copyright 2014 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_discovery_session.h"
7 #include "base/bind.h"
8 #include "device/bluetooth/bluetooth_adapter.h"
10 namespace device {
12 BluetoothDiscoveryFilter::BluetoothDiscoveryFilter(TransportMask transport) {
13 SetTransport(transport);
16 BluetoothDiscoveryFilter::~BluetoothDiscoveryFilter() {
19 bool BluetoothDiscoveryFilter::GetRSSI(int16_t* out_rssi) const {
20 DCHECK(out_rssi);
21 if (!rssi_.get())
22 return false;
24 *out_rssi = *rssi_;
25 return true;
28 void BluetoothDiscoveryFilter::SetRSSI(int16_t rssi) {
29 if (!rssi_.get())
30 rssi_.reset(new int16_t());
32 *rssi_ = rssi;
35 bool BluetoothDiscoveryFilter::GetPathloss(uint16_t* out_pathloss) const {
36 DCHECK(out_pathloss);
37 if (!pathloss_.get())
38 return false;
40 *out_pathloss = *pathloss_;
41 return true;
44 void BluetoothDiscoveryFilter::SetPathloss(uint16_t pathloss) {
45 if (!pathloss_.get())
46 pathloss_.reset(new uint16_t());
48 *pathloss_ = pathloss;
51 BluetoothDiscoveryFilter::TransportMask BluetoothDiscoveryFilter::GetTransport()
52 const {
53 return transport_;
56 void BluetoothDiscoveryFilter::SetTransport(TransportMask transport) {
57 DCHECK(transport > 0 && transport < 4);
58 transport_ = transport;
61 void BluetoothDiscoveryFilter::GetUUIDs(
62 std::set<device::BluetoothUUID>& out_uuids) const {
63 out_uuids.clear();
65 for (auto& uuid : uuids_)
66 out_uuids.insert(*uuid);
69 void BluetoothDiscoveryFilter::AddUUID(const device::BluetoothUUID& uuid) {
70 DCHECK(uuid.IsValid());
71 for (auto& uuid_it : uuids_) {
72 if (*uuid_it == uuid)
73 return;
76 uuids_.push_back(new device::BluetoothUUID(uuid));
79 void BluetoothDiscoveryFilter::CopyFrom(
80 const BluetoothDiscoveryFilter& filter) {
81 transport_ = filter.transport_;
83 if (filter.uuids_.size()) {
84 for (auto& uuid : filter.uuids_)
85 AddUUID(*uuid);
86 } else
87 uuids_.clear();
89 if (filter.rssi_.get()) {
90 SetRSSI(*filter.rssi_);
91 } else
92 rssi_.reset();
94 if (filter.pathloss_.get()) {
95 SetPathloss(*filter.pathloss_);
96 } else
97 pathloss_.reset();
100 scoped_ptr<device::BluetoothDiscoveryFilter> BluetoothDiscoveryFilter::Merge(
101 const device::BluetoothDiscoveryFilter* filter_a,
102 const device::BluetoothDiscoveryFilter* filter_b) {
103 scoped_ptr<BluetoothDiscoveryFilter> result;
105 if (!filter_a && !filter_b) {
106 return result;
109 result.reset(new BluetoothDiscoveryFilter(Transport::TRANSPORT_DUAL));
111 if (!filter_a || !filter_b || filter_a->IsDefault() ||
112 filter_b->IsDefault()) {
113 return result;
116 // both filters are not empty, so they must have transport set.
117 result->SetTransport(filter_a->transport_ | filter_b->transport_);
119 // if both filters have uuids, them merge them. Otherwise uuids filter should
120 // be left empty
121 if (filter_a->uuids_.size() && filter_b->uuids_.size()) {
122 std::set<device::BluetoothUUID> uuids;
123 filter_a->GetUUIDs(uuids);
124 for (auto& uuid : uuids)
125 result->AddUUID(uuid);
127 filter_b->GetUUIDs(uuids);
128 for (auto& uuid : uuids)
129 result->AddUUID(uuid);
132 if ((filter_a->rssi_.get() && filter_b->pathloss_.get()) ||
133 (filter_a->pathloss_.get() && filter_b->rssi_.get())) {
134 // if both rssi and pathloss filtering is enabled in two different
135 // filters, we can't tell which filter is more generic, and we don't set
136 // proximity filtering on merged filter.
137 return result;
140 if (filter_a->rssi_.get() && filter_b->rssi_.get()) {
141 result->SetRSSI(std::min(*filter_a->rssi_, *filter_b->rssi_));
142 } else if (filter_a->pathloss_.get() && filter_b->pathloss_.get()) {
143 result->SetPathloss(std::max(*filter_a->pathloss_, *filter_b->pathloss_));
146 return result;
149 bool BluetoothDiscoveryFilter::Equals(
150 const BluetoothDiscoveryFilter& other) const {
151 if (((!!rssi_.get()) != (!!other.rssi_.get())) ||
152 (rssi_.get() && other.rssi_.get() && *rssi_ != *other.rssi_)) {
153 return false;
156 if (((!!pathloss_.get()) != (!!other.pathloss_.get())) ||
157 (pathloss_.get() && other.pathloss_.get() &&
158 *pathloss_ != *other.pathloss_)) {
159 return false;
162 if (transport_ != other.transport_)
163 return false;
165 std::set<device::BluetoothUUID> uuids_a, uuids_b;
166 GetUUIDs(uuids_a);
167 other.GetUUIDs(uuids_b);
168 if (uuids_a != uuids_b)
169 return false;
171 return true;
174 bool BluetoothDiscoveryFilter::IsDefault() const {
175 return !(rssi_.get() || pathloss_.get() || uuids_.size() ||
176 transport_ != Transport::TRANSPORT_DUAL);
179 BluetoothDiscoverySession::BluetoothDiscoverySession(
180 scoped_refptr<BluetoothAdapter> adapter,
181 scoped_ptr<BluetoothDiscoveryFilter> discovery_filter)
182 : active_(true),
183 adapter_(adapter),
184 discovery_filter_(discovery_filter.release()),
185 weak_ptr_factory_(this) {
186 DCHECK(adapter_.get());
189 BluetoothDiscoverySession::~BluetoothDiscoverySession() {
190 if (active_) {
191 Stop(base::Bind(&base::DoNothing), base::Bind(&base::DoNothing));
192 MarkAsInactive();
196 bool BluetoothDiscoverySession::IsActive() const {
197 return active_;
200 void BluetoothDiscoverySession::Stop(
201 const base::Closure& callback,
202 const ErrorCallback& error_callback) {
203 if (!active_) {
204 LOG(WARNING) << "Discovery session not active. Cannot stop.";
205 error_callback.Run();
206 return;
208 VLOG(1) << "Stopping device discovery session.";
209 adapter_->RemoveDiscoverySession(
210 discovery_filter_.get(),
211 base::Bind(&BluetoothDiscoverySession::OnStop,
212 weak_ptr_factory_.GetWeakPtr(), callback),
213 error_callback);
216 void BluetoothDiscoverySession::OnStop(const base::Closure& callback) {
217 MarkAsInactive();
218 discovery_filter_.reset();
219 callback.Run();
222 void BluetoothDiscoverySession::MarkAsInactive() {
223 if (!active_)
224 return;
225 active_ = false;
226 adapter_->DiscoverySessionBecameInactive(this);
229 void BluetoothDiscoverySession::SetDiscoveryFilter(
230 scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
231 const base::Closure& callback,
232 const ErrorCallback& error_callback) {
233 discovery_filter_.reset(discovery_filter.release());
234 adapter_->SetDiscoveryFilter(adapter_->GetMergedDiscoveryFilter().Pass(),
235 callback, error_callback);
238 const BluetoothDiscoveryFilter* BluetoothDiscoverySession::GetDiscoveryFilter()
239 const {
240 return discovery_filter_.get();
243 } // namespace device