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 <stdint.h> | 5 #include <stdint.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
(...skipping 2275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 SimulateGattDisconnection(device_); | 2286 SimulateGattDisconnection(device_); |
2287 // Do not yet call RunUntilIdle() to process the disconnect task. | 2287 // Do not yet call RunUntilIdle() to process the disconnect task. |
2288 characteristic1_->ReadRemoteCharacteristic( | 2288 characteristic1_->ReadRemoteCharacteristic( |
2289 GetReadValueCallback(Call::NOT_EXPECTED), | 2289 GetReadValueCallback(Call::NOT_EXPECTED), |
2290 GetGattErrorCallback(Call::EXPECTED)); | 2290 GetGattErrorCallback(Call::EXPECTED)); |
2291 | 2291 |
2292 base::RunLoop().RunUntilIdle(); | 2292 base::RunLoop().RunUntilIdle(); |
2293 EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED, | 2293 EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED, |
2294 last_gatt_error_code_); | 2294 last_gatt_error_code_); |
2295 } | 2295 } |
2296 #endif | 2296 #endif // defined(OS_ANDROID) |
2297 | 2297 |
2298 #if defined(OS_ANDROID) | 2298 #if defined(OS_ANDROID) |
2299 // Tests that write requests after a device disconnects but before the | 2299 // Tests that write requests after a device disconnects but before the |
2300 // disconnect task runs result in an error. | 2300 // disconnect task runs result in an error. |
2301 // macOS: Does not apply. All events arrive on the UI Thread. | 2301 // macOS: Does not apply. All events arrive on the UI Thread. |
2302 // TODO(crbug.com/694102): Enable this test on Windows. | 2302 // TODO(crbug.com/694102): Enable this test on Windows. |
2303 TEST_F(BluetoothRemoteGattCharacteristicTest, WriteDuringDisconnect) { | 2303 TEST_F(BluetoothRemoteGattCharacteristicTest, WriteDuringDisconnect) { |
2304 if (!PlatformSupportsLowEnergy()) { | 2304 if (!PlatformSupportsLowEnergy()) { |
2305 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; | 2305 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
2306 return; | 2306 return; |
2307 } | 2307 } |
2308 ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate( | 2308 ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate( |
2309 BluetoothRemoteGattCharacteristic::PROPERTY_WRITE)); | 2309 BluetoothRemoteGattCharacteristic::PROPERTY_WRITE)); |
2310 | 2310 |
2311 SimulateGattDisconnection(device_); | 2311 SimulateGattDisconnection(device_); |
2312 // Do not yet call RunUntilIdle() to process the disconnect task. | 2312 // Do not yet call RunUntilIdle() to process the disconnect task. |
2313 characteristic1_->WriteRemoteCharacteristic( | 2313 characteristic1_->WriteRemoteCharacteristic( |
2314 std::vector<uint8_t>(), GetCallback(Call::NOT_EXPECTED), | 2314 std::vector<uint8_t>(), GetCallback(Call::NOT_EXPECTED), |
2315 GetGattErrorCallback(Call::EXPECTED)); | 2315 GetGattErrorCallback(Call::EXPECTED)); |
2316 | 2316 |
2317 base::RunLoop().RunUntilIdle(); | 2317 base::RunLoop().RunUntilIdle(); |
2318 EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED, | 2318 EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED, |
2319 last_gatt_error_code_); | 2319 last_gatt_error_code_); |
2320 } | 2320 } |
2321 #endif | 2321 #endif // defined(OS_ANDROID) |
2322 | 2322 |
2323 #if defined(OS_ANDROID) | 2323 #if defined(OS_ANDROID) |
2324 // Tests that start notifications requests after a device disconnects but before | 2324 // Tests that start notifications requests after a device disconnects but before |
2325 // the disconnect task runs result in an error. | 2325 // the disconnect task runs result in an error. |
2326 // macOS: Does not apply. All events arrive on the UI Thread. | 2326 // macOS: Does not apply. All events arrive on the UI Thread. |
2327 // TODO(crbug.com/694102): Enable this test on Windows. | 2327 // TODO(crbug.com/694102): Enable this test on Windows. |
2328 TEST_F(BluetoothRemoteGattCharacteristicTest, | 2328 TEST_F(BluetoothRemoteGattCharacteristicTest, |
2329 StartNotifySessionDuringDisconnect) { | 2329 StartNotifySessionDuringDisconnect) { |
2330 if (!PlatformSupportsLowEnergy()) { | 2330 if (!PlatformSupportsLowEnergy()) { |
2331 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; | 2331 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
2332 return; | 2332 return; |
2333 } | 2333 } |
2334 ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate( | 2334 ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate( |
2335 BluetoothRemoteGattCharacteristic::PROPERTY_NOTIFY)); | 2335 BluetoothRemoteGattCharacteristic::PROPERTY_NOTIFY)); |
2336 SimulateGattDescriptor( | 2336 SimulateGattDescriptor( |
2337 characteristic1_, | 2337 characteristic1_, |
2338 BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() | 2338 BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
2339 .canonical_value()); | 2339 .canonical_value()); |
2340 | 2340 |
2341 SimulateGattDisconnection(device_); | 2341 SimulateGattDisconnection(device_); |
2342 // Don't run the disconnect task. | 2342 // Don't run the disconnect task. |
2343 characteristic1_->StartNotifySession(GetNotifyCallback(Call::NOT_EXPECTED), | 2343 characteristic1_->StartNotifySession(GetNotifyCallback(Call::NOT_EXPECTED), |
2344 GetGattErrorCallback(Call::EXPECTED)); | 2344 GetGattErrorCallback(Call::EXPECTED)); |
2345 | 2345 |
2346 base::RunLoop().RunUntilIdle(); | 2346 base::RunLoop().RunUntilIdle(); |
2347 EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED, | 2347 EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED, |
2348 last_gatt_error_code_); | 2348 last_gatt_error_code_); |
2349 } | 2349 } |
2350 #endif | 2350 #endif // defined(OS_ANDROID) |
2351 | 2351 |
2352 #if defined(OS_ANDROID) | 2352 #if defined(OS_ANDROID) |
2353 // Tests that stop notifications requests after a device disconnects but before | 2353 // Tests that stop notifications requests after a device disconnects but before |
2354 // the disconnect task runs do not result in a crash. | 2354 // the disconnect task runs do not result in a crash. |
2355 // macOS: Does not apply. All events arrive on the UI Thread. | 2355 // macOS: Does not apply. All events arrive on the UI Thread. |
2356 // TODO(crbug.com/694102): Enable this test on Windows. | 2356 // TODO(crbug.com/694102): Enable this test on Windows. |
2357 TEST_F(BluetoothRemoteGattCharacteristicTest, | 2357 TEST_F(BluetoothRemoteGattCharacteristicTest, |
2358 StopNotifySessionDuringDisconnect) { | 2358 StopNotifySessionDuringDisconnect) { |
2359 if (!PlatformSupportsLowEnergy()) { | 2359 if (!PlatformSupportsLowEnergy()) { |
2360 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; | 2360 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
2361 return; | 2361 return; |
2362 } | 2362 } |
2363 ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( | 2363 ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
2364 /* properties: NOTIFY */ 0x10, NotifyValueState::NOTIFY)); | 2364 /* properties: NOTIFY */ 0x10, NotifyValueState::NOTIFY)); |
2365 | 2365 |
2366 SimulateGattDisconnection(device_); | 2366 SimulateGattDisconnection(device_); |
2367 // Don't run the disconnect task. | 2367 // Don't run the disconnect task. |
2368 notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); | 2368 notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
2369 base::RunLoop().RunUntilIdle(); | 2369 base::RunLoop().RunUntilIdle(); |
2370 } | 2370 } |
2371 #endif | 2371 #endif // defined(OS_ANDROID) |
2372 | 2372 |
2373 #if defined(OS_ANDROID) | 2373 #if defined(OS_ANDROID) |
2374 // Tests that deleting notify sessions after a device disconnects but before the | 2374 // Tests that deleting notify sessions after a device disconnects but before the |
2375 // disconnect task runs do not result in a crash. | 2375 // disconnect task runs do not result in a crash. |
2376 // macOS: Does not apply. All events arrive on the UI Thread. | 2376 // macOS: Does not apply. All events arrive on the UI Thread. |
2377 // TODO(crbug.com/694102): Enable this test on Windows. | 2377 // TODO(crbug.com/694102): Enable this test on Windows. |
2378 TEST_F(BluetoothRemoteGattCharacteristicTest, | 2378 TEST_F(BluetoothRemoteGattCharacteristicTest, |
2379 DeleteNotifySessionDuringDisconnect) { | 2379 DeleteNotifySessionDuringDisconnect) { |
2380 if (!PlatformSupportsLowEnergy()) { | 2380 if (!PlatformSupportsLowEnergy()) { |
2381 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; | 2381 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
2382 return; | 2382 return; |
2383 } | 2383 } |
2384 ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( | 2384 ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
2385 /* properties: NOTIFY */ 0x10, NotifyValueState::NOTIFY)); | 2385 /* properties: NOTIFY */ 0x10, NotifyValueState::NOTIFY)); |
2386 | 2386 |
2387 SimulateGattDisconnection(device_); | 2387 SimulateGattDisconnection(device_); |
2388 // Don't run the disconnect task. | 2388 // Don't run the disconnect task. |
2389 notify_sessions_.clear(); | 2389 notify_sessions_.clear(); |
2390 base::RunLoop().RunUntilIdle(); | 2390 base::RunLoop().RunUntilIdle(); |
2391 } | 2391 } |
2392 #endif | 2392 #endif // defined(OS_ANDROID) |
| 2393 |
| 2394 #if defined(OS_MACOSX) |
| 2395 // Tests to receive a services changed notification from macOS, while |
| 2396 // discovering descriptors. This test simulate having 2 descriptor scan at the |
| 2397 // same time. Only once both descriptor scanning is done, the gatt device is |
| 2398 // ready. |
| 2399 // Android: This test doesn't apply to Android because there is no services |
| 2400 // changed event that could arrive during a discovery procedure. |
| 2401 TEST_F(BluetoothRemoteGattCharacteristicTest, |
| 2402 SimulateDeviceModificationWhileDiscoveringDescriptors) { |
| 2403 if (!PlatformSupportsLowEnergy()) { |
| 2404 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
| 2405 return; |
| 2406 } |
| 2407 InitWithFakeAdapter(); |
| 2408 StartLowEnergyDiscoverySession(); |
| 2409 BluetoothDevice* device = SimulateLowEnergyDevice(3); |
| 2410 device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED), |
| 2411 GetConnectErrorCallback(Call::NOT_EXPECTED)); |
| 2412 |
| 2413 TestBluetoothAdapterObserver observer(adapter_); |
| 2414 |
| 2415 // Starts first discovery process. |
| 2416 SimulateGattConnection(device); |
| 2417 EXPECT_EQ(1, observer.device_changed_count()); |
| 2418 AddServicesToDevice(device, {kTestUUIDHeartRate}); |
| 2419 SimulateDidDiscoverServicesMac(device); |
| 2420 EXPECT_EQ(1u, device->GetGattServices().size()); |
| 2421 BluetoothRemoteGattService* service = device->GetGattServices()[0]; |
| 2422 std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb"; |
| 2423 AddCharacteristicToService(service, characteristic_uuid, /* properties */ 0); |
| 2424 SimulateDidDiscoverCharacteristicsMac(service); |
| 2425 EXPECT_EQ(1u, service->GetCharacteristics().size()); |
| 2426 BluetoothRemoteGattCharacteristic* characteristic = |
| 2427 service->GetCharacteristics()[0]; |
| 2428 std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb"; |
| 2429 AddDescriptorToCharacteristic(characteristic, descriptor_uuid); |
| 2430 // Now waiting for descriptor discovery. |
| 2431 |
| 2432 // Starts second discovery process. |
| 2433 SimulateGattServicesChanged(device); |
| 2434 EXPECT_EQ(2, observer.device_changed_count()); |
| 2435 SimulateDidDiscoverServicesMac(device); |
| 2436 SimulateDidDiscoverCharacteristicsMac(service); |
| 2437 // Now waiting for a second descriptor discovery. |
| 2438 |
| 2439 // Finish discovery process. |
| 2440 // First system call to -[id<CBPeripheralDelegate> |
| 2441 // peripheral:didDiscoverDescriptorsForCharacteristic:error:] |
| 2442 SimulateDidDiscoverDescriptorsMac(characteristic); |
| 2443 EXPECT_EQ(0, observer.gatt_service_changed_count()); |
| 2444 EXPECT_EQ(1u, service->GetCharacteristics().size()); |
| 2445 EXPECT_EQ(1u, characteristic->GetDescriptors().size()); |
| 2446 EXPECT_EQ(2, observer.device_changed_count()); |
| 2447 |
| 2448 // Second system call to -[id<CBPeripheralDelegate> |
| 2449 // peripheral:didDiscoverDescriptorsForCharacteristic:error:] |
| 2450 // Finish second discovery process. |
| 2451 observer.Reset(); |
| 2452 SimulateDidDiscoverDescriptorsMac(characteristic); |
| 2453 EXPECT_EQ(1, observer.gatt_service_changed_count()); |
| 2454 EXPECT_EQ(1, observer.device_changed_count()); |
| 2455 } |
| 2456 #endif // defined(OS_MACOSX) |
| 2457 |
| 2458 #if defined(OS_MACOSX) |
| 2459 // Simulates to receive an extra discovery descriptor notifications from macOS. |
| 2460 // Those notifications should be ignored. |
| 2461 // Android: This test doesn't apply to Android because there is no services |
| 2462 // changed event that could arrive during a discovery procedure. |
| 2463 TEST_F(BluetoothRemoteGattCharacteristicTest, ExtraDidDiscoverDescriptorsCall) { |
| 2464 if (!PlatformSupportsLowEnergy()) { |
| 2465 LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
| 2466 return; |
| 2467 } |
| 2468 InitWithFakeAdapter(); |
| 2469 StartLowEnergyDiscoverySession(); |
| 2470 BluetoothDevice* device = SimulateLowEnergyDevice(3); |
| 2471 device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED), |
| 2472 GetConnectErrorCallback(Call::NOT_EXPECTED)); |
| 2473 |
| 2474 TestBluetoothAdapterObserver observer(adapter_); |
| 2475 |
| 2476 // Starts first discovery process. |
| 2477 SimulateGattConnection(device); |
| 2478 AddServicesToDevice(device, {kTestUUIDHeartRate}); |
| 2479 SimulateDidDiscoverServicesMac(device); |
| 2480 EXPECT_EQ(1u, device->GetGattServices().size()); |
| 2481 BluetoothRemoteGattService* service = device->GetGattServices()[0]; |
| 2482 std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb"; |
| 2483 AddCharacteristicToService(service, characteristic_uuid, /* properties */ 0); |
| 2484 SimulateDidDiscoverCharacteristicsMac(service); |
| 2485 EXPECT_EQ(1u, service->GetCharacteristics().size()); |
| 2486 BluetoothRemoteGattCharacteristic* characteristic = |
| 2487 service->GetCharacteristics()[0]; |
| 2488 std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb"; |
| 2489 AddDescriptorToCharacteristic(characteristic, descriptor_uuid); |
| 2490 SimulateDidDiscoverDescriptorsMac(characteristic); |
| 2491 EXPECT_EQ(1, observer.gatt_service_changed_count()); |
| 2492 EXPECT_EQ(1u, service->GetCharacteristics().size()); |
| 2493 EXPECT_EQ(1u, characteristic->GetDescriptors().size()); |
| 2494 |
| 2495 observer.Reset(); |
| 2496 SimulateDidDiscoverDescriptorsMac(characteristic); // Extra system call. |
| 2497 SimulateGattServicesChanged(device); |
| 2498 SimulateDidDiscoverDescriptorsMac(characteristic); // Extra system call. |
| 2499 SimulateDidDiscoverServicesMac(device); |
| 2500 SimulateDidDiscoverDescriptorsMac(characteristic); // Extra system call. |
| 2501 SimulateDidDiscoverCharacteristicsMac(service); |
| 2502 SimulateDidDiscoverDescriptorsMac(characteristic); |
| 2503 SimulateDidDiscoverDescriptorsMac(characteristic); // Extra system call. |
| 2504 EXPECT_EQ(2, observer.device_changed_count()); |
| 2505 } |
| 2506 #endif // defined(OS_MACOSX) |
2393 } // namespace device | 2507 } // namespace device |
OLD | NEW |