blob: 18a82134999cf340e42074395be474a2e0fb9541 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_descriptor.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
#include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h"
#include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h"
#include "extensions/common/test_util.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "testing/gmock/include/gmock/gmock.h"
using device::BluetoothUUID;
using device::BluetoothAdapter;
using device::BluetoothDevice;
using device::BluetoothGattCharacteristic;
using device::BluetoothGattConnection;
using device::BluetoothGattDescriptor;
using device::BluetoothGattService;
using device::BluetoothGattNotifySession;
using device::MockBluetoothAdapter;
using device::MockBluetoothDevice;
using device::MockBluetoothGattCharacteristic;
using device::MockBluetoothGattConnection;
using device::MockBluetoothGattDescriptor;
using device::MockBluetoothGattService;
using device::MockBluetoothGattNotifySession;
using extensions::BluetoothLowEnergyEventRouter;
using extensions::ResultCatcher;
using testing::Invoke;
using testing::Return;
using testing::ReturnRef;
using testing::ReturnRefOfCopy;
using testing::SaveArg;
using testing::_;
namespace {
// Test service constants.
const char kTestLeDeviceAddress0[] = "11:22:33:44:55:66";
const char kTestLeDeviceName0[] = "Test LE Device 0";
const char kTestLeDeviceAddress1[] = "77:88:99:AA:BB:CC";
const char kTestLeDeviceName1[] = "Test LE Device 1";
const char kTestServiceId0[] = "service_id0";
const char kTestServiceUuid0[] = "1234";
const char kTestServiceId1[] = "service_id1";
const char kTestServiceUuid1[] = "5678";
// Test characteristic constants.
const char kTestCharacteristicId0[] = "char_id0";
const char kTestCharacteristicUuid0[] = "1211";
const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties0 =
BluetoothGattCharacteristic::kPropertyBroadcast |
BluetoothGattCharacteristic::kPropertyRead |
BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
BluetoothGattCharacteristic::kPropertyIndicate;
const uint8 kTestCharacteristicDefaultValue0[] = {0x01, 0x02, 0x03, 0x04, 0x05};
const char kTestCharacteristicId1[] = "char_id1";
const char kTestCharacteristicUuid1[] = "1212";
const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties1 =
BluetoothGattCharacteristic::kPropertyRead |
BluetoothGattCharacteristic::kPropertyWrite |
BluetoothGattCharacteristic::kPropertyNotify;
const uint8 kTestCharacteristicDefaultValue1[] = {0x06, 0x07, 0x08};
const char kTestCharacteristicId2[] = "char_id2";
const char kTestCharacteristicUuid2[] = "1213";
const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties2 =
BluetoothGattCharacteristic::kPropertyNone;
// Test descriptor constants.
const char kTestDescriptorId0[] = "desc_id0";
const char kTestDescriptorUuid0[] = "1221";
const uint8 kTestDescriptorDefaultValue0[] = {0x01, 0x02, 0x03};
const char kTestDescriptorId1[] = "desc_id1";
const char kTestDescriptorUuid1[] = "1222";
const uint8 kTestDescriptorDefaultValue1[] = {0x04, 0x05};
class BluetoothLowEnergyApiTest : public ExtensionApiTest {
public:
BluetoothLowEnergyApiTest() {}
virtual ~BluetoothLowEnergyApiTest() {}
virtual void SetUpOnMainThread() override {
ExtensionApiTest::SetUpOnMainThread();
empty_extension_ = extensions::test_util::CreateEmptyExtension();
SetUpMocks();
}
virtual void TearDownOnMainThread() override {
EXPECT_CALL(*mock_adapter_, RemoveObserver(_));
}
void SetUpMocks() {
mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>();
EXPECT_CALL(*mock_adapter_, GetDevices())
.WillOnce(Return(BluetoothAdapter::ConstDeviceList()));
event_router()->SetAdapterForTesting(mock_adapter_);
device0_.reset(
new testing::NiceMock<MockBluetoothDevice>(mock_adapter_,
0,
kTestLeDeviceName0,
kTestLeDeviceAddress0,
false /* paired */,
true /* connected */));
device1_.reset(
new testing::NiceMock<MockBluetoothDevice>(mock_adapter_,
0,
kTestLeDeviceName1,
kTestLeDeviceAddress1,
false /* paired */,
false /* connected */));
service0_.reset(new testing::NiceMock<MockBluetoothGattService>(
device0_.get(),
kTestServiceId0,
BluetoothUUID(kTestServiceUuid0),
true /* is_primary */,
false /* is_local */));
service1_.reset(new testing::NiceMock<MockBluetoothGattService>(
device0_.get(),
kTestServiceId1,
BluetoothUUID(kTestServiceUuid1),
false /* is_primary */,
false /* is_local */));
// Assign characteristics some random properties and permissions. They don't
// need to reflect what the characteristic is actually capable of, since
// the JS API just passes values through from
// device::BluetoothGattCharacteristic.
std::vector<uint8> default_value;
chrc0_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
service0_.get(),
kTestCharacteristicId0,
BluetoothUUID(kTestCharacteristicUuid0),
false /* is_local */,
kTestCharacteristicProperties0,
BluetoothGattCharacteristic::kPermissionNone));
default_value.assign(kTestCharacteristicDefaultValue0,
(kTestCharacteristicDefaultValue0 +
sizeof(kTestCharacteristicDefaultValue0)));
ON_CALL(*chrc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
chrc1_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
service0_.get(),
kTestCharacteristicId1,
BluetoothUUID(kTestCharacteristicUuid1),
false /* is_local */,
kTestCharacteristicProperties1,
BluetoothGattCharacteristic::kPermissionNone));
default_value.assign(kTestCharacteristicDefaultValue1,
(kTestCharacteristicDefaultValue1 +
sizeof(kTestCharacteristicDefaultValue1)));
ON_CALL(*chrc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
chrc2_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
service1_.get(),
kTestCharacteristicId2,
BluetoothUUID(kTestCharacteristicUuid2),
false /* is_local */,
kTestCharacteristicProperties2,
BluetoothGattCharacteristic::kPermissionNone));
desc0_.reset(new testing::NiceMock<MockBluetoothGattDescriptor>(
chrc0_.get(),
kTestDescriptorId0,
BluetoothUUID(kTestDescriptorUuid0),
false /* is_local */,
BluetoothGattCharacteristic::kPermissionNone));
default_value.assign(
kTestDescriptorDefaultValue0,
(kTestDescriptorDefaultValue0 + sizeof(kTestDescriptorDefaultValue0)));
ON_CALL(*desc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
desc1_.reset(new testing::NiceMock<MockBluetoothGattDescriptor>(
chrc0_.get(),
kTestDescriptorId1,
BluetoothUUID(kTestDescriptorUuid1),
false /* is_local */,
BluetoothGattCharacteristic::kPermissionNone));
default_value.assign(
kTestDescriptorDefaultValue1,
(kTestDescriptorDefaultValue1 + sizeof(kTestDescriptorDefaultValue1)));
ON_CALL(*desc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
}
protected:
BluetoothLowEnergyEventRouter* event_router() {
return extensions::BluetoothLowEnergyAPI::Get(browser()->profile())
->event_router();
}
testing::StrictMock<MockBluetoothAdapter>* mock_adapter_;
scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device0_;
scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_;
scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service0_;
scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service1_;
scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc0_;
scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc1_;
scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc2_;
scoped_ptr<testing::NiceMock<MockBluetoothGattDescriptor> > desc0_;
scoped_ptr<testing::NiceMock<MockBluetoothGattDescriptor> > desc1_;
private:
scoped_refptr<extensions::Extension> empty_extension_;
};
ACTION_TEMPLATE(InvokeCallbackArgument,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
::std::tr1::get<k>(args).Run();
}
ACTION_TEMPLATE(InvokeCallbackArgument,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(p0)) {
::std::tr1::get<k>(args).Run(p0);
}
ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg,
HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
AND_1_VALUE_PARAMS(p0)) {
::std::tr1::get<k>(args).Run(scoped_ptr<T>(p0));
}
BluetoothGattConnection* CreateGattConnection(
const std::string& device_address,
bool expect_disconnect) {
testing::NiceMock<MockBluetoothGattConnection>* conn =
new testing::NiceMock<MockBluetoothGattConnection>(device_address);
if (expect_disconnect) {
EXPECT_CALL(*conn, Disconnect(_))
.Times(1)
.WillOnce(InvokeCallbackArgument<0>());
} else {
EXPECT_CALL(*conn, Disconnect(_)).Times(0);
}
return conn;
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetServices) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
std::vector<BluetoothGattService*> services;
services.push_back(service0_.get());
services.push_back(service1_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattServices())
.Times(2)
.WillOnce(Return(std::vector<BluetoothGattService*>()))
.WillOnce(Return(services));
// Load and wait for setup.
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_services")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetService) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(2)
.WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
.WillOnce(Return(service0_.get()));
// Load and wait for setup.
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_service")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ServiceEvents) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
// Load the extension and let it set up.
ExtensionTestMessageListener listener(true);
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/service_events")));
// These will create the identifier mappings.
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service1_.get());
// These will send the onServiceAdded event to apps.
event_router()->GattDiscoveryCompleteForService(mock_adapter_,
service0_.get());
event_router()->GattDiscoveryCompleteForService(mock_adapter_,
service1_.get());
// This will send the onServiceChanged event to apps.
event_router()->GattServiceChanged(mock_adapter_, service1_.get());
// This will send the onServiceRemoved event to apps.
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service1_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedService) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
// Load the extension and let it set up.
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_removed_service")));
// 1. getService success.
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(1)
.WillOnce(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(1)
.WillOnce(Return(service0_.get()));
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattDiscoveryCompleteForService(mock_adapter_,
service0_.get());
ExtensionTestMessageListener get_service_success_listener(true);
EXPECT_TRUE(get_service_success_listener.WaitUntilSatisfied());
ASSERT_EQ("getServiceSuccess", get_service_success_listener.message())
<< get_service_success_listener.message();
testing::Mock::VerifyAndClearExpectations(mock_adapter_);
testing::Mock::VerifyAndClearExpectations(device0_.get());
// 2. getService fail.
EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)).Times(0);
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
ExtensionTestMessageListener get_service_fail_listener(true);
EXPECT_TRUE(get_service_fail_listener.WaitUntilSatisfied());
ASSERT_EQ("getServiceFail", get_service_fail_listener.message())
<< get_service_fail_listener.message();
testing::Mock::VerifyAndClearExpectations(mock_adapter_);
testing::Mock::VerifyAndClearExpectations(device0_.get());
get_service_fail_listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetIncludedServices) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/get_included_services")));
// Wait for initial call to end with failure as there is no mapping.
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
EXPECT_TRUE(listener.WaitUntilSatisfied());
// Set up for the rest of the calls before replying. Included services can be
// returned even if there is no instance ID mapping for them yet, so no need
// to call GattServiceAdded for |service1_| here.
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
std::vector<BluetoothGattService*> includes;
includes.push_back(service1_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
.Times(2)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(2)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetIncludedServices())
.Times(2)
.WillOnce(Return(std::vector<BluetoothGattService*>()))
.WillOnce(Return(includes));
listener.Reply("go");
listener.Reset();
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristics) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
std::vector<BluetoothGattCharacteristic*> characteristics;
characteristics.push_back(chrc0_.get());
characteristics.push_back(chrc1_.get());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(3).WillRepeatedly(
Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristics())
.Times(2)
.WillOnce(Return(std::vector<BluetoothGattCharacteristic*>()))
.WillOnce(Return(characteristics));
ExtensionTestMessageListener listener("ready", true);
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristics")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristic) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(4)
.WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(2)
.WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
.WillOnce(Return(chrc0_.get()));
// Load the extension and wait for first test.
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristic")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicProperties) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(12)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(12)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(12)
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetProperties())
.Times(12)
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyNone))
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyBroadcast))
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyRead))
.WillOnce(
Return(BluetoothGattCharacteristic::kPropertyWriteWithoutResponse))
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyWrite))
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyNotify))
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyIndicate))
.WillOnce(Return(
BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites))
.WillOnce(
Return(BluetoothGattCharacteristic::kPropertyExtendedProperties))
.WillOnce(Return(BluetoothGattCharacteristic::kPropertyReliableWrite))
.WillOnce(
Return(BluetoothGattCharacteristic::kPropertyWritableAuxiliaries))
.WillOnce(Return(
BluetoothGattCharacteristic::kPropertyBroadcast |
BluetoothGattCharacteristic::kPropertyRead |
BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
BluetoothGattCharacteristic::kPropertyWrite |
BluetoothGattCharacteristic::kPropertyNotify |
BluetoothGattCharacteristic::kPropertyIndicate |
BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites |
BluetoothGattCharacteristic::kPropertyExtendedProperties |
BluetoothGattCharacteristic::kPropertyReliableWrite |
BluetoothGattCharacteristic::kPropertyWritableAuxiliaries));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/characteristic_properties")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedCharacteristic) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(1)
.WillOnce(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(1)
.WillOnce(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(1)
.WillOnce(Return(chrc0_.get()));
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/get_removed_characteristic")));
ExtensionTestMessageListener listener(true);
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
testing::Mock::VerifyAndClearExpectations(mock_adapter_);
testing::Mock::VerifyAndClearExpectations(device0_.get());
testing::Mock::VerifyAndClearExpectations(service0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
EXPECT_CALL(*device0_, GetGattService(_)).Times(0);
EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0);
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
listener.Reply("go");
listener.Reset();
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
// Cause events to be sent to the extension.
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service1_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc2_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(2)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(1)
.WillOnce(Return(service0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId1))
.Times(1)
.WillOnce(Return(service1_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(1)
.WillOnce(Return(chrc0_.get()));
EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2))
.Times(1)
.WillOnce(Return(chrc2_.get()));
BluetoothGattNotifySession* session0 =
new testing::NiceMock<MockBluetoothGattNotifySession>(
kTestCharacteristicId0);
BluetoothGattNotifySession* session1 =
new testing::NiceMock<MockBluetoothGattNotifySession>(
kTestCharacteristicId2);
EXPECT_CALL(*chrc0_, StartNotifySession(_, _))
.Times(1)
.WillOnce(
InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
session0));
EXPECT_CALL(*chrc2_, StartNotifySession(_, _))
.Times(1)
.WillOnce(
InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
session1));
ExtensionTestMessageListener listener("ready", true);
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/characteristic_value_changed")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
std::vector<uint8> value;
event_router()->GattCharacteristicValueChanged(
mock_adapter_, chrc0_.get(), value);
event_router()->GattCharacteristicValueChanged(
mock_adapter_, chrc2_.get(), value);
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc2_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service1_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadCharacteristicValue) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(3)
.WillRepeatedly(Return(chrc0_.get()));
std::vector<uint8> value;
EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic(_, _))
.Times(2)
.WillOnce(InvokeCallbackArgument<1>(
BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED))
.WillOnce(InvokeCallbackArgument<0>(value));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/read_characteristic_value")));
listener.WaitUntilSatisfied();
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteCharacteristicValue) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(3)
.WillRepeatedly(Return(chrc0_.get()));
std::vector<uint8> write_value;
EXPECT_CALL(*chrc0_, WriteRemoteCharacteristic(_, _, _))
.Times(2)
.WillOnce(InvokeCallbackArgument<2>(
BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED))
.WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>()));
EXPECT_CALL(*chrc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/write_characteristic_value")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptors) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
std::vector<BluetoothGattDescriptor*> descriptors;
descriptors.push_back(desc0_.get());
descriptors.push_back(desc1_.get());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(3)
.WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetDescriptors())
.Times(2)
.WillOnce(Return(std::vector<BluetoothGattDescriptor*>()))
.WillOnce(Return(descriptors));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptors")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptor) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(5)
.WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(4)
.WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(3)
.WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
.Times(2)
.WillOnce(Return(static_cast<BluetoothGattDescriptor*>(NULL)))
.WillOnce(Return(desc0_.get()));
// Load the extension and wait for first test.
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptor")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedDescriptor) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(1)
.WillOnce(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(1)
.WillOnce(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(1)
.WillOnce(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
.Times(1)
.WillOnce(Return(desc0_.get()));
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/get_removed_descriptor")));
ExtensionTestMessageListener listener(true);
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
testing::Mock::VerifyAndClearExpectations(mock_adapter_);
testing::Mock::VerifyAndClearExpectations(device0_.get());
testing::Mock::VerifyAndClearExpectations(service0_.get());
testing::Mock::VerifyAndClearExpectations(chrc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0);
EXPECT_CALL(*device0_, GetGattService(_)).Times(0);
EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0);
EXPECT_CALL(*chrc0_, GetDescriptor(_)).Times(0);
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
listener.Reply("go");
listener.Reset();
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, DescriptorValueChanged) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc1_.get());
// Load the extension and let it set up.
ExtensionTestMessageListener listener("ready", true);
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/descriptor_value_changed")));
// Cause events to be sent to the extension.
std::vector<uint8> value;
event_router()->GattDescriptorValueChanged(
mock_adapter_, desc0_.get(), value);
event_router()->GattDescriptorValueChanged(
mock_adapter_, desc1_.get(), value);
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattDescriptorRemoved(mock_adapter_, desc1_.get());
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(3)
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
.Times(3)
.WillRepeatedly(Return(desc0_.get()));
std::vector<uint8> value;
EXPECT_CALL(*desc0_, ReadRemoteDescriptor(_, _))
.Times(2)
.WillOnce(InvokeCallbackArgument<1>(
BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED))
.WillOnce(InvokeCallbackArgument<0>(value));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/read_descriptor_value")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteDescriptorValue) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.Times(3)
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.Times(3)
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(3)
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
.Times(3)
.WillRepeatedly(Return(desc0_.get()));
std::vector<uint8> write_value;
EXPECT_CALL(*desc0_, WriteRemoteDescriptor(_, _, _))
.Times(2)
.WillOnce(InvokeCallbackArgument<2>(
BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED))
.WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>()));
EXPECT_CALL(*desc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/write_descriptor_value")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, PermissionDenied) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/permission_denied")));
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionMethods) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
std::vector<BluetoothGattService*> services;
services.push_back(service0_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattServices()).WillOnce(Return(services));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0))
.WillRepeatedly(Return(desc0_.get()));
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/uuid_permission_methods")));
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionEvents) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
ExtensionTestMessageListener listener(true);
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/uuid_permission_events")));
// Cause events to be sent to the extension.
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattDescriptorAdded(mock_adapter_, desc0_.get());
std::vector<uint8> value;
event_router()->GattCharacteristicValueChanged(
mock_adapter_, chrc0_.get(), value);
event_router()->GattDescriptorValueChanged(
mock_adapter_, desc0_.get(), value);
event_router()->GattServiceChanged(mock_adapter_, service0_.get());
EXPECT_TRUE(listener.WaitUntilSatisfied());
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
ASSERT_EQ("ready", listener.message()) << listener.message();
event_router()->GattDescriptorRemoved(mock_adapter_, desc0_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GattConnection) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.WillRepeatedly(Return(static_cast<BluetoothDevice*>(NULL)));
EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress1))
.WillRepeatedly(Return(device1_.get()));
EXPECT_CALL(*device0_, CreateGattConnection(_, _))
.Times(3)
.WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_FAILED))
.WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
CreateGattConnection(kTestLeDeviceAddress0,
true /* expect_disconnect */)))
.WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
CreateGattConnection(kTestLeDeviceAddress0,
false /* expect_disconnect */)));
EXPECT_CALL(*device1_, CreateGattConnection(_, _))
.Times(1)
.WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
CreateGattConnection(kTestLeDeviceAddress1,
true /* expect_disconnect */)));
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("bluetooth_low_energy/gatt_connection")));
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReconnectAfterDisconnected) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
.WillRepeatedly(Return(device0_.get()));
MockBluetoothGattConnection* first_conn =
static_cast<MockBluetoothGattConnection*>(CreateGattConnection(
kTestLeDeviceAddress0, false /* expect_disconnect */));
EXPECT_CALL(*first_conn, IsConnected())
.Times(2)
.WillOnce(Return(true))
.WillOnce(Return(false));
EXPECT_CALL(*device0_, CreateGattConnection(_, _))
.Times(2)
.WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
first_conn))
.WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
CreateGattConnection(kTestLeDeviceAddress0,
false /* expect_disconnect */)));
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/reconnect_after_disconnected")));
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ConnectInProgress) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0))
.WillRepeatedly(Return(device0_.get()));
BluetoothDevice::GattConnectionCallback connect_callback;
base::Closure disconnect_callback;
testing::NiceMock<MockBluetoothGattConnection>* conn =
new testing::NiceMock<MockBluetoothGattConnection>(
kTestLeDeviceAddress0);
scoped_ptr<BluetoothGattConnection> conn_ptr(conn);
EXPECT_CALL(*conn, Disconnect(_))
.Times(1)
.WillOnce(SaveArg<0>(&disconnect_callback));
EXPECT_CALL(*device0_, CreateGattConnection(_, _))
.Times(1)
.WillOnce(SaveArg<0>(&connect_callback));
ExtensionTestMessageListener listener(true);
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/connect_in_progress")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
connect_callback.Run(conn_ptr.Pass());
listener.Reset();
EXPECT_TRUE(listener.WaitUntilSatisfied());
ASSERT_EQ("ready", listener.message()) << listener.message();
disconnect_callback.Run();
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, StartStopNotifications) {
ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service0_.get());
event_router()->GattServiceAdded(
mock_adapter_, device0_.get(), service1_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc0_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc1_.get());
event_router()->GattCharacteristicAdded(mock_adapter_, chrc2_.get());
EXPECT_CALL(*mock_adapter_, GetDevice(_))
.WillRepeatedly(Return(device0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId0))
.WillRepeatedly(Return(service0_.get()));
EXPECT_CALL(*device0_, GetGattService(kTestServiceId1))
.WillRepeatedly(Return(service1_.get()));
EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2))
.Times(1)
.WillOnce(Return(chrc2_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
.Times(2)
.WillRepeatedly(Return(chrc0_.get()));
EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId1))
.Times(1)
.WillOnce(Return(chrc1_.get()));
BluetoothGattNotifySession* session0 =
new testing::NiceMock<MockBluetoothGattNotifySession>(
kTestCharacteristicId0);
MockBluetoothGattNotifySession* session1 =
new testing::NiceMock<MockBluetoothGattNotifySession>(
kTestCharacteristicId1);
EXPECT_CALL(*session1, Stop(_))
.Times(1)
.WillOnce(InvokeCallbackArgument<0>());
EXPECT_CALL(*chrc0_, StartNotifySession(_, _))
.Times(2)
.WillOnce(InvokeCallbackArgument<1>(
BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED))
.WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
session0));
EXPECT_CALL(*chrc1_, StartNotifySession(_, _))
.Times(1)
.WillOnce(
InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>(
session1));
ExtensionTestMessageListener listener("ready", true);
listener.set_failure_message("fail");
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"bluetooth_low_energy/start_stop_notifications")));
EXPECT_TRUE(listener.WaitUntilSatisfied());
std::vector<uint8> value;
event_router()->GattCharacteristicValueChanged(
mock_adapter_, chrc0_.get(), value);
event_router()->GattCharacteristicValueChanged(
mock_adapter_, chrc1_.get(), value);
event_router()->GattCharacteristicValueChanged(
mock_adapter_, chrc2_.get(), value);
listener.Reply("go");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc2_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc1_.get());
event_router()->GattCharacteristicRemoved(mock_adapter_, chrc0_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service1_.get());
event_router()->GattServiceRemoved(
mock_adapter_, device0_.get(), service0_.get());
}
} // namespace