Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / bluetooth_low_energy / bluetooth_low_energy_apitest.cc
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/extension_apitest.h"
7 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
8 #include "device/bluetooth/test/mock_bluetooth_device.h"
9 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
10 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
11 #include "device/bluetooth/test/mock_bluetooth_gatt_descriptor.h"
12 #include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h"
13 #include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
14 #include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h"
15 #include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h"
16 #include "extensions/common/test_util.h"
17 #include "extensions/test/extension_test_message_listener.h"
18 #include "extensions/test/result_catcher.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20
21 using device::BluetoothUUID;
22 using device::BluetoothAdapter;
23 using device::BluetoothDevice;
24 using device::BluetoothGattCharacteristic;
25 using device::BluetoothGattConnection;
26 using device::BluetoothGattDescriptor;
27 using device::BluetoothGattService;
28 using device::BluetoothGattNotifySession;
29 using device::MockBluetoothAdapter;
30 using device::MockBluetoothDevice;
31 using device::MockBluetoothGattCharacteristic;
32 using device::MockBluetoothGattConnection;
33 using device::MockBluetoothGattDescriptor;
34 using device::MockBluetoothGattService;
35 using device::MockBluetoothGattNotifySession;
36 using extensions::BluetoothLowEnergyEventRouter;
37 using extensions::ResultCatcher;
38 using testing::Invoke;
39 using testing::Return;
40 using testing::ReturnRef;
41 using testing::ReturnRefOfCopy;
42 using testing::SaveArg;
43 using testing::_;
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:
94   BluetoothLowEnergyApiTest() {}
95
96   virtual ~BluetoothLowEnergyApiTest() {}
97
98   virtual void SetUpOnMainThread() OVERRIDE {
99     ExtensionApiTest::SetUpOnMainThread();
100     empty_extension_ = extensions::test_util::CreateEmptyExtension();
101     SetUpMocks();
102   }
103
104   virtual void TearDownOnMainThread() OVERRIDE {
105     EXPECT_CALL(*mock_adapter_, RemoveObserver(_));
106   }
107
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:
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
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
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
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
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
261 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetServices) {
262   ResultCatcher catcher;
263   catcher.RestrictToBrowserContext(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
290 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetService) {
291   ResultCatcher catcher;
292   catcher.RestrictToBrowserContext(browser()->profile());
293
294   event_router()->GattServiceAdded(
295       mock_adapter_, 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(
318       mock_adapter_, device0_.get(), service0_.get());
319 }
320
321 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ServiceEvents) {
322   ResultCatcher catcher;
323   catcher.RestrictToBrowserContext(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   // These will create the identifier mappings.
331   event_router()->GattServiceAdded(
332       mock_adapter_, device0_.get(), service0_.get());
333   event_router()->GattServiceAdded(
334       mock_adapter_, device0_.get(), service1_.get());
335
336   // These will send the onServiceAdded event to apps.
337   event_router()->GattDiscoveryCompleteForService(mock_adapter_,
338                                                   service0_.get());
339   event_router()->GattDiscoveryCompleteForService(mock_adapter_,
340                                                   service1_.get());
341
342   // This will send the onServiceChanged event to apps.
343   event_router()->GattServiceChanged(mock_adapter_, service1_.get());
344
345   // This will send the  onServiceRemoved event to apps.
346   event_router()->GattServiceRemoved(
347       mock_adapter_, device0_.get(), service0_.get());
348
349   EXPECT_TRUE(listener.WaitUntilSatisfied());
350   listener.Reply("go");
351
352   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
353   event_router()->GattServiceRemoved(
354       mock_adapter_, device0_.get(), service1_.get());
355 }
356
357 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedService) {
358   ResultCatcher catcher;
359   catcher.RestrictToBrowserContext(browser()->profile());
360
361   // Load the extension and let it set up.
362   ASSERT_TRUE(LoadExtension(
363       test_data_dir_.AppendASCII("bluetooth_low_energy/get_removed_service")));
364
365   // 1. getService success.
366   EXPECT_CALL(*mock_adapter_, GetDevice(_))
367       .Times(1)
368       .WillOnce(Return(device0_.get()));
369   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
370       .Times(1)
371       .WillOnce(Return(service0_.get()));
372
373   event_router()->GattServiceAdded(
374       mock_adapter_, device0_.get(), service0_.get());
375   event_router()->GattDiscoveryCompleteForService(mock_adapter_,
376                                                   service0_.get());
377
378   ExtensionTestMessageListener get_service_success_listener("getServiceSuccess",
379                                                             true);
380   EXPECT_TRUE(get_service_success_listener.WaitUntilSatisfied());
381   testing::Mock::VerifyAndClearExpectations(mock_adapter_);
382   testing::Mock::VerifyAndClearExpectations(device0_.get());
383
384   // 2. getService fail.
385   EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
386   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)).Times(0);
387
388   event_router()->GattServiceRemoved(
389       mock_adapter_, device0_.get(), service0_.get());
390
391   ExtensionTestMessageListener get_service_fail_listener("getServiceFail",
392                                                          true);
393   EXPECT_TRUE(get_service_fail_listener.WaitUntilSatisfied());
394   testing::Mock::VerifyAndClearExpectations(mock_adapter_);
395   testing::Mock::VerifyAndClearExpectations(device0_.get());
396
397   get_service_fail_listener.Reply("go");
398
399   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
400 }
401
402 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetIncludedServices) {
403   ResultCatcher catcher;
404   catcher.RestrictToBrowserContext(browser()->profile());
405
406   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
407       "bluetooth_low_energy/get_included_services")));
408
409   // Wait for initial call to end with failure as there is no mapping.
410   ExtensionTestMessageListener listener("ready", true);
411   EXPECT_TRUE(listener.WaitUntilSatisfied());
412
413   // Set up for the rest of the calls before replying. Included services can be
414   // returned even if there is no instance ID mapping for them yet, so no need
415   // to call GattServiceAdded for |service1_| here.
416   event_router()->GattServiceAdded(
417       mock_adapter_, device0_.get(), service0_.get());
418
419   std::vector<BluetoothGattService*> includes;
420   includes.push_back(service1_.get());
421   EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
422       .Times(2)
423       .WillRepeatedly(Return(device0_.get()));
424   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
425       .Times(2)
426       .WillRepeatedly(Return(service0_.get()));
427   EXPECT_CALL(*service0_, GetIncludedServices())
428       .Times(2)
429       .WillOnce(Return(std::vector<BluetoothGattService*>()))
430       .WillOnce(Return(includes));
431
432   listener.Reply("go");
433   listener.Reset();
434
435   EXPECT_TRUE(listener.WaitUntilSatisfied());
436
437   listener.Reply("go");
438
439   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
440   event_router()->GattServiceRemoved(
441       mock_adapter_, device0_.get(), service0_.get());
442 }
443
444 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristics) {
445   ResultCatcher catcher;
446   catcher.RestrictToBrowserContext(browser()->profile());
447
448   std::vector<BluetoothGattCharacteristic*> characteristics;
449   characteristics.push_back(chrc0_.get());
450   characteristics.push_back(chrc1_.get());
451
452   event_router()->GattServiceAdded(
453       mock_adapter_, device0_.get(), service0_.get());
454
455   EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(3).WillRepeatedly(
456       Return(device0_.get()));
457   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
458       .Times(3)
459       .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
460       .WillRepeatedly(Return(service0_.get()));
461   EXPECT_CALL(*service0_, GetCharacteristics())
462       .Times(2)
463       .WillOnce(Return(std::vector<BluetoothGattCharacteristic*>()))
464       .WillOnce(Return(characteristics));
465
466   ExtensionTestMessageListener listener("ready", true);
467   ASSERT_TRUE(LoadExtension(
468       test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristics")));
469   EXPECT_TRUE(listener.WaitUntilSatisfied());
470
471   listener.Reply("go");
472
473   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
474   event_router()->GattServiceRemoved(
475       mock_adapter_, device0_.get(), service0_.get());
476 }
477
478 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristic) {
479   ResultCatcher catcher;
480   catcher.RestrictToBrowserContext(browser()->profile());
481
482   event_router()->GattServiceAdded(
483       mock_adapter_, device0_.get(), service0_.get());
484   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
485
486   EXPECT_CALL(*mock_adapter_, GetDevice(_))
487       .Times(4)
488       .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
489       .WillRepeatedly(Return(device0_.get()));
490
491   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
492       .Times(3)
493       .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
494       .WillRepeatedly(Return(service0_.get()));
495
496   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
497       .Times(2)
498       .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
499       .WillOnce(Return(chrc0_.get()));
500
501   // Load the extension and wait for first test.
502   ExtensionTestMessageListener listener("ready", true);
503   ASSERT_TRUE(LoadExtension(
504       test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristic")));
505   EXPECT_TRUE(listener.WaitUntilSatisfied());
506
507   listener.Reply("go");
508
509   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
510
511   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
512   event_router()->GattServiceRemoved(
513       mock_adapter_, device0_.get(), service0_.get());
514 }
515
516 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicProperties) {
517   ResultCatcher catcher;
518   catcher.RestrictToBrowserContext(browser()->profile());
519
520   event_router()->GattServiceAdded(
521       mock_adapter_, device0_.get(), service0_.get());
522   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
523
524   EXPECT_CALL(*mock_adapter_, GetDevice(_))
525       .Times(12)
526       .WillRepeatedly(Return(device0_.get()));
527   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
528       .Times(12)
529       .WillRepeatedly(Return(service0_.get()));
530   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
531       .Times(12)
532       .WillRepeatedly(Return(chrc0_.get()));
533   EXPECT_CALL(*chrc0_, GetProperties())
534       .Times(12)
535       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNone))
536       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyBroadcast))
537       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyRead))
538       .WillOnce(
539            Return(BluetoothGattCharacteristic::kPropertyWriteWithoutResponse))
540       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyWrite))
541       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNotify))
542       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyIndicate))
543       .WillOnce(Return(
544           BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites))
545       .WillOnce(
546            Return(BluetoothGattCharacteristic::kPropertyExtendedProperties))
547       .WillOnce(Return(BluetoothGattCharacteristic::kPropertyReliableWrite))
548       .WillOnce(
549            Return(BluetoothGattCharacteristic::kPropertyWritableAuxiliaries))
550       .WillOnce(Return(
551           BluetoothGattCharacteristic::kPropertyBroadcast |
552           BluetoothGattCharacteristic::kPropertyRead |
553           BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
554           BluetoothGattCharacteristic::kPropertyWrite |
555           BluetoothGattCharacteristic::kPropertyNotify |
556           BluetoothGattCharacteristic::kPropertyIndicate |
557           BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites |
558           BluetoothGattCharacteristic::kPropertyExtendedProperties |
559           BluetoothGattCharacteristic::kPropertyReliableWrite |
560           BluetoothGattCharacteristic::kPropertyWritableAuxiliaries));
561
562   ExtensionTestMessageListener listener("ready", true);
563   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
564       "bluetooth_low_energy/characteristic_properties")));
565   EXPECT_TRUE(listener.WaitUntilSatisfied());
566
567   listener.Reply("go");
568
569   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
570
571   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
572   event_router()->GattServiceRemoved(
573       mock_adapter_, device0_.get(), service0_.get());
574 }
575
576 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedCharacteristic) {
577   ResultCatcher catcher;
578   catcher.RestrictToBrowserContext(browser()->profile());
579
580   EXPECT_CALL(*mock_adapter_, GetDevice(_))
581       .Times(1)
582       .WillOnce(Return(device0_.get()));
583   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
584       .Times(1)
585       .WillOnce(Return(service0_.get()));
586   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
587       .Times(1)
588       .WillOnce(Return(chrc0_.get()));
589
590   event_router()->GattServiceAdded(
591       mock_adapter_, device0_.get(), service0_.get());
592   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
593
594   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
595       "bluetooth_low_energy/get_removed_characteristic")));
596
597   ExtensionTestMessageListener listener("ready", true);
598   EXPECT_TRUE(listener.WaitUntilSatisfied());
599   testing::Mock::VerifyAndClearExpectations(mock_adapter_);
600   testing::Mock::VerifyAndClearExpectations(device0_.get());
601   testing::Mock::VerifyAndClearExpectations(service0_.get());
602
603   EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
604   EXPECT_CALL(*device0_, GetGattService(_)).Times(0);
605   EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0);
606
607   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
608
609   listener.Reply("go");
610   listener.Reset();
611   EXPECT_TRUE(listener.WaitUntilSatisfied());
612
613   listener.Reply("go");
614
615   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
616   event_router()->GattServiceRemoved(
617       mock_adapter_, device0_.get(), service0_.get());
618 }
619
620 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) {
621   ResultCatcher catcher;
622   catcher.RestrictToBrowserContext(browser()->profile());
623
624   // Cause events to be sent to the extension.
625   event_router()->GattServiceAdded(
626       mock_adapter_, device0_.get(), service0_.get());
627   event_router()->GattServiceAdded(
628       mock_adapter_, device0_.get(), service1_.get());
629   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
630   event_router()->GattCharacteristicAdded(mock_adapter_, chrc2_.get());
631
632   EXPECT_CALL(*mock_adapter_, GetDevice(_))
633       .Times(2)
634       .WillRepeatedly(Return(device0_.get()));
635   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
636       .Times(1)
637       .WillOnce(Return(service0_.get()));
638   EXPECT_CALL(*device0_, GetGattService(kTestServiceId1))
639       .Times(1)
640       .WillOnce(Return(service1_.get()));
641   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
642       .Times(1)
643       .WillOnce(Return(chrc0_.get()));
644   EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2))
645       .Times(1)
646       .WillOnce(Return(chrc2_.get()));
647
648   BluetoothGattNotifySession* session0 =
649       new testing::NiceMock<MockBluetoothGattNotifySession>(
650           kTestCharacteristicId0);
651   BluetoothGattNotifySession* session1 =
652       new testing::NiceMock<MockBluetoothGattNotifySession>(
653           kTestCharacteristicId2);
654
655   EXPECT_CALL(*chrc0_, StartNotifySession(_, _))
656       .Times(1)
657       .WillOnce(
658           InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
659               session0));
660   EXPECT_CALL(*chrc2_, StartNotifySession(_, _))
661       .Times(1)
662       .WillOnce(
663           InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
664               session1));
665
666   ExtensionTestMessageListener listener("ready", true);
667   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
668       "bluetooth_low_energy/characteristic_value_changed")));
669
670   EXPECT_TRUE(listener.WaitUntilSatisfied());
671
672   std::vector<uint8> value;
673   event_router()->GattCharacteristicValueChanged(
674       mock_adapter_, chrc0_.get(), value);
675   event_router()->GattCharacteristicValueChanged(
676       mock_adapter_, chrc2_.get(), value);
677
678   listener.Reply("go");
679
680   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
681   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc2_.get());
682   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
683   event_router()->GattServiceRemoved(
684       mock_adapter_, device0_.get(), service1_.get());
685   event_router()->GattServiceRemoved(
686       mock_adapter_, device0_.get(), service0_.get());
687 }
688
689 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadCharacteristicValue) {
690   ResultCatcher catcher;
691   catcher.RestrictToBrowserContext(browser()->profile());
692
693   event_router()->GattServiceAdded(
694       mock_adapter_, device0_.get(), service0_.get());
695   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
696
697   EXPECT_CALL(*mock_adapter_, GetDevice(_))
698       .Times(3)
699       .WillRepeatedly(Return(device0_.get()));
700
701   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
702       .Times(3)
703       .WillRepeatedly(Return(service0_.get()));
704
705   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
706       .Times(3)
707       .WillRepeatedly(Return(chrc0_.get()));
708
709   std::vector<uint8> value;
710   EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic(_, _))
711       .Times(2)
712       .WillOnce(InvokeCallbackArgument<1>())
713       .WillOnce(InvokeCallbackArgument<0>(value));
714
715   ExtensionTestMessageListener listener("ready", true);
716   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
717       "bluetooth_low_energy/read_characteristic_value")));
718   EXPECT_TRUE(listener.WaitUntilSatisfied());
719
720   listener.Reply("go");
721
722   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
723
724   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
725   event_router()->GattServiceRemoved(
726       mock_adapter_, device0_.get(), service0_.get());
727 }
728
729 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteCharacteristicValue) {
730   ResultCatcher catcher;
731   catcher.RestrictToBrowserContext(browser()->profile());
732
733   event_router()->GattServiceAdded(
734       mock_adapter_, device0_.get(), service0_.get());
735   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
736
737   EXPECT_CALL(*mock_adapter_, GetDevice(_))
738       .Times(3)
739       .WillRepeatedly(Return(device0_.get()));
740
741   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
742       .Times(3)
743       .WillRepeatedly(Return(service0_.get()));
744
745   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
746       .Times(3)
747       .WillRepeatedly(Return(chrc0_.get()));
748
749   std::vector<uint8> write_value;
750   EXPECT_CALL(*chrc0_, WriteRemoteCharacteristic(_, _, _))
751       .Times(2)
752       .WillOnce(InvokeCallbackArgument<2>())
753       .WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>()));
754
755   EXPECT_CALL(*chrc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value));
756
757   ExtensionTestMessageListener listener("ready", true);
758   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
759       "bluetooth_low_energy/write_characteristic_value")));
760   EXPECT_TRUE(listener.WaitUntilSatisfied());
761
762   listener.Reply("go");
763
764   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
765
766   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
767   event_router()->GattServiceRemoved(
768       mock_adapter_, device0_.get(), service0_.get());
769 }
770
771 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptors) {
772   ResultCatcher catcher;
773   catcher.RestrictToBrowserContext(browser()->profile());
774
775   std::vector<BluetoothGattDescriptor*> descriptors;
776   descriptors.push_back(desc0_.get());
777   descriptors.push_back(desc1_.get());
778
779   event_router()->GattServiceAdded(
780       mock_adapter_, device0_.get(), service0_.get());
781   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
782
783   EXPECT_CALL(*mock_adapter_, GetDevice(_))
784       .Times(3)
785       .WillRepeatedly(Return(device0_.get()));
786   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
787       .Times(3)
788       .WillRepeatedly(Return(service0_.get()));
789   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
790       .Times(3)
791       .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
792       .WillRepeatedly(Return(chrc0_.get()));
793   EXPECT_CALL(*chrc0_, GetDescriptors())
794       .Times(2)
795       .WillOnce(Return(std::vector<BluetoothGattDescriptor*>()))
796       .WillOnce(Return(descriptors));
797
798   ExtensionTestMessageListener listener("ready", true);
799   ASSERT_TRUE(LoadExtension(
800       test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptors")));
801   EXPECT_TRUE(listener.WaitUntilSatisfied());
802
803   listener.Reply("go");
804
805   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
806
807   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
808   event_router()->GattServiceRemoved(
809       mock_adapter_, device0_.get(), service0_.get());
810 }
811
812 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptor) {
813   ResultCatcher catcher;
814   catcher.RestrictToBrowserContext(browser()->profile());
815
816   event_router()->GattServiceAdded(
817       mock_adapter_, device0_.get(), service0_.get());
818   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
819   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
820
821   EXPECT_CALL(*mock_adapter_, GetDevice(_))
822       .Times(5)
823       .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
824       .WillRepeatedly(Return(device0_.get()));
825
826   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
827       .Times(4)
828       .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
829       .WillRepeatedly(Return(service0_.get()));
830
831   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
832       .Times(3)
833       .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
834       .WillRepeatedly(Return(chrc0_.get()));
835
836   EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
837       .Times(2)
838       .WillOnce(Return(static_cast<BluetoothGattDescriptor*>(NULL)))
839       .WillOnce(Return(desc0_.get()));
840
841   // Load the extension and wait for first test.
842   ExtensionTestMessageListener listener("ready", true);
843   ASSERT_TRUE(LoadExtension(
844       test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptor")));
845   EXPECT_TRUE(listener.WaitUntilSatisfied());
846
847   listener.Reply("go");
848
849   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
850
851   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
852   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
853   event_router()->GattServiceRemoved(
854       mock_adapter_, device0_.get(), service0_.get());
855 }
856
857 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedDescriptor) {
858   ResultCatcher catcher;
859   catcher.RestrictToBrowserContext(browser()->profile());
860
861   EXPECT_CALL(*mock_adapter_, GetDevice(_))
862       .Times(1)
863       .WillOnce(Return(device0_.get()));
864   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
865       .Times(1)
866       .WillOnce(Return(service0_.get()));
867   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
868       .Times(1)
869       .WillOnce(Return(chrc0_.get()));
870   EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
871       .Times(1)
872       .WillOnce(Return(desc0_.get()));
873
874   event_router()->GattServiceAdded(
875       mock_adapter_, device0_.get(), service0_.get());
876   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
877   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
878
879   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
880       "bluetooth_low_energy/get_removed_descriptor")));
881
882   ExtensionTestMessageListener listener("ready", true);
883   EXPECT_TRUE(listener.WaitUntilSatisfied());
884   testing::Mock::VerifyAndClearExpectations(mock_adapter_);
885   testing::Mock::VerifyAndClearExpectations(device0_.get());
886   testing::Mock::VerifyAndClearExpectations(service0_.get());
887   testing::Mock::VerifyAndClearExpectations(chrc0_.get());
888
889   EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
890   EXPECT_CALL(*device0_, GetGattService(_)).Times(0);
891   EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0);
892   EXPECT_CALL(*chrc0_, GetDescriptor(_)).Times(0);
893
894   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
895
896   listener.Reply("go");
897   listener.Reset();
898   EXPECT_TRUE(listener.WaitUntilSatisfied());
899
900   listener.Reply("go");
901
902   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
903   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
904   event_router()->GattServiceRemoved(
905       mock_adapter_, device0_.get(), service0_.get());
906 }
907
908 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, DescriptorValueChanged) {
909   ResultCatcher catcher;
910   catcher.RestrictToBrowserContext(browser()->profile());
911
912   event_router()->GattServiceAdded(
913       mock_adapter_, device0_.get(), service0_.get());
914   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
915   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
916   event_router()->GattDescriptorAdded(mock_adapter_, desc1_.get());
917
918   // Load the extension and let it set up.
919   ExtensionTestMessageListener listener("ready", true);
920   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
921       "bluetooth_low_energy/descriptor_value_changed")));
922
923   // Cause events to be sent to the extension.
924   std::vector<uint8> value;
925   event_router()->GattDescriptorValueChanged(
926       mock_adapter_, desc0_.get(), value);
927   event_router()->GattDescriptorValueChanged(
928       mock_adapter_, desc1_.get(), value);
929
930   EXPECT_TRUE(listener.WaitUntilSatisfied());
931   listener.Reply("go");
932
933   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
934   event_router()->GattDescriptorRemoved(mock_adapter_, desc1_.get());
935   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
936   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
937   event_router()->GattServiceRemoved(
938       mock_adapter_, device0_.get(), service0_.get());
939 }
940
941 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) {
942   ResultCatcher catcher;
943   catcher.RestrictToBrowserContext(browser()->profile());
944
945   event_router()->GattServiceAdded(
946       mock_adapter_, device0_.get(), service0_.get());
947   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
948   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
949
950   EXPECT_CALL(*mock_adapter_, GetDevice(_))
951       .Times(3)
952       .WillRepeatedly(Return(device0_.get()));
953
954   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
955       .Times(3)
956       .WillRepeatedly(Return(service0_.get()));
957
958   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
959       .Times(3)
960       .WillRepeatedly(Return(chrc0_.get()));
961
962   EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
963       .Times(3)
964       .WillRepeatedly(Return(desc0_.get()));
965
966   std::vector<uint8> value;
967   EXPECT_CALL(*desc0_, ReadRemoteDescriptor(_, _))
968       .Times(2)
969       .WillOnce(InvokeCallbackArgument<1>())
970       .WillOnce(InvokeCallbackArgument<0>(value));
971
972   ExtensionTestMessageListener listener("ready", true);
973   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
974       "bluetooth_low_energy/read_descriptor_value")));
975   EXPECT_TRUE(listener.WaitUntilSatisfied());
976
977   listener.Reply("go");
978
979   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
980
981   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
982   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
983   event_router()->GattServiceRemoved(
984       mock_adapter_, device0_.get(), service0_.get());
985 }
986
987 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteDescriptorValue) {
988   ResultCatcher catcher;
989   catcher.RestrictToBrowserContext(browser()->profile());
990
991   event_router()->GattServiceAdded(
992       mock_adapter_, device0_.get(), service0_.get());
993   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
994   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
995
996   EXPECT_CALL(*mock_adapter_, GetDevice(_))
997       .Times(3)
998       .WillRepeatedly(Return(device0_.get()));
999
1000   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
1001       .Times(3)
1002       .WillRepeatedly(Return(service0_.get()));
1003
1004   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
1005       .Times(3)
1006       .WillRepeatedly(Return(chrc0_.get()));
1007
1008   EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
1009       .Times(3)
1010       .WillRepeatedly(Return(desc0_.get()));
1011
1012   std::vector<uint8> write_value;
1013   EXPECT_CALL(*desc0_, WriteRemoteDescriptor(_, _, _))
1014       .Times(2)
1015       .WillOnce(InvokeCallbackArgument<2>())
1016       .WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>()));
1017
1018   EXPECT_CALL(*desc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value));
1019
1020   ExtensionTestMessageListener listener("ready", true);
1021   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1022       "bluetooth_low_energy/write_descriptor_value")));
1023   EXPECT_TRUE(listener.WaitUntilSatisfied());
1024
1025   listener.Reply("go");
1026
1027   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1028
1029   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
1030   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
1031   event_router()->GattServiceRemoved(
1032       mock_adapter_, device0_.get(), service0_.get());
1033 }
1034
1035 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, PermissionDenied) {
1036   ResultCatcher catcher;
1037   catcher.RestrictToBrowserContext(browser()->profile());
1038
1039   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1040       "bluetooth_low_energy/permission_denied")));
1041   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1042 }
1043
1044 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionMethods) {
1045   ResultCatcher catcher;
1046   catcher.RestrictToBrowserContext(browser()->profile());
1047
1048   event_router()->GattServiceAdded(
1049       mock_adapter_, device0_.get(), service0_.get());
1050   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
1051   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
1052
1053   std::vector<BluetoothGattService*> services;
1054   services.push_back(service0_.get());
1055
1056   EXPECT_CALL(*mock_adapter_, GetDevice(_))
1057       .WillRepeatedly(Return(device0_.get()));
1058   EXPECT_CALL(*device0_, GetGattServices()).WillOnce(Return(services));
1059   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
1060       .WillRepeatedly(Return(service0_.get()));
1061   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
1062       .WillRepeatedly(Return(chrc0_.get()));
1063   EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
1064       .WillRepeatedly(Return(desc0_.get()));
1065
1066   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1067       "bluetooth_low_energy/uuid_permission_methods")));
1068   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1069
1070   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
1071   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
1072   event_router()->GattServiceRemoved(
1073       mock_adapter_, device0_.get(), service0_.get());
1074 }
1075
1076 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionEvents) {
1077   ResultCatcher catcher;
1078   catcher.RestrictToBrowserContext(browser()->profile());
1079
1080   ExtensionTestMessageListener listener("ready", true);
1081   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1082       "bluetooth_low_energy/uuid_permission_events")));
1083
1084   // Cause events to be sent to the extension.
1085   event_router()->GattServiceAdded(
1086       mock_adapter_, device0_.get(), service0_.get());
1087   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
1088   event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
1089
1090   std::vector<uint8> value;
1091   event_router()->GattCharacteristicValueChanged(
1092       mock_adapter_, chrc0_.get(), value);
1093   event_router()->GattDescriptorValueChanged(
1094       mock_adapter_, desc0_.get(), value);
1095   event_router()->GattServiceChanged(mock_adapter_, service0_.get());
1096
1097   EXPECT_TRUE(listener.WaitUntilSatisfied());
1098   listener.Reply("go");
1099   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1100
1101   event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
1102   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
1103   event_router()->GattServiceRemoved(
1104       mock_adapter_, device0_.get(), service0_.get());
1105 }
1106
1107 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GattConnection) {
1108   ResultCatcher catcher;
1109   catcher.RestrictToBrowserContext(browser()->profile());
1110
1111   EXPECT_CALL(*mock_adapter_, GetDevice(_))
1112       .WillRepeatedly(Return(static_cast<BluetoothDevice*>(NULL)));
1113   EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
1114       .WillRepeatedly(Return(device0_.get()));
1115   EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress1))
1116       .WillRepeatedly(Return(device1_.get()));
1117   EXPECT_CALL(*device0_, CreateGattConnection(_, _))
1118       .Times(3)
1119       .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_FAILED))
1120       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1121           CreateGattConnection(kTestLeDeviceAddress0,
1122                                true /* expect_disconnect */)))
1123       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1124           CreateGattConnection(kTestLeDeviceAddress0,
1125                                false /* expect_disconnect */)));
1126   EXPECT_CALL(*device1_, CreateGattConnection(_, _))
1127       .Times(1)
1128       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1129           CreateGattConnection(kTestLeDeviceAddress1,
1130                                true /* expect_disconnect */)));
1131
1132   ASSERT_TRUE(LoadExtension(
1133       test_data_dir_.AppendASCII("bluetooth_low_energy/gatt_connection")));
1134   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1135 }
1136
1137 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReconnectAfterDisconnected) {
1138   ResultCatcher catcher;
1139   catcher.RestrictToBrowserContext(browser()->profile());
1140
1141   EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
1142       .WillRepeatedly(Return(device0_.get()));
1143
1144   MockBluetoothGattConnection* first_conn =
1145       static_cast<MockBluetoothGattConnection*>(CreateGattConnection(
1146           kTestLeDeviceAddress0, false /* expect_disconnect */));
1147   EXPECT_CALL(*first_conn, IsConnected())
1148       .Times(2)
1149       .WillOnce(Return(true))
1150       .WillOnce(Return(false));
1151
1152   EXPECT_CALL(*device0_, CreateGattConnection(_, _))
1153       .Times(2)
1154       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1155           first_conn))
1156       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
1157           CreateGattConnection(kTestLeDeviceAddress0,
1158                                false /* expect_disconnect */)));
1159
1160   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1161       "bluetooth_low_energy/reconnect_after_disconnected")));
1162   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1163 }
1164
1165 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ConnectInProgress) {
1166   ResultCatcher catcher;
1167   catcher.RestrictToBrowserContext(browser()->profile());
1168
1169   EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
1170       .WillRepeatedly(Return(device0_.get()));
1171
1172   BluetoothDevice::GattConnectionCallback connect_callback;
1173   base::Closure disconnect_callback;
1174
1175   testing::NiceMock<MockBluetoothGattConnection>* conn =
1176       new testing::NiceMock<MockBluetoothGattConnection>(
1177           kTestLeDeviceAddress0);
1178   scoped_ptr<BluetoothGattConnection> conn_ptr(conn);
1179   EXPECT_CALL(*conn, Disconnect(_))
1180       .Times(1)
1181       .WillOnce(SaveArg<0>(&disconnect_callback));
1182
1183   EXPECT_CALL(*device0_, CreateGattConnection(_, _))
1184       .Times(1)
1185       .WillOnce(SaveArg<0>(&connect_callback));
1186
1187   ExtensionTestMessageListener listener("ready", true);
1188   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1189       "bluetooth_low_energy/connect_in_progress")));
1190
1191   listener.WaitUntilSatisfied();
1192   connect_callback.Run(conn_ptr.Pass());
1193
1194   listener.Reset();
1195   listener.WaitUntilSatisfied();
1196   disconnect_callback.Run();
1197
1198   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1199 }
1200
1201 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, StartStopNotifications) {
1202   ResultCatcher catcher;
1203   catcher.RestrictToBrowserContext(browser()->profile());
1204
1205   event_router()->GattServiceAdded(
1206       mock_adapter_, device0_.get(), service0_.get());
1207   event_router()->GattServiceAdded(
1208       mock_adapter_, device0_.get(), service1_.get());
1209   event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
1210   event_router()->GattCharacteristicAdded(mock_adapter_, chrc1_.get());
1211   event_router()->GattCharacteristicAdded(mock_adapter_, chrc2_.get());
1212
1213   EXPECT_CALL(*mock_adapter_, GetDevice(_))
1214       .WillRepeatedly(Return(device0_.get()));
1215   EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
1216       .WillRepeatedly(Return(service0_.get()));
1217   EXPECT_CALL(*device0_, GetGattService(kTestServiceId1))
1218       .WillRepeatedly(Return(service1_.get()));
1219   EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2))
1220       .Times(1)
1221       .WillOnce(Return(chrc2_.get()));
1222   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
1223       .Times(2)
1224       .WillRepeatedly(Return(chrc0_.get()));
1225   EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId1))
1226       .Times(1)
1227       .WillOnce(Return(chrc1_.get()));
1228
1229   BluetoothGattNotifySession* session0 =
1230       new testing::NiceMock<MockBluetoothGattNotifySession>(
1231           kTestCharacteristicId0);
1232   MockBluetoothGattNotifySession* session1 =
1233       new testing::NiceMock<MockBluetoothGattNotifySession>(
1234           kTestCharacteristicId1);
1235
1236   EXPECT_CALL(*session1, Stop(_))
1237       .Times(1)
1238       .WillOnce(InvokeCallbackArgument<0>());
1239
1240   EXPECT_CALL(*chrc0_, StartNotifySession(_, _))
1241       .Times(2)
1242       .WillOnce(InvokeCallbackArgument<1>())
1243       .WillOnce(
1244           InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
1245               session0));
1246   EXPECT_CALL(*chrc1_, StartNotifySession(_, _))
1247       .Times(1)
1248       .WillOnce(
1249           InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
1250               session1));
1251
1252   ExtensionTestMessageListener listener("ready", true);
1253   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
1254       "bluetooth_low_energy/start_stop_notifications")));
1255
1256   EXPECT_TRUE(listener.WaitUntilSatisfied());
1257
1258   std::vector<uint8> value;
1259   event_router()->GattCharacteristicValueChanged(
1260       mock_adapter_, chrc0_.get(), value);
1261   event_router()->GattCharacteristicValueChanged(
1262       mock_adapter_, chrc1_.get(), value);
1263   event_router()->GattCharacteristicValueChanged(
1264       mock_adapter_, chrc2_.get(), value);
1265
1266   listener.Reply("go");
1267
1268   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1269   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc2_.get());
1270   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc1_.get());
1271   event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
1272   event_router()->GattServiceRemoved(
1273       mock_adapter_, device0_.get(), service1_.get());
1274   event_router()->GattServiceRemoved(
1275       mock_adapter_, device0_.get(), service0_.get());
1276 }
1277
1278 }  // namespace