OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/test/bluetooth_test_mac.h" | 5 #include "device/bluetooth/test/bluetooth_test_mac.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
| 9 #include "base/mac/foundation_util.h" |
9 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
10 #include "build/build_config.h" | 11 #include "build/build_config.h" |
11 #include "device/bluetooth/bluetooth_adapter_mac.h" | 12 #include "device/bluetooth/bluetooth_adapter_mac.h" |
| 13 #include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h" |
12 #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" | 14 #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" |
13 #include "device/bluetooth/test/test_bluetooth_adapter_observer.h" | 15 #include "device/bluetooth/test/test_bluetooth_adapter_observer.h" |
14 #include "third_party/ocmock/OCMock/OCMock.h" | 16 #include "third_party/ocmock/OCMock/OCMock.h" |
15 | 17 |
16 #if defined(OS_IOS) | |
17 #import <CoreBluetooth/CoreBluetooth.h> | 18 #import <CoreBluetooth/CoreBluetooth.h> |
18 #else // !defined(OS_IOS) | 19 |
19 #import <IOBluetooth/IOBluetooth.h> | 20 using base::mac::ObjCCast; |
20 #endif // defined(OS_IOS) | 21 using base::scoped_nsobject; |
21 | 22 |
22 namespace device { | 23 namespace device { |
23 | 24 |
| 25 // This class hides Objective-C from bluetooth_test_mac.h. |
| 26 class BluetoothTestMac::ScopedMockCentralManager { |
| 27 public: |
| 28 explicit ScopedMockCentralManager(MockCentralManager* mock_central_manager) { |
| 29 mock_central_manager_.reset(mock_central_manager); |
| 30 } |
| 31 |
| 32 // Returns MockCentralManager instance. |
| 33 MockCentralManager* get() { return mock_central_manager_.get(); }; |
| 34 |
| 35 private: |
| 36 scoped_nsobject<MockCentralManager> mock_central_manager_; |
| 37 |
| 38 DISALLOW_COPY_AND_ASSIGN(ScopedMockCentralManager); |
| 39 }; |
| 40 |
24 namespace { | 41 namespace { |
25 | 42 |
26 CBPeripheral* CreateMockPeripheral(NSString* peripheral_identifier) { | 43 CBPeripheral* CreateMockPeripheral(NSString* peripheral_identifier) { |
27 Class peripheral_class = NSClassFromString(@"CBPeripheral"); | 44 Class peripheral_class = NSClassFromString(@"CBPeripheral"); |
28 id mock_peripheral = [OCMockObject mockForClass:[peripheral_class class]]; | 45 id mock_peripheral = [OCMockObject mockForClass:[peripheral_class class]]; |
29 [[[mock_peripheral stub] andReturnValue:@(CBPeripheralStateDisconnected)] | 46 [[[mock_peripheral stub] andReturnValue:@(CBPeripheralStateDisconnected)] |
30 performSelector:@selector(state)]; | 47 performSelector:@selector(state)]; |
31 Class uuid_class = NSClassFromString(@"NSUUID"); | 48 Class uuid_class = NSClassFromString(@"NSUUID"); |
32 [[[mock_peripheral stub] | 49 [[[mock_peripheral stub] |
33 andReturn:[[uuid_class performSelector:@selector(UUID)] | 50 andReturn:[[uuid_class performSelector:@selector(UUID)] |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 adapter_ = adapter_mac_; | 93 adapter_ = adapter_mac_; |
77 } | 94 } |
78 | 95 |
79 void BluetoothTestMac::InitWithoutDefaultAdapter() { | 96 void BluetoothTestMac::InitWithoutDefaultAdapter() { |
80 adapter_mac_ = BluetoothAdapterMac::CreateAdapterForTest( | 97 adapter_mac_ = BluetoothAdapterMac::CreateAdapterForTest( |
81 "", "", message_loop_.task_runner()) | 98 "", "", message_loop_.task_runner()) |
82 .get(); | 99 .get(); |
83 adapter_ = adapter_mac_; | 100 adapter_ = adapter_mac_; |
84 | 101 |
85 if (BluetoothAdapterMac::IsLowEnergyAvailable()) { | 102 if (BluetoothAdapterMac::IsLowEnergyAvailable()) { |
86 id low_energy_central_manager = [[MockCentralManager alloc] init]; | 103 mock_central_manager_.reset( |
87 [low_energy_central_manager setState:CBCentralManagerStateUnsupported]; | 104 new ScopedMockCentralManager([[MockCentralManager alloc] init])); |
88 adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager); | 105 [mock_central_manager_->get() setBluetoothTestMac:this]; |
| 106 [mock_central_manager_->get() setState:CBCentralManagerStateUnsupported]; |
| 107 adapter_mac_->SetCentralManagerForTesting((id)mock_central_manager_->get()); |
89 } | 108 } |
90 } | 109 } |
91 | 110 |
92 void BluetoothTestMac::InitWithFakeAdapter() { | 111 void BluetoothTestMac::InitWithFakeAdapter() { |
93 adapter_mac_ = | 112 adapter_mac_ = |
94 BluetoothAdapterMac::CreateAdapterForTest( | 113 BluetoothAdapterMac::CreateAdapterForTest( |
95 kTestAdapterName, kTestAdapterAddress, message_loop_.task_runner()) | 114 kTestAdapterName, kTestAdapterAddress, message_loop_.task_runner()) |
96 .get(); | 115 .get(); |
97 adapter_ = adapter_mac_; | 116 adapter_ = adapter_mac_; |
98 | 117 |
99 if (BluetoothAdapterMac::IsLowEnergyAvailable()) { | 118 if (BluetoothAdapterMac::IsLowEnergyAvailable()) { |
100 id low_energy_central_manager = [[MockCentralManager alloc] init]; | 119 mock_central_manager_.reset( |
101 [low_energy_central_manager setState:CBCentralManagerStatePoweredOn]; | 120 new ScopedMockCentralManager([[MockCentralManager alloc] init])); |
102 adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager); | 121 mock_central_manager_->get().bluetoothTestMac = this; |
| 122 [mock_central_manager_->get() setState:CBCentralManagerStatePoweredOn]; |
| 123 adapter_mac_->SetCentralManagerForTesting((id)mock_central_manager_->get()); |
103 } | 124 } |
104 } | 125 } |
105 | 126 |
106 BluetoothDevice* BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) { | 127 BluetoothDevice* BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) { |
107 TestBluetoothAdapterObserver observer(adapter_); | 128 TestBluetoothAdapterObserver observer(adapter_); |
108 CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_; | 129 CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_; |
109 BluetoothLowEnergyCentralManagerDelegate* central_manager_delegate = | 130 BluetoothLowEnergyCentralManagerDelegate* central_manager_delegate = |
110 adapter_mac_->low_energy_central_manager_delegate_; | 131 adapter_mac_->low_energy_central_manager_delegate_; |
111 Class cbuuid_class = NSClassFromString(@"CBUUID"); | 132 Class cbuuid_class = NSClassFromString(@"CBUUID"); |
112 switch (device_ordinal) { | 133 switch (device_ordinal) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 stringWithUTF8String:kTestUUIDLinkLoss.c_str()]] | 165 stringWithUTF8String:kTestUUIDLinkLoss.c_str()]] |
145 ]; | 166 ]; |
146 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | 167 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); |
147 [central_manager_delegate centralManager:central_manager | 168 [central_manager_delegate centralManager:central_manager |
148 didDiscoverPeripheral:peripheral | 169 didDiscoverPeripheral:peripheral |
149 advertisementData:advertisement_data | 170 advertisementData:advertisement_data |
150 RSSI:@(0)]; | 171 RSSI:@(0)]; |
151 break; | 172 break; |
152 } | 173 } |
153 case 3: { | 174 case 3: { |
154 CBPeripheral* peripheral = CreateMockPeripheral( | 175 scoped_nsobject<NSString> uuid_string( |
155 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); | 176 [[NSString alloc] initWithUTF8String:kTestPeripheralUUID1.c_str()]); |
156 NSString* name = | 177 scoped_nsobject<NSUUID> identifier( |
157 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; | 178 [[NSUUID alloc] initWithUUIDString:uuid_string]); |
158 NSArray* uuids = nil; | 179 scoped_nsobject<CBPeripheral> peripheral; |
159 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | 180 peripheral.reset(static_cast<CBPeripheral*>( |
| 181 [[MockCBPeripheral alloc] initWithIdentifier:identifier])); |
| 182 scoped_nsobject<NSString> name( |
| 183 [[NSString alloc] initWithUTF8String:kTestDeviceNameEmpty.c_str()]); |
| 184 scoped_nsobject<NSDictionary> advertisement_data( |
| 185 [CreateAdvertisementData(name, nil) retain]); |
160 [central_manager_delegate centralManager:central_manager | 186 [central_manager_delegate centralManager:central_manager |
161 didDiscoverPeripheral:peripheral | 187 didDiscoverPeripheral:peripheral |
162 advertisementData:advertisement_data | 188 advertisementData:advertisement_data |
163 RSSI:@(0)]; | 189 RSSI:@(0)]; |
164 break; | 190 break; |
165 } | 191 } |
166 case 4: { | 192 case 4: { |
167 CBPeripheral* peripheral = CreateMockPeripheral( | 193 CBPeripheral* peripheral = CreateMockPeripheral( |
168 [NSString stringWithUTF8String:kTestPeripheralUUID2.c_str()]); | 194 [NSString stringWithUTF8String:kTestPeripheralUUID2.c_str()]); |
169 NSString* name = | 195 NSString* name = |
170 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; | 196 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; |
171 NSArray* uuids = nil; | 197 NSArray* uuids = nil; |
172 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | 198 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); |
173 [central_manager_delegate centralManager:central_manager | 199 [central_manager_delegate centralManager:central_manager |
174 didDiscoverPeripheral:peripheral | 200 didDiscoverPeripheral:peripheral |
175 advertisementData:advertisement_data | 201 advertisementData:advertisement_data |
176 RSSI:@(0)]; | 202 RSSI:@(0)]; |
177 break; | 203 break; |
178 } | 204 } |
179 } | 205 } |
180 return observer.last_device(); | 206 return observer.last_device(); |
181 } | 207 } |
182 | 208 |
| 209 void BluetoothTestMac::SimulateGattConnection(BluetoothDevice* device) { |
| 210 BluetoothLowEnergyDeviceMac* lowEnergyDeviceMac = |
| 211 static_cast<BluetoothLowEnergyDeviceMac*>(device); |
| 212 CBPeripheral* peripheral = lowEnergyDeviceMac->GetPeripheral(); |
| 213 MockCBPeripheral* mockPeripheral = (MockCBPeripheral*)peripheral; |
| 214 [mockPeripheral setState:CBPeripheralStateConnected]; |
| 215 CBCentralManager* centralManager = |
| 216 ObjCCast<CBCentralManager>(mock_central_manager_->get()); |
| 217 [centralManager.delegate centralManager:centralManager |
| 218 didConnectPeripheral:peripheral]; |
| 219 } |
| 220 |
| 221 void BluetoothTestMac::SimulateGattDisconnection(BluetoothDevice* device) { |
| 222 BluetoothLowEnergyDeviceMac* lowEnergyDeviceMac = |
| 223 static_cast<BluetoothLowEnergyDeviceMac*>(device); |
| 224 CBPeripheral* peripheral = lowEnergyDeviceMac->GetPeripheral(); |
| 225 MockCBPeripheral* mockPeripheral = (MockCBPeripheral*)peripheral; |
| 226 [mockPeripheral setState:CBPeripheralStateDisconnected]; |
| 227 CBCentralManager* centralManager = |
| 228 ObjCCast<CBCentralManager>(mock_central_manager_->get()); |
| 229 [centralManager.delegate centralManager:centralManager |
| 230 didDisconnectPeripheral:peripheral |
| 231 error:nil]; |
| 232 } |
| 233 |
| 234 void BluetoothTestMac::SimulateGattConnectionError( |
| 235 BluetoothDevice* device, |
| 236 BluetoothDevice::ConnectErrorCode errorCode) { |
| 237 BluetoothLowEnergyDeviceMac* lowEnergyDeviceMac = |
| 238 static_cast<BluetoothLowEnergyDeviceMac*>(device); |
| 239 CBPeripheral* peripheral = lowEnergyDeviceMac->GetPeripheral(); |
| 240 MockCBPeripheral* mockPeripheral = (MockCBPeripheral*)peripheral; |
| 241 [mockPeripheral setState:CBPeripheralStateDisconnected]; |
| 242 CBCentralManager* centralManager = |
| 243 ObjCCast<CBCentralManager>(mock_central_manager_->get()); |
| 244 // TODO(http://crbug.com/585894): Need to convert the connect error code into |
| 245 // NSError |
| 246 NSError* error = [NSError errorWithDomain:@"BluetoothDevice::ConnectErrorCode" |
| 247 code:-1 |
| 248 userInfo:nil]; |
| 249 [centralManager.delegate centralManager:centralManager |
| 250 didFailToConnectPeripheral:peripheral |
| 251 error:error]; |
| 252 } |
| 253 |
| 254 void BluetoothTestMac::OnFakeBluetoothDeviceConnectGattCalled() { |
| 255 gatt_connection_attempts_++; |
| 256 } |
| 257 |
| 258 void BluetoothTestMac::OnFakeBluetoothGattDisconnect() { |
| 259 gatt_disconnection_attempts_++; |
| 260 } |
| 261 |
183 // Utility function for generating new (CBUUID, address) pairs where CBUUID | 262 // Utility function for generating new (CBUUID, address) pairs where CBUUID |
184 // hashes to address. For use when adding a new device address to the testing | 263 // hashes to address. For use when adding a new device address to the testing |
185 // suite because CoreBluetooth peripherals have CBUUIDs in place of addresses, | 264 // suite because CoreBluetooth peripherals have CBUUIDs in place of addresses, |
186 // and we construct fake addresses for them by hashing the CBUUID. By changing | 265 // and we construct fake addresses for them by hashing the CBUUID. By changing |
187 // |target| the user can generate sequentially numbered test addresses. | 266 // |target| the user can generate sequentially numbered test addresses. |
188 // | 267 // |
189 // std::string BluetoothTestMac::FindCBUUIDForHashTarget() { | 268 // std::string BluetoothTestMac::FindCBUUIDForHashTarget() { |
190 // // The desired first 6 digits of the hash. For example 0100000, 020000, | 269 // // The desired first 6 digits of the hash. For example 0100000, 020000, |
191 // // 030000, ... | 270 // // 030000, ... |
192 // const std::string target = "010000"; | 271 // const std::string target = "010000"; |
(...skipping 16 matching lines...) Expand all Loading... |
209 // crypto::SHA256HashString(input_str, raw, sizeof(raw)); | 288 // crypto::SHA256HashString(input_str, raw, sizeof(raw)); |
210 // if (base::HexEncode(raw, sizeof(raw)) == target) { | 289 // if (base::HexEncode(raw, sizeof(raw)) == target) { |
211 // return input_str; | 290 // return input_str; |
212 // } | 291 // } |
213 // ++input[0]; | 292 // ++input[0]; |
214 // } | 293 // } |
215 // return ""; | 294 // return ""; |
216 // } | 295 // } |
217 | 296 |
218 } // namespace device | 297 } // namespace device |
OLD | NEW |