1 // Copyright 2015 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 "components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "components/proximity_auth/ble/remote_attribute.h"
11 #include "device/bluetooth/bluetooth_adapter_factory.h"
12 #include "device/bluetooth/bluetooth_uuid.h"
13 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
14 #include "device/bluetooth/test/mock_bluetooth_device.h"
15 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
16 #include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::AtLeast
;
22 using testing::NiceMock
;
23 using testing::Return
;
24 using testing::StrictMock
;
25 using testing::SaveArg
;
27 namespace proximity_auth
{
30 const char kDeviceName
[] = "Device name";
31 const char kBluetoothAddress
[] = "11:22:33:44:55:66";
33 const char kServiceUUID
[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEEF";
34 const char kToPeripheralCharUUID
[] = "FBAE09F2-0482-11E5-8418-1697F925EC7B";
35 const char kFromPeripheralCharUUID
[] = "5539ED10-0483-11E5-8418-1697F925EC7B";
37 const char kToPeripheralCharID
[] = "to peripheral id";
38 const char kFromPeripheralCharID
[] = "from peripheral id";
40 const device::BluetoothGattCharacteristic::Properties
41 kCharacteristicProperties
=
42 device::BluetoothGattCharacteristic::PROPERTY_BROADCAST
|
43 device::BluetoothGattCharacteristic::PROPERTY_READ
|
44 device::BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE
|
45 device::BluetoothGattCharacteristic::PROPERTY_INDICATE
;
47 const char kOtherCharUUID
[] = "09731422-048A-11E5-8418-1697F925EC7B";
48 const char kOtherCharID
[] = "other id";
51 class ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
52 : public testing::Test
{
54 ProximityAuthBluetoothLowEnergyCharacteristicFinderTest()
55 : adapter_(new NiceMock
<device::MockBluetoothAdapter
>),
56 success_callback_(base::Bind(
57 &ProximityAuthBluetoothLowEnergyCharacteristicFinderTest::
58 OnCharacteristicsFound
,
59 base::Unretained(this))),
60 error_callback_(base::Bind(
61 &ProximityAuthBluetoothLowEnergyCharacteristicFinderTest::
62 OnCharacteristicsFinderError
,
63 base::Unretained(this))),
64 device_(new NiceMock
<device::MockBluetoothDevice
>(adapter_
.get(),
70 service_(new NiceMock
<device::MockBluetoothGattService
>(
73 device::BluetoothUUID(kServiceUUID
),
76 remote_service_({device::BluetoothUUID(kServiceUUID
), ""}),
77 to_peripheral_char_({device::BluetoothUUID(kToPeripheralCharUUID
), ""}),
78 from_peripheral_char_(
79 {device::BluetoothUUID(kFromPeripheralCharUUID
), ""}) {
80 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_
);
82 // The default behavior for |device_| is to have no services discovered. Can
83 // be overrided later.
84 ON_CALL(*device_
, GetGattServices())
85 .WillByDefault(Return(std::vector
<device::BluetoothGattService
*>()));
89 EXPECT_CALL(*adapter_
, AddObserver(_
));
90 EXPECT_CALL(*adapter_
, RemoveObserver(_
));
93 MOCK_METHOD3(OnCharacteristicsFound
,
94 void(const RemoteAttribute
&,
95 const RemoteAttribute
&,
96 const RemoteAttribute
&));
97 MOCK_METHOD2(OnCharacteristicsFinderError
,
98 void(const RemoteAttribute
&, const RemoteAttribute
&));
100 scoped_ptr
<device::MockBluetoothGattCharacteristic
>
101 ExpectToFindCharacteristic(const device::BluetoothUUID
& uuid
,
102 const std::string
& id
,
104 scoped_ptr
<device::MockBluetoothGattCharacteristic
> characteristic(
105 new NiceMock
<device::MockBluetoothGattCharacteristic
>(
106 service_
.get(), id
, uuid
, true, kCharacteristicProperties
,
107 device::BluetoothGattCharacteristic::PERMISSION_NONE
));
109 ON_CALL(*characteristic
.get(), GetUUID()).WillByDefault(Return(uuid
));
111 ON_CALL(*characteristic
.get(), GetIdentifier()).WillByDefault(Return(id
));
112 ON_CALL(*characteristic
.get(), GetService())
113 .WillByDefault(Return(service_
.get()));
114 return characteristic
.Pass();
117 scoped_refptr
<device::MockBluetoothAdapter
> adapter_
;
118 BluetoothLowEnergyCharacteristicsFinder::SuccessCallback success_callback_
;
119 BluetoothLowEnergyCharacteristicsFinder::ErrorCallback error_callback_
;
120 scoped_ptr
<device::MockBluetoothDevice
> device_
;
121 scoped_ptr
<device::MockBluetoothGattService
> service_
;
122 RemoteAttribute remote_service_
;
123 RemoteAttribute to_peripheral_char_
;
124 RemoteAttribute from_peripheral_char_
;
127 TEST_F(ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
,
128 ConstructAndDestroyDontCrash
) {
129 BluetoothLowEnergyCharacteristicsFinder
characteristic_finder(
130 adapter_
, device_
.get(), remote_service_
, to_peripheral_char_
,
131 from_peripheral_char_
, success_callback_
, error_callback_
);
134 TEST_F(ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
,
135 FindRightCharacteristics
) {
136 BluetoothLowEnergyCharacteristicsFinder
characteristic_finder(
137 adapter_
, device_
.get(), remote_service_
, to_peripheral_char_
,
138 from_peripheral_char_
, success_callback_
, error_callback_
);
139 // Upcasting |characteristic_finder| to access the virtual protected methods
140 // from Observer: GattCharacteristicAdded() and
141 // GattDiscoveryCompleteForService().
142 device::BluetoothAdapter::Observer
* observer
=
143 static_cast<device::BluetoothAdapter::Observer
*>(&characteristic_finder
);
145 RemoteAttribute found_to_char
, found_from_char
;
146 EXPECT_CALL(*this, OnCharacteristicsFound(_
, _
, _
))
148 DoAll(SaveArg
<1>(&found_to_char
), SaveArg
<2>(&found_from_char
)));
149 EXPECT_CALL(*this, OnCharacteristicsFinderError(_
, _
)).Times(0);
151 scoped_ptr
<device::MockBluetoothGattCharacteristic
> from_char
=
152 ExpectToFindCharacteristic(device::BluetoothUUID(kFromPeripheralCharUUID
),
153 kFromPeripheralCharID
, true);
154 observer
->GattCharacteristicAdded(adapter_
.get(), from_char
.get());
156 scoped_ptr
<device::MockBluetoothGattCharacteristic
> to_char
=
157 ExpectToFindCharacteristic(device::BluetoothUUID(kToPeripheralCharUUID
),
158 kToPeripheralCharID
, true);
159 observer
->GattCharacteristicAdded(adapter_
.get(), to_char
.get());
161 EXPECT_EQ(kToPeripheralCharID
, found_to_char
.id
);
162 EXPECT_EQ(kFromPeripheralCharID
, found_from_char
.id
);
164 EXPECT_CALL(*service_
, GetUUID())
165 .WillOnce(Return(device::BluetoothUUID(kServiceUUID
)));
166 observer
->GattDiscoveryCompleteForService(adapter_
.get(), service_
.get());
169 TEST_F(ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
,
170 DidntFindRightCharacteristics
) {
171 BluetoothLowEnergyCharacteristicsFinder
characteristic_finder(
172 adapter_
, device_
.get(), remote_service_
, to_peripheral_char_
,
173 from_peripheral_char_
, success_callback_
, error_callback_
);
174 device::BluetoothAdapter::Observer
* observer
=
175 static_cast<device::BluetoothAdapter::Observer
*>(&characteristic_finder
);
177 EXPECT_CALL(*this, OnCharacteristicsFound(_
, _
, _
)).Times(0);
178 EXPECT_CALL(*this, OnCharacteristicsFinderError(_
, _
));
180 scoped_ptr
<device::MockBluetoothGattCharacteristic
> other_char
=
181 ExpectToFindCharacteristic(device::BluetoothUUID(kOtherCharUUID
),
182 kOtherCharID
, false);
183 observer
->GattCharacteristicAdded(adapter_
.get(), other_char
.get());
185 EXPECT_CALL(*service_
, GetUUID())
186 .WillOnce(Return(device::BluetoothUUID(kServiceUUID
)));
187 observer
->GattDiscoveryCompleteForService(adapter_
.get(), service_
.get());
190 TEST_F(ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
,
191 FindOnlyOneRightCharacteristic
) {
192 BluetoothLowEnergyCharacteristicsFinder
characteristic_finder(
193 adapter_
, device_
.get(), remote_service_
, to_peripheral_char_
,
194 from_peripheral_char_
, success_callback_
, error_callback_
);
195 device::BluetoothAdapter::Observer
* observer
=
196 static_cast<device::BluetoothAdapter::Observer
*>(&characteristic_finder
);
198 RemoteAttribute found_to_char
, found_from_char
;
199 EXPECT_CALL(*this, OnCharacteristicsFound(_
, _
, _
)).Times(0);
200 EXPECT_CALL(*this, OnCharacteristicsFinderError(_
, _
))
202 DoAll(SaveArg
<0>(&found_to_char
), SaveArg
<1>(&found_from_char
)));
204 scoped_ptr
<device::MockBluetoothGattCharacteristic
> from_char
=
205 ExpectToFindCharacteristic(device::BluetoothUUID(kFromPeripheralCharUUID
),
206 kFromPeripheralCharID
, true);
207 observer
->GattCharacteristicAdded(adapter_
.get(), from_char
.get());
209 EXPECT_CALL(*service_
, GetUUID())
210 .WillOnce(Return(device::BluetoothUUID(kServiceUUID
)));
211 observer
->GattDiscoveryCompleteForService(adapter_
.get(), service_
.get());
212 EXPECT_EQ(kFromPeripheralCharID
, found_from_char
.id
);
215 TEST_F(ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
,
216 FindWrongCharacteristic_FindRightCharacteristics
) {
217 BluetoothLowEnergyCharacteristicsFinder
characteristic_finder(
218 adapter_
, device_
.get(), remote_service_
, to_peripheral_char_
,
219 from_peripheral_char_
, success_callback_
, error_callback_
);
220 device::BluetoothAdapter::Observer
* observer
=
221 static_cast<device::BluetoothAdapter::Observer
*>(&characteristic_finder
);
223 RemoteAttribute found_to_char
, found_from_char
;
224 EXPECT_CALL(*this, OnCharacteristicsFound(_
, _
, _
))
226 DoAll(SaveArg
<1>(&found_to_char
), SaveArg
<2>(&found_from_char
)));
227 EXPECT_CALL(*this, OnCharacteristicsFinderError(_
, _
)).Times(0);
229 scoped_ptr
<device::MockBluetoothGattCharacteristic
> other_char
=
230 ExpectToFindCharacteristic(device::BluetoothUUID(kOtherCharUUID
),
231 kOtherCharID
, false);
232 observer
->GattCharacteristicAdded(adapter_
.get(), other_char
.get());
234 scoped_ptr
<device::MockBluetoothGattCharacteristic
> from_char
=
235 ExpectToFindCharacteristic(device::BluetoothUUID(kFromPeripheralCharUUID
),
236 kFromPeripheralCharID
, true);
237 observer
->GattCharacteristicAdded(adapter_
.get(), from_char
.get());
239 scoped_ptr
<device::MockBluetoothGattCharacteristic
> to_char
=
240 ExpectToFindCharacteristic(device::BluetoothUUID(kToPeripheralCharUUID
),
241 kToPeripheralCharID
, true);
242 observer
->GattCharacteristicAdded(adapter_
.get(), to_char
.get());
244 EXPECT_EQ(kToPeripheralCharID
, found_to_char
.id
);
245 EXPECT_EQ(kFromPeripheralCharID
, found_from_char
.id
);
247 EXPECT_CALL(*service_
, GetUUID())
248 .WillOnce(Return(device::BluetoothUUID(kServiceUUID
)));
249 observer
->GattDiscoveryCompleteForService(adapter_
.get(), service_
.get());
252 TEST_F(ProximityAuthBluetoothLowEnergyCharacteristicFinderTest
,
253 RightCharacteristicsAlreadyPresent
) {
254 RemoteAttribute found_to_char
, found_from_char
;
255 EXPECT_CALL(*this, OnCharacteristicsFound(_
, _
, _
))
257 DoAll(SaveArg
<1>(&found_to_char
), SaveArg
<2>(&found_from_char
)));
258 EXPECT_CALL(*this, OnCharacteristicsFinderError(_
, _
)).Times(0);
260 scoped_ptr
<device::MockBluetoothGattCharacteristic
> from_char
=
261 ExpectToFindCharacteristic(device::BluetoothUUID(kFromPeripheralCharUUID
),
262 kFromPeripheralCharID
, true);
264 scoped_ptr
<device::MockBluetoothGattCharacteristic
> to_char
=
265 ExpectToFindCharacteristic(device::BluetoothUUID(kToPeripheralCharUUID
),
266 kToPeripheralCharID
, true);
268 std::vector
<device::BluetoothGattService
*> services
;
269 services
.push_back(service_
.get());
270 ON_CALL(*device_
, GetGattServices()).WillByDefault(Return(services
));
272 std::vector
<device::BluetoothGattCharacteristic
*> characteristics
;
273 characteristics
.push_back(from_char
.get());
274 characteristics
.push_back(to_char
.get());
275 ON_CALL(*service_
, GetCharacteristics())
276 .WillByDefault(Return(characteristics
));
278 BluetoothLowEnergyCharacteristicsFinder
characteristic_finder(
279 adapter_
, device_
.get(), remote_service_
, to_peripheral_char_
,
280 from_peripheral_char_
, success_callback_
, error_callback_
);
281 device::BluetoothAdapter::Observer
* observer
=
282 static_cast<device::BluetoothAdapter::Observer
*>(&characteristic_finder
);
284 EXPECT_EQ(kToPeripheralCharID
, found_to_char
.id
);
285 EXPECT_EQ(kFromPeripheralCharID
, found_from_char
.id
);
287 EXPECT_CALL(*service_
, GetUUID())
288 .WillOnce(Return(device::BluetoothUUID(kServiceUUID
)));
289 observer
->GattDiscoveryCompleteForService(adapter_
.get(), service_
.get());
292 } // namespace proximity_auth