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.
4
5 #include "base/memory/scoped_ptr.h"
6 #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h"
7 #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h"
8 #include "chrome/browser/extensions/extension_apitest.h"
9 #include "chrome/browser/extensions/extension_function_test_utils.h"
10 #include "chrome/browser/extensions/extension_test_message_listener.h"
11 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
12 #include "device/bluetooth/test/mock_bluetooth_device.h"
13 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
14 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
15 #include "device/bluetooth/test/mock_bluetooth_gatt_descriptor.h"
16 #include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h"
17 #include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19
20 using device::BluetoothUUID;
21 using device::BluetoothAdapter;
22 using device::BluetoothDevice;
23 using device::BluetoothGattCharacteristic;
24 using device::BluetoothGattConnection;
25 using device::BluetoothGattDescriptor;
26 using device::BluetoothGattService;
27 using device::BluetoothGattNotifySession;
28 using device::MockBluetoothAdapter;
29 using device::MockBluetoothDevice;
30 using device::MockBluetoothGattCharacteristic;
31 using device::MockBluetoothGattConnection;
32 using device::MockBluetoothGattDescriptor;
33 using device::MockBluetoothGattService;
34 using device::MockBluetoothGattNotifySession;
35 using extensions::BluetoothLowEnergyEventRouter;
36 using testing::Invoke;
37 using testing::Return;
38 using testing::ReturnRef;
39 using testing::ReturnRefOfCopy;
40 using testing::SaveArg;
41 using testing::_;
42
43 namespace utils = extension_function_test_utils;
44
45 namespace {
46
47 // Test service constants.
48 const char kTestLeDeviceAddress0[] = "11:22:33:44:55:66";
49 const char kTestLeDeviceName0[] = "Test LE Device 0";
50
51 const char kTestLeDeviceAddress1[] = "77:88:99:AA:BB:CC";
52 const char kTestLeDeviceName1[] = "Test LE Device 1";
53
54 const char kTestServiceId0[] = "service_id0";
55 const char kTestServiceUuid0[] = "1234";
56
57 const char kTestServiceId1[] = "service_id1";
58 const char kTestServiceUuid1[] = "5678";
59
60 // Test characteristic constants.
61 const char kTestCharacteristicId0[] = "char_id0";
62 const char kTestCharacteristicUuid0[] = "1211";
63 const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties0 =
64 BluetoothGattCharacteristic::kPropertyBroadcast |
65 BluetoothGattCharacteristic::kPropertyRead |
66 BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
67 BluetoothGattCharacteristic::kPropertyIndicate;
68 const uint8 kTestCharacteristicDefaultValue0[] = {0x01, 0x02, 0x03, 0x04, 0x05};
69
70 const char kTestCharacteristicId1[] = "char_id1";
71 const char kTestCharacteristicUuid1[] = "1212";
72 const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties1 =
73 BluetoothGattCharacteristic::kPropertyRead |
74 BluetoothGattCharacteristic::kPropertyWrite |
75 BluetoothGattCharacteristic::kPropertyNotify;
76 const uint8 kTestCharacteristicDefaultValue1[] = {0x06, 0x07, 0x08};
77
78 const char kTestCharacteristicId2[] = "char_id2";
79 const char kTestCharacteristicUuid2[] = "1213";
80 const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties2 =
81 BluetoothGattCharacteristic::kPropertyNone;
82
83 // Test descriptor constants.
84 const char kTestDescriptorId0[] = "desc_id0";
85 const char kTestDescriptorUuid0[] = "1221";
86 const uint8 kTestDescriptorDefaultValue0[] = {0x01, 0x02, 0x03};
87
88 const char kTestDescriptorId1[] = "desc_id1";
89 const char kTestDescriptorUuid1[] = "1222";
90 const uint8 kTestDescriptorDefaultValue1[] = {0x04, 0x05};
91
92 class BluetoothLowEnergyApiTest : public ExtensionApiTest {
93 public:
BluetoothLowEnergyApiTest()94 BluetoothLowEnergyApiTest() {}
95
~BluetoothLowEnergyApiTest()96 virtual ~BluetoothLowEnergyApiTest() {}
97
SetUpOnMainThread()98 virtual void SetUpOnMainThread() OVERRIDE {
99 ExtensionApiTest::SetUpOnMainThread();
100 empty_extension_ = utils::CreateEmptyExtension();
101 SetUpMocks();
102 }
103
CleanUpOnMainThread()104 virtual void CleanUpOnMainThread() OVERRIDE {
105 EXPECT_CALL(*mock_adapter_, RemoveObserver(_));
106 }
107
SetUpMocks()108 void SetUpMocks() {
109 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>();
110 EXPECT_CALL(*mock_adapter_, GetDevices())
111 .WillOnce(Return(BluetoothAdapter::ConstDeviceList()));
112
113 event_router()->SetAdapterForTesting(mock_adapter_);
114
115 device0_.reset(
116 new testing::NiceMock<MockBluetoothDevice>(mock_adapter_,
117 0,
118 kTestLeDeviceName0,
119 kTestLeDeviceAddress0,
120 false /* paired */,
121 true /* connected */));
122
123 device1_.reset(
124 new testing::NiceMock<MockBluetoothDevice>(mock_adapter_,
125 0,
126 kTestLeDeviceName1,
127 kTestLeDeviceAddress1,
128 false /* paired */,
129 false /* connected */));
130
131 service0_.reset(new testing::NiceMock<MockBluetoothGattService>(
132 device0_.get(),
133 kTestServiceId0,
134 BluetoothUUID(kTestServiceUuid0),
135 true /* is_primary */,
136 false /* is_local */));
137
138 service1_.reset(new testing::NiceMock<MockBluetoothGattService>(
139 device0_.get(),
140 kTestServiceId1,
141 BluetoothUUID(kTestServiceUuid1),
142 false /* is_primary */,
143 false /* is_local */));
144
145 // Assign characteristics some random properties and permissions. They don't
146 // need to reflect what the characteristic is actually capable of, since
147 // the JS API just passes values through from
148 // device::BluetoothGattCharacteristic.
149 std::vector<uint8> default_value;
150 chrc0_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
151 service0_.get(),
152 kTestCharacteristicId0,
153 BluetoothUUID(kTestCharacteristicUuid0),
154 false /* is_local */,
155 kTestCharacteristicProperties0,
156 BluetoothGattCharacteristic::kPermissionNone));
157 default_value.assign(kTestCharacteristicDefaultValue0,
158 (kTestCharacteristicDefaultValue0 +
159 sizeof(kTestCharacteristicDefaultValue0)));
160 ON_CALL(*chrc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
161
162 chrc1_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
163 service0_.get(),
164 kTestCharacteristicId1,
165 BluetoothUUID(kTestCharacteristicUuid1),
166 false /* is_local */,
167 kTestCharacteristicProperties1,
168 BluetoothGattCharacteristic::kPermissionNone));
169 default_value.assign(kTestCharacteristicDefaultValue1,
170 (kTestCharacteristicDefaultValue1 +
171 sizeof(kTestCharacteristicDefaultValue1)));
172 ON_CALL(*chrc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
173
174 chrc2_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
175 service1_.get(),
176 kTestCharacteristicId2,
177 BluetoothUUID(kTestCharacteristicUuid2),
178 false /* is_local */,
179 kTestCharacteristicProperties2,
180 BluetoothGattCharacteristic::kPermissionNone));
181
182 desc0_.reset(new testing::NiceMock<MockBluetoothGattDescriptor>(
183 chrc0_.get(),
184 kTestDescriptorId0,
185 BluetoothUUID(kTestDescriptorUuid0),
186 false /* is_local */,
187 BluetoothGattCharacteristic::kPermissionNone));
188 default_value.assign(
189 kTestDescriptorDefaultValue0,
190 (kTestDescriptorDefaultValue0 + sizeof(kTestDescriptorDefaultValue0)));
191 ON_CALL(*desc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
192
193 desc1_.reset(new testing::NiceMock<MockBluetoothGattDescriptor>(
194 chrc0_.get(),
195 kTestDescriptorId1,
196 BluetoothUUID(kTestDescriptorUuid1),
197 false /* is_local */,
198 BluetoothGattCharacteristic::kPermissionNone));
199 default_value.assign(
200 kTestDescriptorDefaultValue1,
201 (kTestDescriptorDefaultValue1 + sizeof(kTestDescriptorDefaultValue1)));
202 ON_CALL(*desc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
203 }
204
205 protected:
event_router()206 BluetoothLowEnergyEventRouter* event_router() {
207 return extensions::BluetoothLowEnergyAPI::Get(browser()->profile())
208 ->event_router();
209 }
210
211 testing::StrictMock<MockBluetoothAdapter>* mock_adapter_;
212 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device0_;
213 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_;
214 scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service0_;
215 scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service1_;
216 scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc0_;
217 scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc1_;
218 scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc2_;
219 scoped_ptr<testing::NiceMock<MockBluetoothGattDescriptor> > desc0_;
220 scoped_ptr<testing::NiceMock<MockBluetoothGattDescriptor> > desc1_;
221
222 private:
223 scoped_refptr<extensions::Extension> empty_extension_;
224 };
225
ACTION_TEMPLATE(InvokeCallbackArgument,HAS_1_TEMPLATE_PARAMS (int,k),AND_0_VALUE_PARAMS ())226 ACTION_TEMPLATE(InvokeCallbackArgument,
227 HAS_1_TEMPLATE_PARAMS(int, k),
228 AND_0_VALUE_PARAMS()) {
229 ::std::tr1::get<k>(args).Run();
230 }
231
ACTION_TEMPLATE(InvokeCallbackArgument,HAS_1_TEMPLATE_PARAMS (int,k),AND_1_VALUE_PARAMS (p0))232 ACTION_TEMPLATE(InvokeCallbackArgument,
233 HAS_1_TEMPLATE_PARAMS(int, k),
234 AND_1_VALUE_PARAMS(p0)) {
235 ::std::tr1::get<k>(args).Run(p0);
236 }
237
ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg,HAS_2_TEMPLATE_PARAMS (int,k,typename,T),AND_1_VALUE_PARAMS (p0))238 ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg,
239 HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
240 AND_1_VALUE_PARAMS(p0)) {
241 ::std::tr1::get<k>(args).Run(scoped_ptr<T>(p0));
242 }
243
CreateGattConnection(const std::string & device_address,bool expect_disconnect)244 BluetoothGattConnection* CreateGattConnection(
245 const std::string& device_address,
246 bool expect_disconnect) {
247 testing::NiceMock<MockBluetoothGattConnection>* conn =
248 new testing::NiceMock<MockBluetoothGattConnection>(device_address);
249
250 if (expect_disconnect) {
251 EXPECT_CALL(*conn, Disconnect(_))
252 .Times(1)
253 .WillOnce(InvokeCallbackArgument<0>());
254 } else {
255 EXPECT_CALL(*conn, Disconnect(_)).Times(0);
256 }
257
258 return conn;
259 }
260
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetServices)261 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetServices) {
262 ResultCatcher catcher;
263 catcher.RestrictToProfile(browser()->profile());
264
265 std::vector<BluetoothGattService*> services;
266 services.push_back(service0_.get());
267 services.push_back(service1_.get());
268
269 EXPECT_CALL(*mock_adapter_, GetDevice(_))
270 .Times(3)
271 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
272 .WillRepeatedly(Return(device0_.get()));
273
274 EXPECT_CALL(*device0_, GetGattServices())
275 .Times(2)
276 .WillOnce(Return(std::vector<BluetoothGattService*>()))
277 .WillOnce(Return(services));
278
279 // Load and wait for setup.
280 ExtensionTestMessageListener listener("ready", true);
281 ASSERT_TRUE(LoadExtension(
282 test_data_dir_.AppendASCII("bluetooth_low_energy/get_services")));
283 EXPECT_TRUE(listener.WaitUntilSatisfied());
284
285 listener.Reply("go");
286
287 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
288 }
289
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetService)290 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetService) {
291 ResultCatcher catcher;
292 catcher.RestrictToProfile(browser()->profile());
293
294 event_router()->DeviceAdded(mock_adapter_, device0_.get());
295 event_router()->GattServiceAdded(device0_.get(), service0_.get());
296
297 EXPECT_CALL(*mock_adapter_, GetDevice(_))
298 .Times(3)
299 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
300 .WillRepeatedly(Return(device0_.get()));
301
302 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
303 .Times(2)
304 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
305 .WillOnce(Return(service0_.get()));
306
307 // Load and wait for setup.
308 ExtensionTestMessageListener listener("ready", true);
309 ASSERT_TRUE(LoadExtension(
310 test_data_dir_.AppendASCII("bluetooth_low_energy/get_service")));
311 EXPECT_TRUE(listener.WaitUntilSatisfied());
312
313 listener.Reply("go");
314
315 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
316
317 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
318 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
319 }
320
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,ServiceEvents)321 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ServiceEvents) {
322 ResultCatcher catcher;
323 catcher.RestrictToProfile(browser()->profile());
324
325 // Load the extension and let it set up.
326 ExtensionTestMessageListener listener("ready", true);
327 ASSERT_TRUE(LoadExtension(
328 test_data_dir_.AppendASCII("bluetooth_low_energy/service_events")));
329
330 // Cause events to be sent to the extension.
331 event_router()->DeviceAdded(mock_adapter_, device0_.get());
332
333 event_router()->GattServiceAdded(device0_.get(), service0_.get());
334 event_router()->GattServiceAdded(device0_.get(), service1_.get());
335 event_router()->GattServiceChanged(service1_.get());
336 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
337
338 EXPECT_TRUE(listener.WaitUntilSatisfied());
339 listener.Reply("go");
340
341 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
342 event_router()->GattServiceRemoved(device0_.get(), service1_.get());
343 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
344 }
345
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetRemovedService)346 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedService) {
347 ResultCatcher catcher;
348 catcher.RestrictToProfile(browser()->profile());
349
350 // Load the extension and let it set up.
351 ASSERT_TRUE(LoadExtension(
352 test_data_dir_.AppendASCII("bluetooth_low_energy/get_removed_service")));
353
354 // 1. getService success.
355 EXPECT_CALL(*mock_adapter_, GetDevice(_))
356 .Times(1)
357 .WillOnce(Return(device0_.get()));
358 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
359 .Times(1)
360 .WillOnce(Return(service0_.get()));
361
362 event_router()->DeviceAdded(mock_adapter_, device0_.get());
363 event_router()->GattServiceAdded(device0_.get(), service0_.get());
364
365 ExtensionTestMessageListener get_service_success_listener("getServiceSuccess",
366 true);
367 EXPECT_TRUE(get_service_success_listener.WaitUntilSatisfied());
368 testing::Mock::VerifyAndClearExpectations(mock_adapter_);
369 testing::Mock::VerifyAndClearExpectations(device0_.get());
370
371 // 2. getService fail.
372 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
373 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)).Times(0);
374
375 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
376
377 ExtensionTestMessageListener get_service_fail_listener("getServiceFail",
378 true);
379 EXPECT_TRUE(get_service_fail_listener.WaitUntilSatisfied());
380 testing::Mock::VerifyAndClearExpectations(mock_adapter_);
381 testing::Mock::VerifyAndClearExpectations(device0_.get());
382
383 get_service_fail_listener.Reply("go");
384
385 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
386 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
387 }
388
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetIncludedServices)389 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetIncludedServices) {
390 ResultCatcher catcher;
391 catcher.RestrictToProfile(browser()->profile());
392
393 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
394 "bluetooth_low_energy/get_included_services")));
395
396 // Wait for initial call to end with failure as there is no mapping.
397 ExtensionTestMessageListener listener("ready", true);
398 EXPECT_TRUE(listener.WaitUntilSatisfied());
399
400 // Set up for the rest of the calls before replying. Included services can be
401 // returned even if there is no instance ID mapping for them yet, so no need
402 // to call GattServiceAdded for |service1_| here.
403 event_router()->DeviceAdded(mock_adapter_, device0_.get());
404 event_router()->GattServiceAdded(device0_.get(), service0_.get());
405
406 std::vector<BluetoothGattService*> includes;
407 includes.push_back(service1_.get());
408 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
409 .Times(2)
410 .WillRepeatedly(Return(device0_.get()));
411 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
412 .Times(2)
413 .WillRepeatedly(Return(service0_.get()));
414 EXPECT_CALL(*service0_, GetIncludedServices())
415 .Times(2)
416 .WillOnce(Return(std::vector<BluetoothGattService*>()))
417 .WillOnce(Return(includes));
418
419 listener.Reply("go");
420 listener.Reset();
421
422 EXPECT_TRUE(listener.WaitUntilSatisfied());
423
424 listener.Reply("go");
425
426 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
427 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
428 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
429 }
430
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetCharacteristics)431 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristics) {
432 ResultCatcher catcher;
433 catcher.RestrictToProfile(browser()->profile());
434
435 std::vector<BluetoothGattCharacteristic*> characteristics;
436 characteristics.push_back(chrc0_.get());
437 characteristics.push_back(chrc1_.get());
438
439 event_router()->DeviceAdded(mock_adapter_, device0_.get());
440 event_router()->GattServiceAdded(device0_.get(), service0_.get());
441
442 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(3).WillRepeatedly(
443 Return(device0_.get()));
444 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
445 .Times(3)
446 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
447 .WillRepeatedly(Return(service0_.get()));
448 EXPECT_CALL(*service0_, GetCharacteristics())
449 .Times(2)
450 .WillOnce(Return(std::vector<BluetoothGattCharacteristic*>()))
451 .WillOnce(Return(characteristics));
452
453 ExtensionTestMessageListener listener("ready", true);
454 ASSERT_TRUE(LoadExtension(
455 test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristics")));
456 EXPECT_TRUE(listener.WaitUntilSatisfied());
457
458 listener.Reply("go");
459
460 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
461 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
462 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
463 }
464
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetCharacteristic)465 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristic) {
466 ResultCatcher catcher;
467 catcher.RestrictToProfile(browser()->profile());
468
469 event_router()->DeviceAdded(mock_adapter_, device0_.get());
470 event_router()->GattServiceAdded(device0_.get(), service0_.get());
471 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
472
473 EXPECT_CALL(*mock_adapter_, GetDevice(_))
474 .Times(4)
475 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
476 .WillRepeatedly(Return(device0_.get()));
477
478 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
479 .Times(3)
480 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
481 .WillRepeatedly(Return(service0_.get()));
482
483 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
484 .Times(2)
485 .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
486 .WillOnce(Return(chrc0_.get()));
487
488 // Load the extension and wait for first test.
489 ExtensionTestMessageListener listener("ready", true);
490 ASSERT_TRUE(LoadExtension(
491 test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristic")));
492 EXPECT_TRUE(listener.WaitUntilSatisfied());
493
494 listener.Reply("go");
495
496 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
497
498 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
499 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
500 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
501 }
502
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,CharacteristicProperties)503 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicProperties) {
504 ResultCatcher catcher;
505 catcher.RestrictToProfile(browser()->profile());
506
507 event_router()->DeviceAdded(mock_adapter_, device0_.get());
508 event_router()->GattServiceAdded(device0_.get(), service0_.get());
509 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
510
511 EXPECT_CALL(*mock_adapter_, GetDevice(_))
512 .Times(12)
513 .WillRepeatedly(Return(device0_.get()));
514 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
515 .Times(12)
516 .WillRepeatedly(Return(service0_.get()));
517 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
518 .Times(12)
519 .WillRepeatedly(Return(chrc0_.get()));
520 EXPECT_CALL(*chrc0_, GetProperties())
521 .Times(12)
522 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNone))
523 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyBroadcast))
524 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyRead))
525 .WillOnce(
526 Return(BluetoothGattCharacteristic::kPropertyWriteWithoutResponse))
527 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyWrite))
528 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNotify))
529 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyIndicate))
530 .WillOnce(Return(
531 BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites))
532 .WillOnce(
533 Return(BluetoothGattCharacteristic::kPropertyExtendedProperties))
534 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyReliableWrite))
535 .WillOnce(
536 Return(BluetoothGattCharacteristic::kPropertyWritableAuxiliaries))
537 .WillOnce(Return(
538 BluetoothGattCharacteristic::kPropertyBroadcast |
539 BluetoothGattCharacteristic::kPropertyRead |
540 BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
541 BluetoothGattCharacteristic::kPropertyWrite |
542 BluetoothGattCharacteristic::kPropertyNotify |
543 BluetoothGattCharacteristic::kPropertyIndicate |
544 BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites |
545 BluetoothGattCharacteristic::kPropertyExtendedProperties |
546 BluetoothGattCharacteristic::kPropertyReliableWrite |
547 BluetoothGattCharacteristic::kPropertyWritableAuxiliaries));
548
549 ExtensionTestMessageListener listener("ready", true);
550 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
551 "bluetooth_low_energy/characteristic_properties")));
552 EXPECT_TRUE(listener.WaitUntilSatisfied());
553
554 listener.Reply("go");
555
556 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
557
558 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
559 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
560 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
561 }
562
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetRemovedCharacteristic)563 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedCharacteristic) {
564 ResultCatcher catcher;
565 catcher.RestrictToProfile(browser()->profile());
566
567 EXPECT_CALL(*mock_adapter_, GetDevice(_))
568 .Times(1)
569 .WillOnce(Return(device0_.get()));
570 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
571 .Times(1)
572 .WillOnce(Return(service0_.get()));
573 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
574 .Times(1)
575 .WillOnce(Return(chrc0_.get()));
576
577 event_router()->DeviceAdded(mock_adapter_, device0_.get());
578 event_router()->GattServiceAdded(device0_.get(), service0_.get());
579 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
580
581 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
582 "bluetooth_low_energy/get_removed_characteristic")));
583
584 ExtensionTestMessageListener listener("ready", true);
585 EXPECT_TRUE(listener.WaitUntilSatisfied());
586 testing::Mock::VerifyAndClearExpectations(mock_adapter_);
587 testing::Mock::VerifyAndClearExpectations(device0_.get());
588 testing::Mock::VerifyAndClearExpectations(service0_.get());
589
590 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
591 EXPECT_CALL(*device0_, GetGattService(_)).Times(0);
592 EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0);
593
594 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
595
596 listener.Reply("go");
597 listener.Reset();
598 EXPECT_TRUE(listener.WaitUntilSatisfied());
599
600 listener.Reply("go");
601
602 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
603 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
604 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
605 }
606
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,CharacteristicValueChanged)607 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) {
608 ResultCatcher catcher;
609 catcher.RestrictToProfile(browser()->profile());
610
611 // Cause events to be sent to the extension.
612 event_router()->DeviceAdded(mock_adapter_, device0_.get());
613 event_router()->GattServiceAdded(device0_.get(), service0_.get());
614 event_router()->GattServiceAdded(device0_.get(), service1_.get());
615 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
616 event_router()->GattCharacteristicAdded(service1_.get(), chrc2_.get());
617
618 EXPECT_CALL(*mock_adapter_, GetDevice(_))
619 .Times(2)
620 .WillRepeatedly(Return(device0_.get()));
621 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
622 .Times(1)
623 .WillOnce(Return(service0_.get()));
624 EXPECT_CALL(*device0_, GetGattService(kTestServiceId1))
625 .Times(1)
626 .WillOnce(Return(service1_.get()));
627 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
628 .Times(1)
629 .WillOnce(Return(chrc0_.get()));
630 EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2))
631 .Times(1)
632 .WillOnce(Return(chrc2_.get()));
633
634 BluetoothGattNotifySession* session0 =
635 new testing::NiceMock<MockBluetoothGattNotifySession>(
636 kTestCharacteristicId0);
637 BluetoothGattNotifySession* session1 =
638 new testing::NiceMock<MockBluetoothGattNotifySession>(
639 kTestCharacteristicId2);
640
641 EXPECT_CALL(*chrc0_, StartNotifySession(_, _))
642 .Times(1)
643 .WillOnce(
644 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
645 session0));
646 EXPECT_CALL(*chrc2_, StartNotifySession(_, _))
647 .Times(1)
648 .WillOnce(
649 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
650 session1));
651
652 ExtensionTestMessageListener listener("ready", true);
653 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
654 "bluetooth_low_energy/characteristic_value_changed")));
655
656 EXPECT_TRUE(listener.WaitUntilSatisfied());
657
658 std::vector<uint8> value;
659 event_router()->GattCharacteristicValueChanged(
660 service0_.get(), chrc0_.get(), value);
661 event_router()->GattCharacteristicValueChanged(
662 service1_.get(), chrc2_.get(), value);
663
664 listener.Reply("go");
665
666 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
667 event_router()->GattCharacteristicRemoved(service1_.get(), chrc2_.get());
668 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
669 event_router()->GattServiceRemoved(device0_.get(), service1_.get());
670 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
671 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
672 }
673
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,ReadCharacteristicValue)674 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadCharacteristicValue) {
675 ResultCatcher catcher;
676 catcher.RestrictToProfile(browser()->profile());
677
678 event_router()->DeviceAdded(mock_adapter_, device0_.get());
679 event_router()->GattServiceAdded(device0_.get(), service0_.get());
680 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
681
682 EXPECT_CALL(*mock_adapter_, GetDevice(_))
683 .Times(3)
684 .WillRepeatedly(Return(device0_.get()));
685
686 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
687 .Times(3)
688 .WillRepeatedly(Return(service0_.get()));
689
690 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
691 .Times(3)
692 .WillRepeatedly(Return(chrc0_.get()));
693
694 std::vector<uint8> value;
695 EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic(_, _))
696 .Times(2)
697 .WillOnce(InvokeCallbackArgument<1>())
698 .WillOnce(InvokeCallbackArgument<0>(value));
699
700 ExtensionTestMessageListener listener("ready", true);
701 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
702 "bluetooth_low_energy/read_characteristic_value")));
703 EXPECT_TRUE(listener.WaitUntilSatisfied());
704
705 listener.Reply("go");
706
707 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
708
709 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
710 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
711 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
712 }
713
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,WriteCharacteristicValue)714 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteCharacteristicValue) {
715 ResultCatcher catcher;
716 catcher.RestrictToProfile(browser()->profile());
717
718 event_router()->DeviceAdded(mock_adapter_, device0_.get());
719 event_router()->GattServiceAdded(device0_.get(), service0_.get());
720 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
721
722 EXPECT_CALL(*mock_adapter_, GetDevice(_))
723 .Times(3)
724 .WillRepeatedly(Return(device0_.get()));
725
726 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
727 .Times(3)
728 .WillRepeatedly(Return(service0_.get()));
729
730 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
731 .Times(3)
732 .WillRepeatedly(Return(chrc0_.get()));
733
734 std::vector<uint8> write_value;
735 EXPECT_CALL(*chrc0_, WriteRemoteCharacteristic(_, _, _))
736 .Times(2)
737 .WillOnce(InvokeCallbackArgument<2>())
738 .WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>()));
739
740 EXPECT_CALL(*chrc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value));
741
742 ExtensionTestMessageListener listener("ready", true);
743 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
744 "bluetooth_low_energy/write_characteristic_value")));
745 EXPECT_TRUE(listener.WaitUntilSatisfied());
746
747 listener.Reply("go");
748
749 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
750
751 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
752 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
753 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
754 }
755
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetDescriptors)756 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptors) {
757 ResultCatcher catcher;
758 catcher.RestrictToProfile(browser()->profile());
759
760 std::vector<BluetoothGattDescriptor*> descriptors;
761 descriptors.push_back(desc0_.get());
762 descriptors.push_back(desc1_.get());
763
764 event_router()->DeviceAdded(mock_adapter_, device0_.get());
765 event_router()->GattServiceAdded(device0_.get(), service0_.get());
766 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
767
768 EXPECT_CALL(*mock_adapter_, GetDevice(_))
769 .Times(3)
770 .WillRepeatedly(Return(device0_.get()));
771 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
772 .Times(3)
773 .WillRepeatedly(Return(service0_.get()));
774 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
775 .Times(3)
776 .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
777 .WillRepeatedly(Return(chrc0_.get()));
778 EXPECT_CALL(*chrc0_, GetDescriptors())
779 .Times(2)
780 .WillOnce(Return(std::vector<BluetoothGattDescriptor*>()))
781 .WillOnce(Return(descriptors));
782
783 ExtensionTestMessageListener listener("ready", true);
784 ASSERT_TRUE(LoadExtension(
785 test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptors")));
786 EXPECT_TRUE(listener.WaitUntilSatisfied());
787
788 listener.Reply("go");
789
790 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
791
792 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
793 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
794 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
795 }
796
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetDescriptor)797 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptor) {
798 ResultCatcher catcher;
799 catcher.RestrictToProfile(browser()->profile());
800
801 event_router()->DeviceAdded(mock_adapter_, device0_.get());
802 event_router()->GattServiceAdded(device0_.get(), service0_.get());
803 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
804 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
805
806 EXPECT_CALL(*mock_adapter_, GetDevice(_))
807 .Times(5)
808 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
809 .WillRepeatedly(Return(device0_.get()));
810
811 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
812 .Times(4)
813 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
814 .WillRepeatedly(Return(service0_.get()));
815
816 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
817 .Times(3)
818 .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
819 .WillRepeatedly(Return(chrc0_.get()));
820
821 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
822 .Times(2)
823 .WillOnce(Return(static_cast<BluetoothGattDescriptor*>(NULL)))
824 .WillOnce(Return(desc0_.get()));
825
826 // Load the extension and wait for first test.
827 ExtensionTestMessageListener listener("ready", true);
828 ASSERT_TRUE(LoadExtension(
829 test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptor")));
830 EXPECT_TRUE(listener.WaitUntilSatisfied());
831
832 listener.Reply("go");
833
834 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
835
836 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
837 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
838 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
839 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
840 }
841
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GetRemovedDescriptor)842 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedDescriptor) {
843 ResultCatcher catcher;
844 catcher.RestrictToProfile(browser()->profile());
845
846 EXPECT_CALL(*mock_adapter_, GetDevice(_))
847 .Times(1)
848 .WillOnce(Return(device0_.get()));
849 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
850 .Times(1)
851 .WillOnce(Return(service0_.get()));
852 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
853 .Times(1)
854 .WillOnce(Return(chrc0_.get()));
855 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
856 .Times(1)
857 .WillOnce(Return(desc0_.get()));
858
859 event_router()->DeviceAdded(mock_adapter_, device0_.get());
860 event_router()->GattServiceAdded(device0_.get(), service0_.get());
861 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
862 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
863
864 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
865 "bluetooth_low_energy/get_removed_descriptor")));
866
867 ExtensionTestMessageListener listener("ready", true);
868 EXPECT_TRUE(listener.WaitUntilSatisfied());
869 testing::Mock::VerifyAndClearExpectations(mock_adapter_);
870 testing::Mock::VerifyAndClearExpectations(device0_.get());
871 testing::Mock::VerifyAndClearExpectations(service0_.get());
872 testing::Mock::VerifyAndClearExpectations(chrc0_.get());
873
874 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
875 EXPECT_CALL(*device0_, GetGattService(_)).Times(0);
876 EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0);
877 EXPECT_CALL(*chrc0_, GetDescriptor(_)).Times(0);
878
879 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
880
881 listener.Reply("go");
882 listener.Reset();
883 EXPECT_TRUE(listener.WaitUntilSatisfied());
884
885 listener.Reply("go");
886
887 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
888 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
889 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
890 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
891 }
892
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,DescriptorValueChanged)893 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, DescriptorValueChanged) {
894 ResultCatcher catcher;
895 catcher.RestrictToProfile(browser()->profile());
896
897 event_router()->DeviceAdded(mock_adapter_, device0_.get());
898 event_router()->GattServiceAdded(device0_.get(), service0_.get());
899 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
900 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
901 event_router()->GattDescriptorAdded(chrc0_.get(), desc1_.get());
902
903 // Load the extension and let it set up.
904 ExtensionTestMessageListener listener("ready", true);
905 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
906 "bluetooth_low_energy/descriptor_value_changed")));
907
908 // Cause events to be sent to the extension.
909 std::vector<uint8> value;
910 event_router()->GattDescriptorValueChanged(chrc0_.get(), desc0_.get(), value);
911 event_router()->GattDescriptorValueChanged(chrc0_.get(), desc1_.get(), value);
912
913 EXPECT_TRUE(listener.WaitUntilSatisfied());
914 listener.Reply("go");
915
916 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
917 event_router()->GattDescriptorRemoved(chrc0_.get(), desc1_.get());
918 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
919 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
920 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
921 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
922 }
923
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,ReadDescriptorValue)924 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) {
925 ResultCatcher catcher;
926 catcher.RestrictToProfile(browser()->profile());
927
928 event_router()->DeviceAdded(mock_adapter_, device0_.get());
929 event_router()->GattServiceAdded(device0_.get(), service0_.get());
930 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
931 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
932
933 EXPECT_CALL(*mock_adapter_, GetDevice(_))
934 .Times(3)
935 .WillRepeatedly(Return(device0_.get()));
936
937 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
938 .Times(3)
939 .WillRepeatedly(Return(service0_.get()));
940
941 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
942 .Times(3)
943 .WillRepeatedly(Return(chrc0_.get()));
944
945 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
946 .Times(3)
947 .WillRepeatedly(Return(desc0_.get()));
948
949 std::vector<uint8> value;
950 EXPECT_CALL(*desc0_, ReadRemoteDescriptor(_, _))
951 .Times(2)
952 .WillOnce(InvokeCallbackArgument<1>())
953 .WillOnce(InvokeCallbackArgument<0>(value));
954
955 ExtensionTestMessageListener listener("ready", true);
956 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
957 "bluetooth_low_energy/read_descriptor_value")));
958 EXPECT_TRUE(listener.WaitUntilSatisfied());
959
960 listener.Reply("go");
961
962 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
963
964 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
965 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
966 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
967 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
968 }
969
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,WriteDescriptorValue)970 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteDescriptorValue) {
971 ResultCatcher catcher;
972 catcher.RestrictToProfile(browser()->profile());
973
974 event_router()->DeviceAdded(mock_adapter_, device0_.get());
975 event_router()->GattServiceAdded(device0_.get(), service0_.get());
976 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
977 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
978
979 EXPECT_CALL(*mock_adapter_, GetDevice(_))
980 .Times(3)
981 .WillRepeatedly(Return(device0_.get()));
982
983 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
984 .Times(3)
985 .WillRepeatedly(Return(service0_.get()));
986
987 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
988 .Times(3)
989 .WillRepeatedly(Return(chrc0_.get()));
990
991 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
992 .Times(3)
993 .WillRepeatedly(Return(desc0_.get()));
994
995 std::vector<uint8> write_value;
996 EXPECT_CALL(*desc0_, WriteRemoteDescriptor(_, _, _))
997 .Times(2)
998 .WillOnce(InvokeCallbackArgument<2>())
999 .WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>()));
1000
1001 EXPECT_CALL(*desc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value));
1002
1003 ExtensionTestMessageListener listener("ready", true);
1004 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1005 "bluetooth_low_energy/write_descriptor_value")));
1006 EXPECT_TRUE(listener.WaitUntilSatisfied());
1007
1008 listener.Reply("go");
1009
1010 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1011
1012 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
1013 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
1014 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
1015 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1016 }
1017
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,PermissionDenied)1018 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, PermissionDenied) {
1019 ResultCatcher catcher;
1020 catcher.RestrictToProfile(browser()->profile());
1021
1022 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1023 "bluetooth_low_energy/permission_denied")));
1024 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1025 }
1026
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,UuidPermissionMethods)1027 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionMethods) {
1028 ResultCatcher catcher;
1029 catcher.RestrictToProfile(browser()->profile());
1030
1031 event_router()->DeviceAdded(mock_adapter_, device0_.get());
1032 event_router()->GattServiceAdded(device0_.get(), service0_.get());
1033 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
1034 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
1035
1036 std::vector<BluetoothGattService*> services;
1037 services.push_back(service0_.get());
1038
1039 EXPECT_CALL(*mock_adapter_, GetDevice(_))
1040 .WillRepeatedly(Return(device0_.get()));
1041 EXPECT_CALL(*device0_, GetGattServices()).WillOnce(Return(services));
1042 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
1043 .WillRepeatedly(Return(service0_.get()));
1044 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
1045 .WillRepeatedly(Return(chrc0_.get()));
1046 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
1047 .WillRepeatedly(Return(desc0_.get()));
1048
1049 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1050 "bluetooth_low_energy/uuid_permission_methods")));
1051 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1052
1053 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
1054 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
1055 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
1056 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1057 }
1058
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,UuidPermissionEvents)1059 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionEvents) {
1060 ResultCatcher catcher;
1061 catcher.RestrictToProfile(browser()->profile());
1062
1063 ExtensionTestMessageListener listener("ready", true);
1064 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1065 "bluetooth_low_energy/uuid_permission_events")));
1066
1067 // Cause events to be sent to the extension.
1068 event_router()->DeviceAdded(mock_adapter_, device0_.get());
1069 event_router()->GattServiceAdded(device0_.get(), service0_.get());
1070 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
1071 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get());
1072
1073 std::vector<uint8> value;
1074 event_router()->GattCharacteristicValueChanged(
1075 service0_.get(), chrc0_.get(), value);
1076 event_router()->GattDescriptorValueChanged(chrc0_.get(), desc0_.get(), value);
1077 event_router()->GattServiceChanged(service0_.get());
1078
1079 EXPECT_TRUE(listener.WaitUntilSatisfied());
1080 listener.Reply("go");
1081 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1082
1083 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get());
1084 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
1085 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
1086 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1087 }
1088
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,GattConnection)1089 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GattConnection) {
1090 ResultCatcher catcher;
1091 catcher.RestrictToProfile(browser()->profile());
1092
1093 event_router()->DeviceAdded(mock_adapter_, device0_.get());
1094 event_router()->DeviceAdded(mock_adapter_, device1_.get());
1095
1096 EXPECT_CALL(*mock_adapter_, GetDevice(_))
1097 .WillRepeatedly(Return(static_cast<BluetoothDevice*>(NULL)));
1098 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
1099 .WillRepeatedly(Return(device0_.get()));
1100 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress1))
1101 .WillRepeatedly(Return(device1_.get()));
1102 EXPECT_CALL(*device0_, CreateGattConnection(_, _))
1103 .Times(3)
1104 .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_FAILED))
1105 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1106 CreateGattConnection(kTestLeDeviceAddress0,
1107 true /* expect_disconnect */)))
1108 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1109 CreateGattConnection(kTestLeDeviceAddress0,
1110 false /* expect_disconnect */)));
1111 EXPECT_CALL(*device1_, CreateGattConnection(_, _))
1112 .Times(1)
1113 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1114 CreateGattConnection(kTestLeDeviceAddress1,
1115 true /* expect_disconnect */)));
1116
1117 ASSERT_TRUE(LoadExtension(
1118 test_data_dir_.AppendASCII("bluetooth_low_energy/gatt_connection")));
1119 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1120
1121 event_router()->DeviceRemoved(mock_adapter_, device1_.get());
1122 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1123 }
1124
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,ReconnectAfterDisconnected)1125 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReconnectAfterDisconnected) {
1126 ResultCatcher catcher;
1127 catcher.RestrictToProfile(browser()->profile());
1128
1129 event_router()->DeviceAdded(mock_adapter_, device0_.get());
1130
1131 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
1132 .WillRepeatedly(Return(device0_.get()));
1133
1134 MockBluetoothGattConnection* first_conn =
1135 static_cast<MockBluetoothGattConnection*>(CreateGattConnection(
1136 kTestLeDeviceAddress0, false /* expect_disconnect */));
1137 EXPECT_CALL(*first_conn, IsConnected())
1138 .Times(2)
1139 .WillOnce(Return(true))
1140 .WillOnce(Return(false));
1141
1142 EXPECT_CALL(*device0_, CreateGattConnection(_, _))
1143 .Times(2)
1144 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1145 first_conn))
1146 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1147 CreateGattConnection(kTestLeDeviceAddress0,
1148 false /* expect_disconnect */)));
1149
1150 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1151 "bluetooth_low_energy/reconnect_after_disconnected")));
1152 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1153
1154 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1155 }
1156
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,ConnectInProgress)1157 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ConnectInProgress) {
1158 ResultCatcher catcher;
1159 catcher.RestrictToProfile(browser()->profile());
1160
1161 event_router()->DeviceAdded(mock_adapter_, device0_.get());
1162
1163 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
1164 .WillRepeatedly(Return(device0_.get()));
1165
1166 BluetoothDevice::GattConnectionCallback connect_callback;
1167 base::Closure disconnect_callback;
1168
1169 testing::NiceMock<MockBluetoothGattConnection>* conn =
1170 new testing::NiceMock<MockBluetoothGattConnection>(
1171 kTestLeDeviceAddress0);
1172 scoped_ptr<BluetoothGattConnection> conn_ptr(conn);
1173 EXPECT_CALL(*conn, Disconnect(_))
1174 .Times(1)
1175 .WillOnce(SaveArg<0>(&disconnect_callback));
1176
1177 EXPECT_CALL(*device0_, CreateGattConnection(_, _))
1178 .Times(1)
1179 .WillOnce(SaveArg<0>(&connect_callback));
1180
1181 ExtensionTestMessageListener listener("ready", true);
1182 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1183 "bluetooth_low_energy/connect_in_progress")));
1184
1185 listener.WaitUntilSatisfied();
1186 connect_callback.Run(conn_ptr.Pass());
1187
1188 listener.Reset();
1189 listener.WaitUntilSatisfied();
1190 disconnect_callback.Run();
1191
1192 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1193
1194 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1195 }
1196
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest,StartStopNotifications)1197 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, StartStopNotifications) {
1198 ResultCatcher catcher;
1199 catcher.RestrictToProfile(browser()->profile());
1200
1201 event_router()->DeviceAdded(mock_adapter_, device0_.get());
1202 event_router()->GattServiceAdded(device0_.get(), service0_.get());
1203 event_router()->GattServiceAdded(device0_.get(), service1_.get());
1204 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
1205 event_router()->GattCharacteristicAdded(service0_.get(), chrc1_.get());
1206 event_router()->GattCharacteristicAdded(service1_.get(), chrc2_.get());
1207
1208 EXPECT_CALL(*mock_adapter_, GetDevice(_))
1209 .WillRepeatedly(Return(device0_.get()));
1210 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
1211 .WillRepeatedly(Return(service0_.get()));
1212 EXPECT_CALL(*device0_, GetGattService(kTestServiceId1))
1213 .WillRepeatedly(Return(service1_.get()));
1214 EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2))
1215 .Times(1)
1216 .WillOnce(Return(chrc2_.get()));
1217 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
1218 .Times(2)
1219 .WillRepeatedly(Return(chrc0_.get()));
1220 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId1))
1221 .Times(1)
1222 .WillOnce(Return(chrc1_.get()));
1223
1224 BluetoothGattNotifySession* session0 =
1225 new testing::NiceMock<MockBluetoothGattNotifySession>(
1226 kTestCharacteristicId0);
1227 MockBluetoothGattNotifySession* session1 =
1228 new testing::NiceMock<MockBluetoothGattNotifySession>(
1229 kTestCharacteristicId1);
1230
1231 EXPECT_CALL(*session1, Stop(_))
1232 .Times(1)
1233 .WillOnce(InvokeCallbackArgument<0>());
1234
1235 EXPECT_CALL(*chrc0_, StartNotifySession(_, _))
1236 .Times(2)
1237 .WillOnce(InvokeCallbackArgument<1>())
1238 .WillOnce(
1239 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
1240 session0));
1241 EXPECT_CALL(*chrc1_, StartNotifySession(_, _))
1242 .Times(1)
1243 .WillOnce(
1244 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
1245 session1));
1246
1247 ExtensionTestMessageListener listener("ready", true);
1248 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1249 "bluetooth_low_energy/start_stop_notifications")));
1250
1251 EXPECT_TRUE(listener.WaitUntilSatisfied());
1252
1253 std::vector<uint8> value;
1254 event_router()->GattCharacteristicValueChanged(
1255 service0_.get(), chrc0_.get(), value);
1256 event_router()->GattCharacteristicValueChanged(
1257 service0_.get(), chrc1_.get(), value);
1258 event_router()->GattCharacteristicValueChanged(
1259 service1_.get(), chrc2_.get(), value);
1260
1261 listener.Reply("go");
1262
1263 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1264 event_router()->GattCharacteristicRemoved(service1_.get(), chrc2_.get());
1265 event_router()->GattCharacteristicRemoved(service0_.get(), chrc1_.get());
1266 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
1267 event_router()->GattServiceRemoved(device0_.get(), service1_.get());
1268 event_router()->GattServiceRemoved(device0_.get(), service0_.get());
1269 event_router()->DeviceRemoved(mock_adapter_, device0_.get());
1270 }
1271
1272 } // namespace
1273