• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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