summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorjlebel <jlebel@chromium.org>2016-03-14 03:33:28 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-14 10:35:25 +0000
commita58fd7578542a34fe30bf56ae52b884ad71c9061 (patch)
tree5709a920ca4a36a25c2c6ccffa58aafc80e8f5c8 /device
parenta70190e18d697d66bfd0ef4e9a2e4e578668e335 (diff)
downloadchromium_src-a58fd7578542a34fe30bf56ae52b884ad71c9061.zip
chromium_src-a58fd7578542a34fe30bf56ae52b884ad71c9061.tar.gz
chromium_src-a58fd7578542a34fe30bf56ae52b884ad71c9061.tar.bz2
Implementing GATT connection/disconnect on OS X.
BUG=520774 Review URL: https://codereview.chromium.org/1538173003 Cr-Commit-Position: refs/heads/master@{#380951}
Diffstat (limited to 'device')
-rw-r--r--device/BUILD.gn4
-rw-r--r--device/bluetooth/BUILD.gn2
-rw-r--r--device/bluetooth/bluetooth.gyp2
-rw-r--r--device/bluetooth/bluetooth_adapter_mac.h24
-rw-r--r--device/bluetooth/bluetooth_adapter_mac.mm93
-rw-r--r--device/bluetooth/bluetooth_adapter_mac_unittest.mm8
-rw-r--r--device/bluetooth/bluetooth_device_unittest.cc92
-rw-r--r--device/bluetooth/bluetooth_low_energy_central_manager_delegate.mm31
-rw-r--r--device/bluetooth/bluetooth_low_energy_device_mac.h13
-rw-r--r--device/bluetooth/bluetooth_low_energy_device_mac.mm37
-rw-r--r--device/bluetooth/test/bluetooth_test_mac.h13
-rw-r--r--device/bluetooth/test/bluetooth_test_mac.mm111
-rw-r--r--device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h25
-rw-r--r--device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm42
-rw-r--r--device/bluetooth/test/mock_bluetooth_central_manager_mac.h9
-rw-r--r--device/bluetooth/test/mock_bluetooth_central_manager_mac.mm35
-rw-r--r--device/device_tests.gyp4
17 files changed, 465 insertions, 80 deletions
diff --git a/device/BUILD.gn b/device/BUILD.gn
index a65caaf..a8870d3 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -42,6 +42,10 @@ test("device_unittests") {
"bluetooth/test/bluetooth_test_mac.mm",
"bluetooth/test/bluetooth_test_win.cc",
"bluetooth/test/bluetooth_test_win.h",
+ "bluetooth/test/mock_bluetooth_cbperipheral_mac.h",
+ "bluetooth/test/mock_bluetooth_cbperipheral_mac.mm",
+ "bluetooth/test/mock_bluetooth_central_manager_mac.h",
+ "bluetooth/test/mock_bluetooth_central_manager_mac.mm",
"bluetooth/test/test_bluetooth_adapter_observer.cc",
"bluetooth/test/test_bluetooth_adapter_observer.h",
"nfc/nfc_chromeos_unittest.cc",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index b3394b9..299d3ac 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -286,8 +286,6 @@ static_library("mocks") {
"test/mock_bluetooth_adapter.h",
"test/mock_bluetooth_advertisement.cc",
"test/mock_bluetooth_advertisement.h",
- "test/mock_bluetooth_central_manager_mac.h",
- "test/mock_bluetooth_central_manager_mac.mm",
"test/mock_bluetooth_device.cc",
"test/mock_bluetooth_device.h",
"test/mock_bluetooth_discovery_session.cc",
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index d46a243..26c90d3 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -354,8 +354,6 @@
'test/mock_bluetooth_adapter.h',
'test/mock_bluetooth_advertisement.cc',
'test/mock_bluetooth_advertisement.h',
- 'test/mock_bluetooth_central_manager_mac.mm',
- 'test/mock_bluetooth_central_manager_mac.h',
'test/mock_bluetooth_device.cc',
'test/mock_bluetooth_device.h',
'test/mock_bluetooth_discovery_session.cc',
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h
index 472c2f9..7bd221d 100644
--- a/device/bluetooth/bluetooth_adapter_mac.h
+++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -97,10 +97,16 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterMac
// (crbug.com/506287).
static bool IsLowEnergyAvailable();
- // Resets |low_energy_central_manager_| to |central_manager| and sets
- // |low_energy_central_manager_delegate_| as the manager's delegate. Should
- // be called only when |IsLowEnergyAvailable()|.
- void SetCentralManagerForTesting(CBCentralManager* central_manager);
+ // Creates a GATT connection by calling CoreBluetooth APIs.
+ void CreateGattConnection(BluetoothLowEnergyDeviceMac* device_mac);
+
+ // Closes the GATT connection by calling CoreBluetooth APIs.
+ void DisconnectGatt(BluetoothLowEnergyDeviceMac* device_mac);
+
+ // Methods called from CBCentralManager delegate.
+ void DidConnectPeripheral(CBPeripheral* peripheral);
+ void DidFailToConnectPeripheral(CBPeripheral* peripheral, NSError* error);
+ void DidDisconnectPeripheral(CBPeripheral* peripheral, NSError* error);
protected:
// BluetoothAdapter override:
@@ -108,6 +114,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterMac
device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
private:
+ // Resets |low_energy_central_manager_| to |central_manager| and sets
+ // |low_energy_central_manager_delegate_| as the manager's delegate. Should
+ // be called only when |IsLowEnergyAvailable()|.
+ void SetCentralManagerForTesting(CBCentralManager* central_manager);
+ CBCentralManager* GetCentralManagerForTesting();
+
// The length of time that must elapse since the last Inquiry response (on
// Classic devices) or call to BluetoothLowEnergyDevice::Update() (on Low
// Energy) before a discovered device is considered to be no longer available.
@@ -162,6 +174,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterMac
// observers.
void AddPairedDevices();
+ // Returns the BLE device associated with the CoreBluetooth peripheral.
+ BluetoothLowEnergyDeviceMac* GetBluetoothLowEnergyDeviceMac(
+ CBPeripheral* peripheral);
+
std::string address_;
std::string name_;
bool classic_powered_;
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 76dad60..2c431a4 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -92,6 +92,14 @@ BluetoothAdapterMac::BluetoothAdapterMac()
}
BluetoothAdapterMac::~BluetoothAdapterMac() {
+ // When devices will be destroyed, they will need this current instance to
+ // disconnect the gatt connection. To make sure they don't use the mac
+ // adapter, they should be explicitly destroyed here.
+ devices_.clear();
+ // Set low_energy_central_manager_ to nil so no devices will try to use it
+ // while being destroyed after this method. |devices_| is owned by
+ // BluetoothAdapter.
+ low_energy_central_manager_.reset();
}
std::string BluetoothAdapterMac::GetAddress() const {
@@ -221,17 +229,21 @@ bool BluetoothAdapterMac::IsLowEnergyAvailable() {
return base::mac::IsOSYosemiteOrLater();
}
+void BluetoothAdapterMac::RemovePairingDelegateInternal(
+ BluetoothDevice::PairingDelegate* pairing_delegate) {}
+
void BluetoothAdapterMac::SetCentralManagerForTesting(
CBCentralManager* central_manager) {
CHECK(BluetoothAdapterMac::IsLowEnergyAvailable());
central_manager.delegate = low_energy_central_manager_delegate_;
- low_energy_central_manager_.reset(central_manager);
+ low_energy_central_manager_.reset(central_manager,
+ base::scoped_policy::RETAIN);
low_energy_discovery_manager_->SetCentralManager(
low_energy_central_manager_.get());
}
-void BluetoothAdapterMac::RemovePairingDelegateInternal(
- BluetoothDevice::PairingDelegate* pairing_delegate) {
+CBCentralManager* BluetoothAdapterMac::GetCentralManagerForTesting() {
+ return low_energy_central_manager_;
}
void BluetoothAdapterMac::AddDiscoverySession(
@@ -454,25 +466,23 @@ void BluetoothAdapterMac::LowEnergyDeviceUpdated(
CBPeripheral* peripheral,
NSDictionary* advertisement_data,
int rssi) {
- std::string device_address =
- BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
- // Try to find device from |devices_| with key |device_address|,
+ BluetoothLowEnergyDeviceMac* device_mac =
+ GetBluetoothLowEnergyDeviceMac(peripheral);
// if has no entry in the map, create new device and insert into |devices_|,
// otherwise update the existing device.
- DevicesMap::const_iterator iter = devices_.find(device_address);
- if (iter == devices_.end()) {
+ if (!device_mac) {
VLOG(1) << "LowEnergyDeviceUpdated new device";
// A new device has been found.
- BluetoothLowEnergyDeviceMac* device_mac = new BluetoothLowEnergyDeviceMac(
- this, peripheral, advertisement_data, rssi);
+ device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral,
+ advertisement_data, rssi);
+ std::string device_address =
+ BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
devices_.add(device_address, scoped_ptr<BluetoothDevice>(device_mac));
FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
DeviceAdded(this, device_mac));
return;
}
- BluetoothLowEnergyDeviceMac* device_mac =
- static_cast<BluetoothLowEnergyDeviceMac*>(iter->second);
std::string stored_device_id = device_mac->GetIdentifier();
std::string updated_device_id =
BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
@@ -535,4 +545,63 @@ void BluetoothAdapterMac::AddPairedDevices() {
}
}
+void BluetoothAdapterMac::CreateGattConnection(
+ BluetoothLowEnergyDeviceMac* device_mac) {
+ [low_energy_central_manager_ connectPeripheral:device_mac->peripheral_
+ options:nil];
+}
+
+void BluetoothAdapterMac::DisconnectGatt(
+ BluetoothLowEnergyDeviceMac* device_mac) {
+ [low_energy_central_manager_
+ cancelPeripheralConnection:device_mac->peripheral_];
+}
+
+void BluetoothAdapterMac::DidConnectPeripheral(CBPeripheral* peripheral) {
+ BluetoothLowEnergyDeviceMac* device_mac =
+ GetBluetoothLowEnergyDeviceMac(peripheral);
+ if (!device_mac) {
+ [low_energy_central_manager_ cancelPeripheralConnection:peripheral];
+ return;
+ }
+ device_mac->DidConnectGatt();
+}
+
+void BluetoothAdapterMac::DidFailToConnectPeripheral(CBPeripheral* peripheral,
+ NSError* error) {
+ BluetoothLowEnergyDeviceMac* device_mac =
+ GetBluetoothLowEnergyDeviceMac(peripheral);
+ if (!device_mac) {
+ [low_energy_central_manager_ cancelPeripheralConnection:peripheral];
+ return;
+ }
+ VLOG(1) << "Bluetooth error, domain: " << error.domain.UTF8String
+ << ", error code: " << error.code;
+ // TODO(http://crbug.com/585894): Need to convert the error.
+ device_mac->DidFailToConnectGatt(BluetoothClassicDeviceMac::ERROR_UNKNOWN);
+}
+
+void BluetoothAdapterMac::DidDisconnectPeripheral(CBPeripheral* peripheral,
+ NSError* error) {
+ BluetoothLowEnergyDeviceMac* device_mac =
+ GetBluetoothLowEnergyDeviceMac(peripheral);
+ if (!device_mac) {
+ [low_energy_central_manager_ cancelPeripheralConnection:peripheral];
+ return;
+ }
+ // TODO(http://crbug.com/585897): Need to pass the error.
+ device_mac->DidDisconnectPeripheral();
+}
+
+BluetoothLowEnergyDeviceMac*
+BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) {
+ std::string device_address =
+ BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
+ DevicesMap::const_iterator iter = devices_.find(device_address);
+ if (iter == devices_.end()) {
+ return nil;
+ }
+ return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second);
+}
+
} // namespace device
diff --git a/device/bluetooth/bluetooth_adapter_mac_unittest.mm b/device/bluetooth/bluetooth_adapter_mac_unittest.mm
index bc63499..f855e72 100644
--- a/device/bluetooth/bluetooth_adapter_mac_unittest.mm
+++ b/device/bluetooth/bluetooth_adapter_mac_unittest.mm
@@ -116,9 +116,11 @@ class BluetoothAdapterMacTest : public testing::Test {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return false;
}
- mock_central_manager_ = [[MockCentralManager alloc] init];
+ mock_central_manager_.reset([[MockCentralManager alloc] init]);
[mock_central_manager_ setState:desired_state];
- adapter_mac_->SetCentralManagerForTesting(mock_central_manager_);
+ CBCentralManager* centralManager =
+ (CBCentralManager*)mock_central_manager_.get();
+ adapter_mac_->SetCentralManagerForTesting(centralManager);
return true;
}
@@ -153,7 +155,7 @@ class BluetoothAdapterMacTest : public testing::Test {
BluetoothAdapterMac* adapter_mac_;
// Owned by |adapter_mac_|.
- id mock_central_manager_ = NULL;
+ base::scoped_nsobject<MockCentralManager> mock_central_manager_;
int callback_count_;
int error_callback_count_;
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc
index 6d956c0..13607f492 100644
--- a/device/bluetooth/bluetooth_device_unittest.cc
+++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -122,9 +122,13 @@ TEST_F(BluetoothTest, LowEnergyDeviceNoUUIDs) {
// also require build configuration to generate string resources into a .pak
// file.
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Basic CreateGattConnection test.
TEST_F(BluetoothTest, CreateGattConnection) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -137,12 +141,16 @@ TEST_F(BluetoothTest, CreateGattConnection) {
EXPECT_TRUE(device->IsGattConnected());
EXPECT_TRUE(gatt_connections_[0]->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Creates BluetoothGattConnection instances and tests that the interface
// functions even when some Disconnect and the BluetoothDevice is destroyed.
TEST_F(BluetoothTest, BluetoothGattConnection) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -198,12 +206,16 @@ TEST_F(BluetoothTest, BluetoothGattConnection) {
EXPECT_EQ(device_address, gatt_connections_[0]->GetDeviceAddress());
EXPECT_EQ(device_address, gatt_connections_[1]->GetDeviceAddress());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Calls CreateGattConnection then simulates multiple connections from platform.
TEST_F(BluetoothTest,
BluetoothGattConnection_ConnectWithMultipleOSConnections) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -224,11 +236,15 @@ TEST_F(BluetoothTest,
SimulateGattDisconnection(device);
EXPECT_FALSE(gatt_connections_[0]->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Calls CreateGattConnection after already connected.
TEST_F(BluetoothTest, BluetoothGattConnection_AlreadyConnected) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -246,12 +262,16 @@ TEST_F(BluetoothTest, BluetoothGattConnection_AlreadyConnected) {
EXPECT_EQ(0, gatt_connection_attempts_);
EXPECT_TRUE(gatt_connections_[1]->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Creates BluetoothGattConnection after one exists that has disconnected.
TEST_F(BluetoothTest,
BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -275,11 +295,15 @@ TEST_F(BluetoothTest,
"connection is created.";
EXPECT_TRUE(gatt_connections_[1]->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Deletes BluetoothGattConnection causing disconnection.
TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -296,11 +320,15 @@ TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
gatt_connections_.clear();
EXPECT_EQ(1, gatt_disconnection_attempts_);
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Starts process of disconnecting and then calls BluetoothGattConnection.
TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectInProgress) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -333,12 +361,16 @@ TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectInProgress) {
for (BluetoothGattConnection* connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Calls CreateGattConnection but receives notice that the device disconnected
// before it ever connects.
TEST_F(BluetoothTest, BluetoothGattConnection_SimulateDisconnect) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -352,11 +384,15 @@ TEST_F(BluetoothTest, BluetoothGattConnection_SimulateDisconnect) {
for (BluetoothGattConnection* connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Calls CreateGattConnection & DisconnectGatt, then simulates connection.
TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -376,12 +412,16 @@ TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
EXPECT_EQ(0, callback_count_);
EXPECT_EQ(0, error_callback_count_);
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Calls CreateGattConnection & DisconnectGatt, then simulates disconnection.
TEST_F(BluetoothTest,
BluetoothGattConnection_DisconnectGatt_SimulateDisconnect) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -397,12 +437,16 @@ TEST_F(BluetoothTest,
for (BluetoothGattConnection* connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_MACOSX)
#if defined(OS_ANDROID)
// Calls CreateGattConnection & DisconnectGatt, then checks that gatt services
// have been cleaned up.
TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectGatt_Cleanup) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -452,6 +496,10 @@ TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectGatt_Cleanup) {
// Calls CreateGattConnection, but simulate errors connecting. Also, verifies
// multiple errors should only invoke callbacks once.
TEST_F(BluetoothTest, BluetoothGattConnection_ErrorAfterConnection) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
@@ -533,6 +581,10 @@ TEST_F(BluetoothTest, GetGattServices_and_GetGattService) {
#if defined(OS_ANDROID)
TEST_F(BluetoothTest, GetGattServices_DiscoveryError) {
+ if (!PlatformSupportsLowEnergy()) {
+ LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
+ return;
+ }
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
diff --git a/device/bluetooth/bluetooth_low_energy_central_manager_delegate.mm b/device/bluetooth/bluetooth_low_energy_central_manager_delegate.mm
index 598e4b9..95e452c 100644
--- a/device/bluetooth/bluetooth_low_energy_central_manager_delegate.mm
+++ b/device/bluetooth/bluetooth_low_energy_central_manager_delegate.mm
@@ -33,6 +33,20 @@ class BluetoothLowEnergyCentralManagerBridge {
adapter_->LowEnergyCentralManagerUpdatedState();
}
+ virtual void DidConnectPeripheral(CBPeripheral* peripheral) {
+ adapter_->DidConnectPeripheral(peripheral);
+ }
+
+ virtual void DidFailToConnectPeripheral(CBPeripheral* peripheral,
+ NSError* error) {
+ adapter_->DidFailToConnectPeripheral(peripheral, error);
+ }
+
+ virtual void DidDisconnectPeripheral(CBPeripheral* peripheral,
+ NSError* error) {
+ adapter_->DidDisconnectPeripheral(peripheral, error);
+ }
+
private:
BluetoothLowEnergyDiscoveryManagerMac* discovery_manager_;
BluetoothAdapterMac* adapter_;
@@ -65,4 +79,21 @@ class BluetoothLowEnergyCentralManagerBridge {
bridge_->UpdatedState();
}
+- (void)centralManager:(CBCentralManager*)central
+ didConnectPeripheral:(CBPeripheral*)peripheral {
+ bridge_->DidConnectPeripheral(peripheral);
+}
+
+- (void)centralManager:(CBCentralManager*)central
+ didFailToConnectPeripheral:(CBPeripheral*)peripheral
+ error:(nullable NSError*)error {
+ bridge_->DidFailToConnectPeripheral(peripheral, error);
+}
+
+- (void)centralManager:(CBCentralManager*)central
+ didDisconnectPeripheral:(CBPeripheral*)peripheral
+ error:(nullable NSError*)error {
+ bridge_->DidDisconnectPeripheral(peripheral, error);
+}
+
@end
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.h b/device/bluetooth/bluetooth_low_energy_device_mac.h
index ad713a5..6f33c89 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.h
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.h
@@ -79,9 +79,6 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac
const device::BluetoothUUID& uuid,
const ConnectToServiceCallback& callback,
const ConnectToServiceErrorCallback& error_callback) override;
- void CreateGattConnection(
- const GattConnectionCallback& callback,
- const ConnectErrorCallback& error_callback) override;
// BluetoothDeviceMac override.
NSDate* GetLastUpdateTime() const override;
@@ -108,6 +105,16 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac
private:
friend class BluetoothAdapterMac;
friend class BluetoothAdapterMacTest;
+ friend class BluetoothTestMac;
+
+ // Returns the Bluetooth adapter.
+ BluetoothAdapterMac* GetMacAdapter();
+
+ // Returns the CoreBluetooth Peripheral.
+ CBPeripheral* GetPeripheral();
+
+ // Callback used when the CoreBluetooth Peripheral is disconnected.
+ void DidDisconnectPeripheral();
// CoreBluetooth data structure.
base::scoped_nsobject<CBPeripheral> peripheral_;
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm
index 00712ae..d0f3f3d 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.mm
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -43,6 +43,9 @@ BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac(
}
BluetoothLowEnergyDeviceMac::~BluetoothLowEnergyDeviceMac() {
+ if (IsGattConnected()) {
+ GetMacAdapter()->DisconnectGatt(this);
+ }
}
void BluetoothLowEnergyDeviceMac::Update(CBPeripheral* peripheral,
@@ -134,7 +137,7 @@ bool BluetoothLowEnergyDeviceMac::IsConnectable() const {
}
bool BluetoothLowEnergyDeviceMac::IsConnecting() const {
- return false;
+ return ([peripheral_ state] == CBPeripheralStateConnecting);
}
BluetoothDevice::UUIDList BluetoothLowEnergyDeviceMac::GetUUIDs() const {
@@ -220,12 +223,6 @@ void BluetoothLowEnergyDeviceMac::ConnectToServiceInsecurely(
NOTIMPLEMENTED();
}
-void BluetoothLowEnergyDeviceMac::CreateGattConnection(
- const GattConnectionCallback& callback,
- const ConnectErrorCallback& error_callback) {
- NOTIMPLEMENTED();
-}
-
NSDate* BluetoothLowEnergyDeviceMac::GetLastUpdateTime() const {
return last_update_time_.get();
}
@@ -235,15 +232,13 @@ std::string BluetoothLowEnergyDeviceMac::GetDeviceName() const {
}
void BluetoothLowEnergyDeviceMac::CreateGattConnectionImpl() {
- // Mac implementation does not yet use the default CreateGattConnection
- // implementation. http://crbug.com/520774
- NOTIMPLEMENTED();
+ if (!IsGattConnected()) {
+ GetMacAdapter()->CreateGattConnection(this);
+ }
}
void BluetoothLowEnergyDeviceMac::DisconnectGatt() {
- // Mac implementation does not yet use the default CreateGattConnection
- // implementation. http://crbug.com/520774
- NOTIMPLEMENTED();
+ GetMacAdapter()->DisconnectGatt(this);
}
// static
@@ -265,3 +260,19 @@ std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(
std::string hash = base::HexEncode(raw, sizeof(raw));
return BluetoothDevice::CanonicalizeAddress(hash);
}
+
+device::BluetoothAdapterMac* BluetoothLowEnergyDeviceMac::GetMacAdapter() {
+ return static_cast<BluetoothAdapterMac*>(this->adapter_);
+}
+
+CBPeripheral* BluetoothLowEnergyDeviceMac::GetPeripheral() {
+ return peripheral_;
+}
+
+void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral() {
+ if (create_gatt_connection_error_callbacks_.empty()) {
+ DidDisconnectGatt();
+ } else {
+ DidFailToConnectGatt(ERROR_FAILED);
+ }
+}
diff --git a/device/bluetooth/test/bluetooth_test_mac.h b/device/bluetooth/test/bluetooth_test_mac.h
index fd354da..1b40b2b 100644
--- a/device/bluetooth/test/bluetooth_test_mac.h
+++ b/device/bluetooth/test/bluetooth_test_mac.h
@@ -5,6 +5,7 @@
#ifndef DEVICE_BLUETOOTH_TEST_BLUETOOTH_TEST_MAC_H_
#define DEVICE_BLUETOOTH_TEST_BLUETOOTH_TEST_MAC_H_
+#include "base/memory/scoped_ptr.h"
#include "base/test/test_simple_task_runner.h"
#include "device/bluetooth/test/bluetooth_test.h"
@@ -30,12 +31,24 @@ class BluetoothTestMac : public BluetoothTestBase {
void InitWithoutDefaultAdapter() override;
void InitWithFakeAdapter() override;
BluetoothDevice* DiscoverLowEnergyDevice(int device_ordinal) override;
+ void SimulateGattConnection(BluetoothDevice* device) override;
+ void SimulateGattDisconnection(BluetoothDevice* device) override;
+ void SimulateGattConnectionError(
+ BluetoothDevice* device,
+ BluetoothDevice::ConnectErrorCode errorCode) override;
+
+ // Callback for the bluetooth central manager mock.
+ void OnFakeBluetoothDeviceConnectGattCalled();
+ void OnFakeBluetoothGattDisconnect();
protected:
+ class ScopedMockCentralManager;
+
// Utility function for finding CBUUIDs with relatively nice SHA256 hashes.
std::string FindCBUUIDForHashTarget();
BluetoothAdapterMac* adapter_mac_ = NULL;
+ scoped_ptr<ScopedMockCentralManager> mock_central_manager_;
};
// Defines common test fixture name. Use TEST_F(BluetoothTest, YourTestName).
diff --git a/device/bluetooth/test/bluetooth_test_mac.mm b/device/bluetooth/test/bluetooth_test_mac.mm
index d64b5f7..9ad4583 100644
--- a/device/bluetooth/test/bluetooth_test_mac.mm
+++ b/device/bluetooth/test/bluetooth_test_mac.mm
@@ -6,21 +6,38 @@
#include <stdint.h>
+#include "base/mac/foundation_util.h"
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_adapter_mac.h"
+#include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
#include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "third_party/ocmock/OCMock/OCMock.h"
-#if defined(OS_IOS)
#import <CoreBluetooth/CoreBluetooth.h>
-#else // !defined(OS_IOS)
-#import <IOBluetooth/IOBluetooth.h>
-#endif // defined(OS_IOS)
+
+using base::mac::ObjCCast;
+using base::scoped_nsobject;
namespace device {
+// This class hides Objective-C from bluetooth_test_mac.h.
+class BluetoothTestMac::ScopedMockCentralManager {
+ public:
+ explicit ScopedMockCentralManager(MockCentralManager* mock_central_manager) {
+ mock_central_manager_.reset(mock_central_manager);
+ }
+
+ // Returns MockCentralManager instance.
+ MockCentralManager* get() { return mock_central_manager_.get(); };
+
+ private:
+ scoped_nsobject<MockCentralManager> mock_central_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedMockCentralManager);
+};
+
namespace {
CBPeripheral* CreateMockPeripheral(NSString* peripheral_identifier) {
@@ -83,9 +100,11 @@ void BluetoothTestMac::InitWithoutDefaultAdapter() {
adapter_ = adapter_mac_;
if (BluetoothAdapterMac::IsLowEnergyAvailable()) {
- id low_energy_central_manager = [[MockCentralManager alloc] init];
- [low_energy_central_manager setState:CBCentralManagerStateUnsupported];
- adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager);
+ mock_central_manager_.reset(
+ new ScopedMockCentralManager([[MockCentralManager alloc] init]));
+ [mock_central_manager_->get() setBluetoothTestMac:this];
+ [mock_central_manager_->get() setState:CBCentralManagerStateUnsupported];
+ adapter_mac_->SetCentralManagerForTesting((id)mock_central_manager_->get());
}
}
@@ -97,9 +116,11 @@ void BluetoothTestMac::InitWithFakeAdapter() {
adapter_ = adapter_mac_;
if (BluetoothAdapterMac::IsLowEnergyAvailable()) {
- id low_energy_central_manager = [[MockCentralManager alloc] init];
- [low_energy_central_manager setState:CBCentralManagerStatePoweredOn];
- adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager);
+ mock_central_manager_.reset(
+ new ScopedMockCentralManager([[MockCentralManager alloc] init]));
+ mock_central_manager_->get().bluetoothTestMac = this;
+ [mock_central_manager_->get() setState:CBCentralManagerStatePoweredOn];
+ adapter_mac_->SetCentralManagerForTesting((id)mock_central_manager_->get());
}
}
@@ -151,12 +172,17 @@ BluetoothDevice* BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) {
break;
}
case 3: {
- CBPeripheral* peripheral = CreateMockPeripheral(
- [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]);
- NSString* name =
- [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()];
- NSArray* uuids = nil;
- NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids);
+ scoped_nsobject<NSString> uuid_string(
+ [[NSString alloc] initWithUTF8String:kTestPeripheralUUID1.c_str()]);
+ scoped_nsobject<NSUUID> identifier(
+ [[NSUUID alloc] initWithUUIDString:uuid_string]);
+ scoped_nsobject<CBPeripheral> peripheral;
+ peripheral.reset(static_cast<CBPeripheral*>(
+ [[MockCBPeripheral alloc] initWithIdentifier:identifier]));
+ scoped_nsobject<NSString> name(
+ [[NSString alloc] initWithUTF8String:kTestDeviceNameEmpty.c_str()]);
+ scoped_nsobject<NSDictionary> advertisement_data(
+ [CreateAdvertisementData(name, nil) retain]);
[central_manager_delegate centralManager:central_manager
didDiscoverPeripheral:peripheral
advertisementData:advertisement_data
@@ -180,6 +206,59 @@ BluetoothDevice* BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) {
return observer.last_device();
}
+void BluetoothTestMac::SimulateGattConnection(BluetoothDevice* device) {
+ BluetoothLowEnergyDeviceMac* lowEnergyDeviceMac =
+ static_cast<BluetoothLowEnergyDeviceMac*>(device);
+ CBPeripheral* peripheral = lowEnergyDeviceMac->GetPeripheral();
+ MockCBPeripheral* mockPeripheral = (MockCBPeripheral*)peripheral;
+ [mockPeripheral setState:CBPeripheralStateConnected];
+ CBCentralManager* centralManager =
+ ObjCCast<CBCentralManager>(mock_central_manager_->get());
+ [centralManager.delegate centralManager:centralManager
+ didConnectPeripheral:peripheral];
+}
+
+void BluetoothTestMac::SimulateGattDisconnection(BluetoothDevice* device) {
+ BluetoothLowEnergyDeviceMac* lowEnergyDeviceMac =
+ static_cast<BluetoothLowEnergyDeviceMac*>(device);
+ CBPeripheral* peripheral = lowEnergyDeviceMac->GetPeripheral();
+ MockCBPeripheral* mockPeripheral = (MockCBPeripheral*)peripheral;
+ [mockPeripheral setState:CBPeripheralStateDisconnected];
+ CBCentralManager* centralManager =
+ ObjCCast<CBCentralManager>(mock_central_manager_->get());
+ [centralManager.delegate centralManager:centralManager
+ didDisconnectPeripheral:peripheral
+ error:nil];
+}
+
+void BluetoothTestMac::SimulateGattConnectionError(
+ BluetoothDevice* device,
+ BluetoothDevice::ConnectErrorCode errorCode) {
+ BluetoothLowEnergyDeviceMac* lowEnergyDeviceMac =
+ static_cast<BluetoothLowEnergyDeviceMac*>(device);
+ CBPeripheral* peripheral = lowEnergyDeviceMac->GetPeripheral();
+ MockCBPeripheral* mockPeripheral = (MockCBPeripheral*)peripheral;
+ [mockPeripheral setState:CBPeripheralStateDisconnected];
+ CBCentralManager* centralManager =
+ ObjCCast<CBCentralManager>(mock_central_manager_->get());
+ // TODO(http://crbug.com/585894): Need to convert the connect error code into
+ // NSError
+ NSError* error = [NSError errorWithDomain:@"BluetoothDevice::ConnectErrorCode"
+ code:-1
+ userInfo:nil];
+ [centralManager.delegate centralManager:centralManager
+ didFailToConnectPeripheral:peripheral
+ error:error];
+}
+
+void BluetoothTestMac::OnFakeBluetoothDeviceConnectGattCalled() {
+ gatt_connection_attempts_++;
+}
+
+void BluetoothTestMac::OnFakeBluetoothGattDisconnect() {
+ gatt_disconnection_attempts_++;
+}
+
// Utility function for generating new (CBUUID, address) pairs where CBUUID
// hashes to address. For use when adding a new device address to the testing
// suite because CoreBluetooth peripherals have CBUUIDs in place of addresses,
diff --git a/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h b/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h
new file mode 100644
index 0000000..f2e66da
--- /dev/null
+++ b/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+#ifndef DEVICE_BLUETOOTH_MOCK_BLUETOOTH_CBPERIPHERAL_MAC_H_
+#define DEVICE_BLUETOOTH_MOCK_BLUETOOTH_CBPERIPHERAL_MAC_H_
+
+#include "base/mac/sdk_forward_declarations.h"
+#include "build/build_config.h"
+
+#import <CoreBluetooth/CoreBluetooth.h>
+
+// This class mocks the behavior of a CBPeripheral.
+@interface MockCBPeripheral : NSObject
+
+@property(nonatomic, readonly) CBPeripheralState state;
+@property(nonatomic, readonly) NSUUID* identifier;
+@property(nonatomic, readonly) NSString* name;
+
+- (instancetype)initWithIdentifier:(NSUUID*)identifier;
+- (void)setState:(CBPeripheralState)state;
+
+@end
+
+#endif // DEVICE_BLUETOOTH_MOCK_BLUETOOTH_CBPERIPHERAL_MAC_H_
diff --git a/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm b/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm
new file mode 100644
index 0000000..0ca4a46
--- /dev/null
+++ b/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm
@@ -0,0 +1,42 @@
+// Copyright 2015 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.
+
+#import "mock_bluetooth_cbperipheral_mac.h"
+
+#include "base/mac/scoped_nsobject.h"
+
+@interface MockCBPeripheral () {
+ base::scoped_nsobject<NSUUID> _identifier;
+ base::scoped_nsobject<NSString> _name;
+}
+
+@end
+
+@implementation MockCBPeripheral
+
+@synthesize state = _state;
+
+- (instancetype)initWithIdentifier:(NSUUID*)identifier {
+ self = [super init];
+ if (self) {
+ _identifier.reset([identifier retain]);
+ _name.reset([@"FakeBluetoothDevice" retain]);
+ _state = CBPeripheralStateDisconnected;
+ }
+ return self;
+}
+
+- (void)setState:(CBPeripheralState)state {
+ _state = state;
+}
+
+- (NSUUID*)identifier {
+ return _identifier.get();
+}
+
+- (NSString*)name {
+ return _name.get();
+}
+
+@end
diff --git a/device/bluetooth/test/mock_bluetooth_central_manager_mac.h b/device/bluetooth/test/mock_bluetooth_central_manager_mac.h
index 535d72d2..5bc0245 100644
--- a/device/bluetooth/test/mock_bluetooth_central_manager_mac.h
+++ b/device/bluetooth/test/mock_bluetooth_central_manager_mac.h
@@ -7,12 +7,9 @@
#include "base/mac/sdk_forward_declarations.h"
#include "build/build_config.h"
+#include "device/bluetooth/test/bluetooth_test_mac.h"
-#if defined(OS_IOS)
#import <CoreBluetooth/CoreBluetooth.h>
-#else
-#import <IOBluetooth/IOBluetooth.h>
-#endif
// Class to mock a CBCentralManager. Cannot use a OCMockObject because mocking
// the 'state' property gives a compiler warning when mock_central_manager is of
@@ -25,12 +22,16 @@
@property(nonatomic, assign) NSInteger stopScanCallCount;
@property(nonatomic, assign) id<CBCentralManagerDelegate> delegate;
@property(nonatomic, assign) CBCentralManagerState state;
+@property(nonatomic, assign) device::BluetoothTestMac* bluetoothTestMac;
- (void)scanForPeripheralsWithServices:(NSArray*)serviceUUIDs
options:(NSDictionary*)options;
- (void)stopScan;
+- (void)connectPeripheral:(CBPeripheral*)peripheral
+ options:(NSDictionary*)options;
+
@end
#endif // DEVICE_BLUETOOTH_MOCK_BLUETOOTH_CENTRAL_MANAGER_MAC_H_
diff --git a/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm b/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm
index 96e7ce9..fbb0dff 100644
--- a/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm
+++ b/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm
@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#import "mock_bluetooth_central_manager_mac.h"
+#import "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
+
+#import "device/bluetooth/test/bluetooth_test_mac.h"
+#import "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
@implementation MockCentralManager
@@ -10,6 +13,23 @@
@synthesize stopScanCallCount = _stopScanCallCount;
@synthesize delegate = _delegate;
@synthesize state = _state;
+@synthesize bluetoothTestMac = _bluetoothTestMac;
+
+- (BOOL)isKindOfClass:(Class)aClass {
+ if (aClass == [CBCentralManager class] ||
+ [aClass isSubclassOfClass:[CBCentralManager class]]) {
+ return YES;
+ }
+ return [super isKindOfClass:aClass];
+}
+
+- (BOOL)isMemberOfClass:(Class)aClass {
+ if (aClass == [CBCentralManager class] ||
+ [aClass isSubclassOfClass:[CBCentralManager class]]) {
+ return YES;
+ }
+ return [super isKindOfClass:aClass];
+}
- (void)scanForPeripheralsWithServices:(NSArray*)serviceUUIDs
options:(NSDictionary*)options {
@@ -20,4 +40,17 @@
_stopScanCallCount++;
}
+- (void)connectPeripheral:(CBPeripheral*)peripheral
+ options:(NSDictionary*)options {
+ if (_bluetoothTestMac) {
+ _bluetoothTestMac->OnFakeBluetoothDeviceConnectGattCalled();
+ }
+}
+
+- (void)cancelPeripheralConnection:(CBPeripheral*)peripheral {
+ if (_bluetoothTestMac) {
+ _bluetoothTestMac->OnFakeBluetoothGattDisconnect();
+ }
+}
+
@end
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index 7a22fb3..e477b11 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -59,6 +59,10 @@
'bluetooth/test/bluetooth_test_mac.mm',
'bluetooth/test/bluetooth_test_win.h',
'bluetooth/test/bluetooth_test_win.cc',
+ 'bluetooth/test/mock_bluetooth_cbperipheral_mac.mm',
+ 'bluetooth/test/mock_bluetooth_cbperipheral_mac.h',
+ 'bluetooth/test/mock_bluetooth_central_manager_mac.mm',
+ 'bluetooth/test/mock_bluetooth_central_manager_mac.h',
'bluetooth/test/test_bluetooth_adapter_observer.cc',
'bluetooth/test/test_bluetooth_adapter_observer.h',
'hid/hid_connection_unittest.cc',