Index: device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc |
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc |
index ec0310b5f65f3fb7fcb3b19e43c7419929d09ece..553618e3f3d1956a67c996c3434804101e8ea85e 100644 |
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc |
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc |
@@ -1022,7 +1022,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, |
#endif // defined(OS_ANDROID) |
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) |
-// Tests StartNotifySession success on a characteristic enabling Notify. |
+// Tests StartNotifySession success on a characteristic that enabled Notify. |
TEST_F(BluetoothRemoteGattCharacteristicTest, StartNotifySession) { |
if (!PlatformSupportsLowEnergy()) { |
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
@@ -1035,7 +1035,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, StartNotifySession) { |
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) |
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) |
-// Tests StartNotifySession success on a characteristic enabling Indicate. |
+// Tests StartNotifySession success on a characteristic that enabled Indicate. |
TEST_F(BluetoothRemoteGattCharacteristicTest, StartNotifySession_OnIndicate) { |
if (!PlatformSupportsLowEnergy()) { |
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; |
@@ -1048,7 +1048,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, StartNotifySession_OnIndicate) { |
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) |
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) |
-// Tests StartNotifySession success on a characteristic enabling Notify & |
+// Tests StartNotifySession success on a characteristic that enabled Notify & |
// Indicate. |
TEST_F(BluetoothRemoteGattCharacteristicTest, |
StartNotifySession_OnNotifyAndIndicate) { |
@@ -1088,6 +1088,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, StartNotifySession_Multiple) { |
GetGattErrorCallback(Call::NOT_EXPECTED)); |
EXPECT_EQ(0, callback_count_); |
SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
EXPECT_EQ(1, gatt_notify_characteristic_attempts_); |
EXPECT_EQ(2, callback_count_); |
EXPECT_EQ(0, error_callback_count_); |
@@ -1130,6 +1131,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, |
EXPECT_EQ(0, callback_count_); |
SimulateGattNotifySessionStartError( |
characteristic1_, BluetoothRemoteGattService::GATT_ERROR_FAILED); |
+ base::RunLoop().RunUntilIdle(); |
EXPECT_EQ(0, callback_count_); |
EXPECT_EQ(2, error_callback_count_); |
ASSERT_EQ(0u, notify_sessions_.size()); |
@@ -1169,6 +1171,45 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, StartNotifySession_AfterDeleted) { |
} |
#endif // defined(OS_ANDROID) |
+#if defined(OS_ANDROID) |
+// Tests StartNotifySession completing before chrome objects are deleted. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StartNotifySession_BeforeDeleted) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+ |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCallback(Call::EXPECTED), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ EXPECT_EQ(1, gatt_notify_characteristic_attempts_); |
+ EXPECT_EQ(0, callback_count_); |
+ |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ ASSERT_EQ(1u, notify_sessions_.size()); |
+ |
+ std::string characteristic_identifier = characteristic1_->GetIdentifier(); |
+ |
+ EXPECT_EQ(characteristic_identifier, |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ |
+ DeleteDevice(device_); // TODO(576906) delete only the characteristic. |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_TRUE("Did not crash!"); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_EQ(characteristic_identifier, |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
#if defined(OS_MACOSX) || defined(OS_WIN) |
// Tests StartNotifySession reentrant in start notify session success callback |
// and the reentrant start notify session success. |
@@ -1287,6 +1328,604 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, |
} |
#endif // defined(OS_WIN) |
+#if defined(OS_ANDROID) |
+// Tests StopNotifySession success on a characteristic that enabled Notify. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ EXPECT_EQ(1, gatt_write_descriptor_attempts_); |
+ |
+ notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the right values were written to the descriptor. |
+ EXPECT_EQ(2, gatt_write_descriptor_attempts_); |
+ ASSERT_EQ(2u, last_write_value_.size()); |
+ EXPECT_EQ(0, last_write_value_[0]); |
+ EXPECT_EQ(0, last_write_value_[1]); |
+ |
+ // Check that the notify session is inactive. |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests that deleted sessions are stopped. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_SessionDeleted) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ EXPECT_EQ(1, gatt_write_descriptor_attempts_); |
+ |
+ notify_sessions_.clear(); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the right values were written to the descriptor. |
+ EXPECT_EQ(2, gatt_write_descriptor_attempts_); |
+ ASSERT_EQ(2u, last_write_value_.size()); |
+ EXPECT_EQ(0, last_write_value_[0]); |
+ EXPECT_EQ(0, last_write_value_[1]); |
+ |
+ // Check that the notify session is inactive. |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests that deleting the sessions before the stop callbacks have been |
+// invoked does not cause problems. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_SessionDeleted2) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ |
+#if !defined(OS_MACOSX) |
+ // TODO(624017) enable for macosx |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+#endif |
+ |
+ // Start notify sessions. |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(0), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(1), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ EXPECT_EQ(0, callback_count_); |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(1, gatt_notify_characteristic_attempts_); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ ASSERT_EQ(2u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ ASSERT_TRUE(notify_sessions_[1]); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[1]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_TRUE(notify_sessions_[1]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ // Queue up stop events. |
+ notify_sessions_[1]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ |
+ // Delete the notify sessions. |
+ notify_sessions_.clear(); |
+ |
+ // Run the stop events. |
+ base::RunLoop().RunUntilIdle(); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the state is correct. |
+ EXPECT_TRUE("Did not crash!"); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests that deleted sessions are stopped. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_AfterDeleted) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ |
+ // Check that the session is correctly setup |
+ std::string characteristic_identifier = characteristic1_->GetIdentifier(); |
+ EXPECT_EQ(characteristic_identifier, |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ |
+ DeleteDevice(device_); // TODO(576906) delete only the characteristic. |
+ |
+ ResetEventCounts(); |
+ notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ |
+ // Check that the callback does not arrive synchronously. |
+ EXPECT_EQ(0, callback_count_); |
+ |
+ // Trigger the stop callback |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(1, callback_count_); |
+ |
+ EXPECT_TRUE("Did not crash!"); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_EQ(characteristic_identifier, |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests StopNotifySession success on a characteristic that enabled Indicate. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_OnIndicate) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: INDICATE */ 0x20, |
+ /* expected_config_descriptor_value: INDICATE */ 2)); |
+ EXPECT_EQ(1, gatt_write_descriptor_attempts_); |
+ |
+ notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the right values were written to the descriptor. |
+ EXPECT_EQ(2, gatt_write_descriptor_attempts_); |
+ ASSERT_EQ(2u, last_write_value_.size()); |
+ EXPECT_EQ(0, last_write_value_[0]); |
+ EXPECT_EQ(0, last_write_value_[1]); |
+ |
+ // Check that the notify session is inactive. |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests StopNotifySession success on a characteristic that enabled Notify & |
+// Indicate. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_OnNotifyAndIndicate) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY and INDICATE bits set */ 0x30, |
+ /* expected_config_descriptor_value: INDICATE */ 1)); |
+ EXPECT_EQ(1, gatt_write_descriptor_attempts_); |
+ |
+ notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the right values were written to the descriptor. |
+ EXPECT_EQ(2, gatt_write_descriptor_attempts_); |
+ ASSERT_EQ(2u, last_write_value_.size()); |
+ EXPECT_EQ(0, last_write_value_[0]); |
+ EXPECT_EQ(0, last_write_value_[1]); |
+ |
+ // Check that the notify session is inactive. |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests StopNotifySession error |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_Error) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ |
+ // Check that the notify session is active. |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ notify_sessions_[0]->Stop(GetStopNotifyCallback(Call::EXPECTED)); |
+ SimulateGattNotifySessionStopError( |
+ characteristic1_, BluetoothRemoteGattService::GATT_ERROR_UNKNOWN); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the notify session is inactive. |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests multiple StopNotifySession calls for a single session. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_Multiple1) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ |
+#if !defined(OS_MACOSX) |
+ // TODO(624017) enable for macosx |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+#endif |
+ |
+ // Start notify session |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCallback(Call::EXPECTED), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ EXPECT_EQ(0, callback_count_); |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(1, gatt_notify_characteristic_attempts_); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ ASSERT_EQ(1u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ // Stop the notify session twice |
+ ResetEventCounts(); |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(0)); |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(1)); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the notify session is inactive. |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests multiple StartNotifySession calls and multiple StopNotifySession calls. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_Multiple2) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ |
+#if !defined(OS_MACOSX) |
+ // TODO(624017) enable for macosx |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+#endif |
+ |
+ // Start notify sessions |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(0), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(1), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ EXPECT_EQ(0, callback_count_); |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(1, gatt_notify_characteristic_attempts_); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ ASSERT_EQ(2u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ ASSERT_TRUE(notify_sessions_[1]); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[1]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_TRUE(notify_sessions_[1]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ // Stop the notify sessions |
+ notify_sessions_[1]->Stop(GetStopNotifyCheckForPrecedingCalls(2)); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(notify_sessions_[1]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(3)); |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the notify sessions is inactive. |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(notify_sessions_[1]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+// Tests starting a new notify session before the previous stop request |
+// resolves. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_StopStart) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+ |
+ // Start notify session |
+ ResetEventCounts(); |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(0), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(1u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ |
+ // Stop the notify session |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(1)); |
+ |
+ // Start another notify session |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(2), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(2u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ ASSERT_TRUE(notify_sessions_[1]); |
+ EXPECT_TRUE(notify_sessions_[1]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_StartStopStart) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ |
+ // Check that the initial notify session is active. |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ // Queue up the first event. |
+ ResetEventCounts(); |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(0), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ |
+ // Queue up the second event. |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(1)); |
+ |
+ // Queue up the third event. |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(2), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ |
+ // Run the event loop to resolve all three events. |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check the state of all the sessions. |
+ ASSERT_EQ(3u, notify_sessions_.size()); |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[1]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[1]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[1]->IsActive()); |
+ |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[2]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[2]->GetCharacteristic()); |
+ EXPECT_TRUE(notify_sessions_[2]->IsActive()); |
+ |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+} |
+#endif |
+ |
+#if defined(OS_ANDROID) |
+// Tests starting a new notify session before the previous stop requests |
+// resolve. |
+TEST_F(BluetoothRemoteGattCharacteristicTest, StopNotifySession_StopStopStart) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+ |
+ // Start notify session |
+ ResetEventCounts(); |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(0), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(1u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_EQ(1, gatt_write_descriptor_attempts_); |
+ |
+ // Stop the notify session twice |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(1)); |
+ notify_sessions_[0]->Stop(GetStopNotifyCheckForPrecedingCalls(2)); |
+ |
+ // Check that the right values were written to the descriptor. |
+ EXPECT_EQ(2, gatt_write_descriptor_attempts_); |
+ ASSERT_EQ(2u, last_write_value_.size()); |
+ EXPECT_EQ(0, last_write_value_[0]); |
+ EXPECT_EQ(0, last_write_value_[1]); |
+ |
+ // Start another notify session |
+ characteristic1_->StartNotifySession( |
+ GetNotifyCheckForPrecedingCalls(3), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ |
+ // Check that nothing was written by the StartNotifySession call above |
+ EXPECT_EQ(2, gatt_write_descriptor_attempts_); |
+ |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Check that the right values were written to the descriptor. |
+ EXPECT_EQ(3, gatt_write_descriptor_attempts_); |
+ ASSERT_EQ(2u, last_write_value_.size()); |
+ EXPECT_EQ(1, last_write_value_[0]); |
+ EXPECT_EQ(0, last_write_value_[1]); |
+ |
+ // Check the notify state |
+ ASSERT_EQ(2u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ ASSERT_TRUE(notify_sessions_[1]); |
+ EXPECT_TRUE(notify_sessions_[1]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+} |
+#endif // defined(OS_ANDROID) |
+ |
+#if defined(OS_ANDROID) |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_Reentrant_Success_Stop) { |
+ ASSERT_NO_FATAL_FAILURE( |
+ FakeCharacteristicBoilerplate(/* properties: NOTIFY */ 0x10)); |
+ SimulateGattDescriptor( |
+ characteristic1_, |
+ BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid() |
+ .canonical_value()); |
+ ASSERT_EQ(1u, characteristic1_->GetDescriptors().size()); |
+ |
+ // Start notify session |
+ characteristic1_->StartNotifySession( |
+ base::Bind( |
+ [](BluetoothRemoteGattCharacteristic::NotifySessionCallback |
+ notifyCallback, |
+ base::Closure stopNotifyCallback, |
+ std::unique_ptr<BluetoothGattNotifySession> session) { |
+ BluetoothGattNotifySession* s = session.get(); |
+ notifyCallback.Run(std::move(session)); |
+ s->Stop(stopNotifyCallback); |
+ }, |
+ GetNotifyCallback(Call::EXPECTED), |
+ GetStopNotifyCallback(Call::EXPECTED)), |
+ GetGattErrorCallback(Call::NOT_EXPECTED)); |
+ |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(1u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif |
+ |
+#if defined(OS_ANDROID) |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_Reentrant_Stop_StartSuccess) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ |
+ // Check that the notify session is active. |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ notify_sessions_[0]->Stop(base::Bind( |
+ [](BluetoothRemoteGattCharacteristic* characteristic, |
+ BluetoothRemoteGattCharacteristic::NotifySessionCallback |
+ notifyCallback, |
+ BluetoothRemoteGattCharacteristic::ErrorCallback errorCallback) { |
+ characteristic->StartNotifySession(notifyCallback, errorCallback); |
+ }, |
+ characteristic1_, GetNotifyCallback(Call::EXPECTED), |
+ GetGattErrorCallback(Call::NOT_EXPECTED))); |
+ |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+ |
+ SimulateGattNotifySessionStarted(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(2u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ ASSERT_TRUE(notify_sessions_[1]); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[1]->GetCharacteristic()); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_TRUE(notify_sessions_[1]->IsActive()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+} |
+#endif |
+ |
+#if defined(OS_ANDROID) |
+TEST_F(BluetoothRemoteGattCharacteristicTest, |
+ StopNotifySession_Reentrant_Stop_StartError) { |
+ ASSERT_NO_FATAL_FAILURE(StartNotifyBoilerplate( |
+ /* properties: NOTIFY */ 0x10, |
+ /* expected_config_descriptor_value: NOTIFY */ 1)); |
+ |
+ // Check that the notify session is active. |
+ EXPECT_TRUE(notify_sessions_[0]->IsActive()); |
+ EXPECT_EQ(characteristic1_->GetIdentifier(), |
+ notify_sessions_[0]->GetCharacteristicIdentifier()); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_TRUE(characteristic1_->IsNotifying()); |
+ |
+ notify_sessions_[0]->Stop(base::Bind( |
+ [](BluetoothRemoteGattCharacteristic* characteristic, |
+ BluetoothRemoteGattCharacteristic::NotifySessionCallback |
+ notifyCallback, |
+ BluetoothRemoteGattCharacteristic::ErrorCallback errorCallback) { |
+ characteristic->StartNotifySession(notifyCallback, errorCallback); |
+ }, |
+ characteristic1_, GetNotifyCallback(Call::NOT_EXPECTED), |
+ GetGattErrorCallback(Call::EXPECTED))); |
+ |
+ SimulateGattNotifySessionStopped(characteristic1_); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+ |
+ SimulateGattNotifySessionStartError( |
+ characteristic1_, BluetoothRemoteGattService::GATT_ERROR_FAILED); |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(1u, notify_sessions_.size()); |
+ ASSERT_TRUE(notify_sessions_[0]); |
+ EXPECT_EQ(characteristic1_, notify_sessions_[0]->GetCharacteristic()); |
+ EXPECT_FALSE(notify_sessions_[0]->IsActive()); |
+ EXPECT_FALSE(characteristic1_->IsNotifying()); |
+} |
+#endif |
+ |
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) |
// Tests Characteristic Value changes during a Notify Session. |
TEST_F(BluetoothRemoteGattCharacteristicTest, GattCharacteristicValueChanged) { |