| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/bluetooth/bluetooth_adapter_mac.h" | 5 #include "device/bluetooth/bluetooth_adapter_mac.h" |
| 6 | 6 |
| 7 #import <Foundation/Foundation.h> |
| 8 |
| 7 #include <memory> | 9 #include <memory> |
| 8 | 10 |
| 9 #include "base/bind.h" | 11 #include "base/bind.h" |
| 10 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 11 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 12 #include "base/test/test_simple_task_runner.h" | 14 #include "base/test/test_simple_task_runner.h" |
| 13 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 14 #include "device/bluetooth/bluetooth_adapter.h" | 16 #include "device/bluetooth/bluetooth_adapter.h" |
| 15 #include "device/bluetooth/bluetooth_common.h" | 17 #include "device/bluetooth/bluetooth_common.h" |
| 16 #include "device/bluetooth/bluetooth_discovery_session.h" | 18 #include "device/bluetooth/bluetooth_discovery_session.h" |
| 17 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" | 19 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" |
| 18 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" | 20 #import "device/bluetooth/bluetooth_low_energy_device_mac.h" |
| 19 #include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h" | 21 #import "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h" |
| 20 #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" | 22 #import "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #include "third_party/ocmock/OCMock/OCMock.h" | 24 #import "third_party/ocmock/OCMock/OCMock.h" |
| 23 | 25 |
| 24 #if defined(OS_IOS) | 26 #if defined(OS_IOS) |
| 25 #import <CoreBluetooth/CoreBluetooth.h> | 27 #import <CoreBluetooth/CoreBluetooth.h> |
| 26 #else // !defined(OS_IOS) | 28 #else // !defined(OS_IOS) |
| 27 #import <IOBluetooth/IOBluetooth.h> | 29 #import <IOBluetooth/IOBluetooth.h> |
| 28 #endif // defined(OS_IOS) | 30 #endif // defined(OS_IOS) |
| 29 | 31 |
| 30 #import <Foundation/Foundation.h> | |
| 31 | |
| 32 namespace { | 32 namespace { |
| 33 // |kTestHashAddress| is the hash corresponding to identifier |kTestNSUUID|. | 33 // |kTestHashAddress| is the hash corresponding to identifier |kTestNSUUID|. |
| 34 const char* const kTestNSUUID = "00000000-1111-2222-3333-444444444444"; | 34 const char* const kTestNSUUID = "00000000-1111-2222-3333-444444444444"; |
| 35 const std::string kTestHashAddress = "D1:6F:E3:22:FD:5B"; | 35 const std::string kTestHashAddress = "D1:6F:E3:22:FD:5B"; |
| 36 const int kTestRssi = 0; | 36 const int kTestRssi = 0; |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 namespace device { | 39 namespace device { |
| 40 | 40 |
| 41 class BluetoothAdapterMacTest : public testing::Test { | 41 class BluetoothAdapterMacTest : public testing::Test { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } | 85 } |
| 86 | 86 |
| 87 int NumDevices() { return adapter_mac_->devices_.size(); } | 87 int NumDevices() { return adapter_mac_->devices_.size(); } |
| 88 | 88 |
| 89 bool DevicePresent(CBPeripheral* peripheral) { | 89 bool DevicePresent(CBPeripheral* peripheral) { |
| 90 BluetoothDevice* device = adapter_mac_->GetDevice( | 90 BluetoothDevice* device = adapter_mac_->GetDevice( |
| 91 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral)); | 91 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral)); |
| 92 return (device != NULL); | 92 return (device != NULL); |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool SetMockCentralManager(CBCentralManagerState desired_state) { | 95 bool SetMockCentralManager(CBManagerState desired_state) { |
| 96 if (!BluetoothAdapterMac::IsLowEnergyAvailable()) { | 96 if (!BluetoothAdapterMac::IsLowEnergyAvailable()) { |
| 97 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; | 97 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
| 98 return false; | 98 return false; |
| 99 } | 99 } |
| 100 mock_central_manager_.reset([[MockCentralManager alloc] init]); | 100 mock_central_manager_.reset([[MockCentralManager alloc] init]); |
| 101 [mock_central_manager_ setState:desired_state]; | 101 [mock_central_manager_ setState:desired_state]; |
| 102 CBCentralManager* centralManager = | 102 CBCentralManager* centralManager = |
| 103 static_cast<CBCentralManager*>(mock_central_manager_.get()); | 103 static_cast<CBCentralManager*>(mock_central_manager_.get()); |
| 104 adapter_mac_->SetCentralManagerForTesting(centralManager); | 104 adapter_mac_->SetCentralManagerForTesting(centralManager); |
| 105 return true; | 105 return true; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 int callback_count_; | 141 int callback_count_; |
| 142 int error_callback_count_; | 142 int error_callback_count_; |
| 143 }; | 143 }; |
| 144 | 144 |
| 145 TEST_F(BluetoothAdapterMacTest, Poll) { | 145 TEST_F(BluetoothAdapterMacTest, Poll) { |
| 146 PollAdapter(); | 146 PollAdapter(); |
| 147 EXPECT_TRUE(ui_task_runner_->HasPendingTask()); | 147 EXPECT_TRUE(ui_task_runner_->HasPendingTask()); |
| 148 } | 148 } |
| 149 | 149 |
| 150 TEST_F(BluetoothAdapterMacTest, AddDiscoverySessionWithLowEnergyFilter) { | 150 TEST_F(BluetoothAdapterMacTest, AddDiscoverySessionWithLowEnergyFilter) { |
| 151 if (!SetMockCentralManager(CBCentralManagerStatePoweredOn)) | 151 if (!SetMockCentralManager(CBManagerStatePoweredOn)) |
| 152 return; | 152 return; |
| 153 EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]); | 153 EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]); |
| 154 EXPECT_EQ(0, NumDiscoverySessions()); | 154 EXPECT_EQ(0, NumDiscoverySessions()); |
| 155 | 155 |
| 156 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( | 156 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( |
| 157 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); | 157 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); |
| 158 AddDiscoverySession(discovery_filter.get()); | 158 AddDiscoverySession(discovery_filter.get()); |
| 159 EXPECT_EQ(1, callback_count_); | 159 EXPECT_EQ(1, callback_count_); |
| 160 EXPECT_EQ(0, error_callback_count_); | 160 EXPECT_EQ(0, error_callback_count_); |
| 161 EXPECT_EQ(1, NumDiscoverySessions()); | 161 EXPECT_EQ(1, NumDiscoverySessions()); |
| 162 | 162 |
| 163 // Check that adding a discovery session resulted in | 163 // Check that adding a discovery session resulted in |
| 164 // scanForPeripheralsWithServices being called on the Central Manager. | 164 // scanForPeripheralsWithServices being called on the Central Manager. |
| 165 EXPECT_EQ(1, [mock_central_manager_ scanForPeripheralsCallCount]); | 165 EXPECT_EQ(1, [mock_central_manager_ scanForPeripheralsCallCount]); |
| 166 } | 166 } |
| 167 | 167 |
| 168 // TODO(krstnmnlsn): Test changing the filter when adding the second discovery | 168 // TODO(krstnmnlsn): Test changing the filter when adding the second discovery |
| 169 // session (once we have that ability). | 169 // session (once we have that ability). |
| 170 TEST_F(BluetoothAdapterMacTest, AddSecondDiscoverySessionWithLowEnergyFilter) { | 170 TEST_F(BluetoothAdapterMacTest, AddSecondDiscoverySessionWithLowEnergyFilter) { |
| 171 if (!SetMockCentralManager(CBCentralManagerStatePoweredOn)) | 171 if (!SetMockCentralManager(CBManagerStatePoweredOn)) |
| 172 return; | 172 return; |
| 173 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( | 173 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( |
| 174 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); | 174 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); |
| 175 AddDiscoverySession(discovery_filter.get()); | 175 AddDiscoverySession(discovery_filter.get()); |
| 176 EXPECT_EQ(1, callback_count_); | 176 EXPECT_EQ(1, callback_count_); |
| 177 EXPECT_EQ(0, error_callback_count_); | 177 EXPECT_EQ(0, error_callback_count_); |
| 178 EXPECT_EQ(1, NumDiscoverySessions()); | 178 EXPECT_EQ(1, NumDiscoverySessions()); |
| 179 | 179 |
| 180 // We replaced the success callback handed to AddDiscoverySession, so | 180 // We replaced the success callback handed to AddDiscoverySession, so |
| 181 // |adapter_mac_| should remain in a discovering state indefinitely. | 181 // |adapter_mac_| should remain in a discovering state indefinitely. |
| 182 EXPECT_TRUE(adapter_mac_->IsDiscovering()); | 182 EXPECT_TRUE(adapter_mac_->IsDiscovering()); |
| 183 | 183 |
| 184 AddDiscoverySession(discovery_filter.get()); | 184 AddDiscoverySession(discovery_filter.get()); |
| 185 EXPECT_EQ(2, [mock_central_manager_ scanForPeripheralsCallCount]); | 185 EXPECT_EQ(2, [mock_central_manager_ scanForPeripheralsCallCount]); |
| 186 EXPECT_EQ(2, callback_count_); | 186 EXPECT_EQ(2, callback_count_); |
| 187 EXPECT_EQ(0, error_callback_count_); | 187 EXPECT_EQ(0, error_callback_count_); |
| 188 EXPECT_EQ(2, NumDiscoverySessions()); | 188 EXPECT_EQ(2, NumDiscoverySessions()); |
| 189 } | 189 } |
| 190 | 190 |
| 191 TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilter) { | 191 TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilter) { |
| 192 if (!SetMockCentralManager(CBCentralManagerStatePoweredOn)) | 192 if (!SetMockCentralManager(CBManagerStatePoweredOn)) |
| 193 return; | 193 return; |
| 194 EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]); | 194 EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]); |
| 195 | 195 |
| 196 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( | 196 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( |
| 197 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); | 197 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); |
| 198 AddDiscoverySession(discovery_filter.get()); | 198 AddDiscoverySession(discovery_filter.get()); |
| 199 EXPECT_EQ(1, callback_count_); | 199 EXPECT_EQ(1, callback_count_); |
| 200 EXPECT_EQ(0, error_callback_count_); | 200 EXPECT_EQ(0, error_callback_count_); |
| 201 EXPECT_EQ(1, NumDiscoverySessions()); | 201 EXPECT_EQ(1, NumDiscoverySessions()); |
| 202 | 202 |
| 203 EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]); | 203 EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]); |
| 204 RemoveDiscoverySession(discovery_filter.get()); | 204 RemoveDiscoverySession(discovery_filter.get()); |
| 205 EXPECT_EQ(2, callback_count_); | 205 EXPECT_EQ(2, callback_count_); |
| 206 EXPECT_EQ(0, error_callback_count_); | 206 EXPECT_EQ(0, error_callback_count_); |
| 207 EXPECT_EQ(0, NumDiscoverySessions()); | 207 EXPECT_EQ(0, NumDiscoverySessions()); |
| 208 | 208 |
| 209 // Check that removing the discovery session resulted in stopScan being called | 209 // Check that removing the discovery session resulted in stopScan being called |
| 210 // on the Central Manager. | 210 // on the Central Manager. |
| 211 EXPECT_EQ(1, [mock_central_manager_ stopScanCallCount]); | 211 EXPECT_EQ(1, [mock_central_manager_ stopScanCallCount]); |
| 212 } | 212 } |
| 213 | 213 |
| 214 TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilterFail) { | 214 TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilterFail) { |
| 215 if (!SetMockCentralManager(CBCentralManagerStatePoweredOn)) | 215 if (!SetMockCentralManager(CBManagerStatePoweredOn)) |
| 216 return; | 216 return; |
| 217 EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]); | 217 EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]); |
| 218 EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]); | 218 EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]); |
| 219 EXPECT_EQ(0, NumDiscoverySessions()); | 219 EXPECT_EQ(0, NumDiscoverySessions()); |
| 220 | 220 |
| 221 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( | 221 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter( |
| 222 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); | 222 new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE)); |
| 223 RemoveDiscoverySession(discovery_filter.get()); | 223 RemoveDiscoverySession(discovery_filter.get()); |
| 224 EXPECT_EQ(0, callback_count_); | 224 EXPECT_EQ(0, callback_count_); |
| 225 EXPECT_EQ(1, error_callback_count_); | 225 EXPECT_EQ(1, error_callback_count_); |
| 226 EXPECT_EQ(0, NumDiscoverySessions()); | 226 EXPECT_EQ(0, NumDiscoverySessions()); |
| 227 | 227 |
| 228 // Check that stopScan was not called. | 228 // Check that stopScan was not called. |
| 229 EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]); | 229 EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]); |
| 230 } | 230 } |
| 231 | 231 |
| 232 TEST_F(BluetoothAdapterMacTest, CheckGetPeripheralHashAddress) { | 232 TEST_F(BluetoothAdapterMacTest, CheckGetPeripheralHashAddress) { |
| 233 if (!SetMockCentralManager(CBCentralManagerStatePoweredOn)) | 233 if (!SetMockCentralManager(CBManagerStatePoweredOn)) |
| 234 return; | 234 return; |
| 235 base::scoped_nsobject<CBPeripheral> mock_peripheral( | 235 base::scoped_nsobject<CBPeripheral> mock_peripheral( |
| 236 CreateMockPeripheral(kTestNSUUID)); | 236 CreateMockPeripheral(kTestNSUUID)); |
| 237 if (!mock_peripheral) | 237 if (!mock_peripheral) |
| 238 return; | 238 return; |
| 239 EXPECT_EQ(kTestHashAddress, GetHashAddress(mock_peripheral)); | 239 EXPECT_EQ(kTestHashAddress, GetHashAddress(mock_peripheral)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 TEST_F(BluetoothAdapterMacTest, LowEnergyDeviceUpdatedNewDevice) { | 242 TEST_F(BluetoothAdapterMacTest, LowEnergyDeviceUpdatedNewDevice) { |
| 243 if (!SetMockCentralManager(CBCentralManagerStatePoweredOn)) | 243 if (!SetMockCentralManager(CBManagerStatePoweredOn)) |
| 244 return; | 244 return; |
| 245 base::scoped_nsobject<CBPeripheral> mock_peripheral( | 245 base::scoped_nsobject<CBPeripheral> mock_peripheral( |
| 246 CreateMockPeripheral(kTestNSUUID)); | 246 CreateMockPeripheral(kTestNSUUID)); |
| 247 if (!mock_peripheral) | 247 if (!mock_peripheral) |
| 248 return; | 248 return; |
| 249 base::scoped_nsobject<NSDictionary> advertisement_data(AdvertisementData()); | 249 base::scoped_nsobject<NSDictionary> advertisement_data(AdvertisementData()); |
| 250 | 250 |
| 251 EXPECT_EQ(0, NumDevices()); | 251 EXPECT_EQ(0, NumDevices()); |
| 252 EXPECT_FALSE(DevicePresent(mock_peripheral)); | 252 EXPECT_FALSE(DevicePresent(mock_peripheral)); |
| 253 LowEnergyDeviceUpdated(mock_peripheral, advertisement_data, kTestRssi); | 253 LowEnergyDeviceUpdated(mock_peripheral, advertisement_data, kTestRssi); |
| 254 EXPECT_EQ(1, NumDevices()); | 254 EXPECT_EQ(1, NumDevices()); |
| 255 EXPECT_TRUE(DevicePresent(mock_peripheral)); | 255 EXPECT_TRUE(DevicePresent(mock_peripheral)); |
| 256 } | 256 } |
| 257 | 257 |
| 258 } // namespace device | 258 } // namespace device |
| OLD | NEW |