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