Loading system/bta/le_audio/client.cc +107 −54 Original line number Diff line number Diff line Loading @@ -1105,10 +1105,37 @@ class LeAudioClientImpl : public LeAudioClient { return; } if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) { LOG_INFO("%s, state: %s", ADDRESS_TO_LOGGABLE_CSTR(address), bluetooth::common::ToString(leAudioDevice->GetConnectionState()) .c_str()); auto connection_state = leAudioDevice->GetConnectionState(); switch (connection_state) { case DeviceConnectState::REMOVING: case DeviceConnectState::PENDING_REMOVAL: /* Just return, and let device disconnect */ return; case DeviceConnectState::CONNECTED: case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY: case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY: /* ACL exist in this case, disconnect and mark as removing */ Disconnect(address); [[fallthrough]]; case DeviceConnectState::DISCONNECTING: /* Remove device from the background connect if it is there */ BTA_GATTC_CancelOpen(gatt_if_, address, false); /* Device is disconnecting, just mark it shall be removed after all. */ leAudioDevice->SetConnectionState(DeviceConnectState::REMOVING); return; case DeviceConnectState::CONNECTING_BY_USER: BTA_GATTC_CancelOpen(gatt_if_, address, true); [[fallthrough]]; case DeviceConnectState::CONNECTING_AUTOCONNECT: /* Cancel background conection */ BTA_GATTC_CancelOpen(gatt_if_, address, false); break; case DeviceConnectState::DISCONNECTED: /* Do nothing, just remove device */ break; } /* Remove the group assignment if not yet removed. It might happen that the Loading Loading @@ -1267,24 +1294,27 @@ class LeAudioClientImpl : public LeAudioClient { return SerializeAses(leAudioDevice, out); } void BackgroundConnectIfGroupConnected(LeAudioDevice* leAudioDevice) { void BackgroundConnectIfNeeded(LeAudioDevice* leAudioDevice) { DLOG(INFO) << __func__ << ADDRESS_TO_LOGGABLE_STR(leAudioDevice->address_); auto group = aseGroups_.FindById(leAudioDevice->group_id_); if (!group) { DLOG(INFO) << __func__ << " Device is not yet part of the group. "; LOG_INFO(" Device %s is not yet part of the group %d. ", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), leAudioDevice->group_id_); return; } if (!group->IsAnyDeviceConnected()) { DLOG(INFO) << __func__ << " group: " << leAudioDevice->group_id_ << " is not connected"; if (!leAudioDevice->autoconnect_flag_ && !group->IsAnyDeviceConnected()) { LOG_DEBUG("Device %s not in the background connect", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_)); return; } DLOG(INFO) << __func__ << " Add " << ADDRESS_TO_LOGGABLE_STR(leAudioDevice->address_) << " to background connect to connected group: " << leAudioDevice->group_id_; LOG_INFO( "Add %s added to background connect. autoconnect flag: %d " "group_connected: %d", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), leAudioDevice->group_id_, group->IsAnyDeviceConnected()); leAudioDevice->SetConnectionState( DeviceConnectState::CONNECTING_AUTOCONNECT); Loading @@ -1302,28 +1332,31 @@ class LeAudioClientImpl : public LeAudioClient { return; } /* cancel pending direct connect */ if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTING_BY_USER) { BTA_GATTC_CancelOpen(gatt_if_, address, true); } /* Removes all registrations for connection */ BTA_GATTC_CancelOpen(0, address, false); auto connection_state = leAudioDevice->GetConnectionState(); LOG_INFO("%s, state: %s", ADDRESS_TO_LOGGABLE_CSTR(address), bluetooth::common::ToString(connection_state).c_str()); if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) { switch (connection_state) { case DeviceConnectState::CONNECTING_BY_USER: /* Timeout happen on the Java layer. Device probably not in the range. * Cancel just direct connection and keep background if it is there. */ BTA_GATTC_CancelOpen(gatt_if_, address, true); break; case DeviceConnectState::CONNECTED: { /* User is disconnecting the device, we shall remove the autoconnect * flag for this device and all others */ LOG_INFO("Removing autoconnect flag for group_id %d", leAudioDevice->group_id_); auto group = aseGroups_.FindById(leAudioDevice->group_id_); if (leAudioDevice->autoconnect_flag_) { /* Removes device from background connect */ BTA_GATTC_CancelOpen(gatt_if_, address, false); btif_storage_set_leaudio_autoconnect(address, false); leAudioDevice->autoconnect_flag_ = false; } auto group = aseGroups_.FindById(leAudioDevice->group_id_); if (group) { /* Remove devices from auto connect mode */ Loading @@ -1346,14 +1379,34 @@ class LeAudioClientImpl : public LeAudioClient { groupStateMachine_->StopStream(group); return; } } [[fallthrough]]; case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY: /* Timeout happen on the Java layer before native got ready with the * device */ DisconnectDevice(leAudioDevice); return; case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY: /* Java is not aware about autoconnect actions, * therefore this should not happen. */ LOG_WARN("Should not happen - disconnect device"); DisconnectDevice(leAudioDevice); return; case DeviceConnectState::DISCONNECTED: case DeviceConnectState::DISCONNECTING: case DeviceConnectState::CONNECTING_AUTOCONNECT: case DeviceConnectState::PENDING_REMOVAL: case DeviceConnectState::REMOVING: LOG_WARN("%s, invalid state %s", ADDRESS_TO_LOGGABLE_CSTR(address), bluetooth::common::ToString(connection_state).c_str()); break; } /* If this is a device which is a part of the group which is connected, * lets start backgroup connect */ BackgroundConnectIfGroupConnected(leAudioDevice); BackgroundConnectIfNeeded(leAudioDevice); } void DisconnectDevice(LeAudioDevice* leAudioDevice, Loading system/bta/le_audio/devices.cc +1 −1 Original line number Diff line number Diff line Loading @@ -2157,7 +2157,7 @@ void LeAudioDeviceGroup::Dump(int fd, int active_group_id) { /* LeAudioDevice Class methods implementation */ void LeAudioDevice::SetConnectionState(DeviceConnectState state) { LOG_DEBUG(" %s --> %s", LOG_DEBUG("%s, %s --> %s", ADDRESS_TO_LOGGABLE_CSTR(address_), bluetooth::common::ToString(connection_state_).c_str(), bluetooth::common::ToString(state).c_str()); connection_state_ = state; Loading system/bta/le_audio/le_audio_client_test.cc +212 −1 Original line number Diff line number Diff line Loading @@ -2266,7 +2266,7 @@ class UnicastTestNoInit : public Test { gatt::MockBtaGattQueue mock_gatt_queue_; tBTA_GATTC_CBACK* gatt_callback; const uint8_t gatt_if = 0xfe; uint8_t global_conn_id = 1; uint16_t global_conn_id = 1; le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_; std::map<int, LeAudioDeviceGroup*> streaming_groups; Loading Loading @@ -3164,6 +3164,217 @@ TEST_F(UnicastTest, RemoveTwoEarbudsCsisGrouped) { Mock::VerifyAndClearExpectations(&mock_btif_storage_); } TEST_F(UnicastTest, RemoveDeviceWhenConnected) { const RawAddress test_address0 = GetTestAddress(0); int group_id = bluetooth::groups::kGroupUnknown; uint16_t conn_id = 1; SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED)) .WillOnce(DoAll(SaveArg<1>(&group_id))); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) .Times(1); ConnectLeAudio(test_address0); ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)) .Times(1); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); LeAudioClient::Get()->RemoveDevice(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_gatt_queue_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, RemoveDeviceWhenConnecting) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = 1; /* Prepare mock to not inject connect event so the device can stay in * CONNECTING state*/ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)) .Times(1); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)) .Times(1); LeAudioClient::Get()->RemoveDevice(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, RemoveDeviceWhenGettingConnectionReady) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = 1; /* Prepare mock to not inject Service Search Complete*/ ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)) .Times(1); LeAudioClient::Get()->RemoveDevice(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, DisconnectDeviceWhenConnected) { const RawAddress test_address0 = GetTestAddress(0); int group_id = bluetooth::groups::kGroupUnknown; uint16_t conn_id = 1; SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED)) .WillOnce(DoAll(SaveArg<1>(&group_id))); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) .Times(1); ConnectLeAudio(test_address0); ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)) .Times(1); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); LeAudioClient::Get()->Disconnect(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_gatt_queue_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, DisconnectDeviceWhenConnecting) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = 1; /* Prepare mock to not inject connect event so the device can stay in * CONNECTING state*/ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); /* Prepare on call mock on Close - to not trigger Inject Disconnection, as it * is done in default mock. */ ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return())); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)) .Times(1); LeAudioClient::Get()->Disconnect(test_address0); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, DisconnectDeviceWhenGettingConnectionReady) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = global_conn_id; /* Prepare mock to not inject Service Search Complete*/ ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)) .Times(0); LeAudioClient::Get()->Disconnect(test_address0); } TEST_F(UnicastTest, RemoveWhileStreaming) { const RawAddress test_address0 = GetTestAddress(0); int group_id = bluetooth::groups::kGroupUnknown; Loading Loading
system/bta/le_audio/client.cc +107 −54 Original line number Diff line number Diff line Loading @@ -1105,10 +1105,37 @@ class LeAudioClientImpl : public LeAudioClient { return; } if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) { LOG_INFO("%s, state: %s", ADDRESS_TO_LOGGABLE_CSTR(address), bluetooth::common::ToString(leAudioDevice->GetConnectionState()) .c_str()); auto connection_state = leAudioDevice->GetConnectionState(); switch (connection_state) { case DeviceConnectState::REMOVING: case DeviceConnectState::PENDING_REMOVAL: /* Just return, and let device disconnect */ return; case DeviceConnectState::CONNECTED: case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY: case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY: /* ACL exist in this case, disconnect and mark as removing */ Disconnect(address); [[fallthrough]]; case DeviceConnectState::DISCONNECTING: /* Remove device from the background connect if it is there */ BTA_GATTC_CancelOpen(gatt_if_, address, false); /* Device is disconnecting, just mark it shall be removed after all. */ leAudioDevice->SetConnectionState(DeviceConnectState::REMOVING); return; case DeviceConnectState::CONNECTING_BY_USER: BTA_GATTC_CancelOpen(gatt_if_, address, true); [[fallthrough]]; case DeviceConnectState::CONNECTING_AUTOCONNECT: /* Cancel background conection */ BTA_GATTC_CancelOpen(gatt_if_, address, false); break; case DeviceConnectState::DISCONNECTED: /* Do nothing, just remove device */ break; } /* Remove the group assignment if not yet removed. It might happen that the Loading Loading @@ -1267,24 +1294,27 @@ class LeAudioClientImpl : public LeAudioClient { return SerializeAses(leAudioDevice, out); } void BackgroundConnectIfGroupConnected(LeAudioDevice* leAudioDevice) { void BackgroundConnectIfNeeded(LeAudioDevice* leAudioDevice) { DLOG(INFO) << __func__ << ADDRESS_TO_LOGGABLE_STR(leAudioDevice->address_); auto group = aseGroups_.FindById(leAudioDevice->group_id_); if (!group) { DLOG(INFO) << __func__ << " Device is not yet part of the group. "; LOG_INFO(" Device %s is not yet part of the group %d. ", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), leAudioDevice->group_id_); return; } if (!group->IsAnyDeviceConnected()) { DLOG(INFO) << __func__ << " group: " << leAudioDevice->group_id_ << " is not connected"; if (!leAudioDevice->autoconnect_flag_ && !group->IsAnyDeviceConnected()) { LOG_DEBUG("Device %s not in the background connect", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_)); return; } DLOG(INFO) << __func__ << " Add " << ADDRESS_TO_LOGGABLE_STR(leAudioDevice->address_) << " to background connect to connected group: " << leAudioDevice->group_id_; LOG_INFO( "Add %s added to background connect. autoconnect flag: %d " "group_connected: %d", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), leAudioDevice->group_id_, group->IsAnyDeviceConnected()); leAudioDevice->SetConnectionState( DeviceConnectState::CONNECTING_AUTOCONNECT); Loading @@ -1302,28 +1332,31 @@ class LeAudioClientImpl : public LeAudioClient { return; } /* cancel pending direct connect */ if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTING_BY_USER) { BTA_GATTC_CancelOpen(gatt_if_, address, true); } /* Removes all registrations for connection */ BTA_GATTC_CancelOpen(0, address, false); auto connection_state = leAudioDevice->GetConnectionState(); LOG_INFO("%s, state: %s", ADDRESS_TO_LOGGABLE_CSTR(address), bluetooth::common::ToString(connection_state).c_str()); if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) { switch (connection_state) { case DeviceConnectState::CONNECTING_BY_USER: /* Timeout happen on the Java layer. Device probably not in the range. * Cancel just direct connection and keep background if it is there. */ BTA_GATTC_CancelOpen(gatt_if_, address, true); break; case DeviceConnectState::CONNECTED: { /* User is disconnecting the device, we shall remove the autoconnect * flag for this device and all others */ LOG_INFO("Removing autoconnect flag for group_id %d", leAudioDevice->group_id_); auto group = aseGroups_.FindById(leAudioDevice->group_id_); if (leAudioDevice->autoconnect_flag_) { /* Removes device from background connect */ BTA_GATTC_CancelOpen(gatt_if_, address, false); btif_storage_set_leaudio_autoconnect(address, false); leAudioDevice->autoconnect_flag_ = false; } auto group = aseGroups_.FindById(leAudioDevice->group_id_); if (group) { /* Remove devices from auto connect mode */ Loading @@ -1346,14 +1379,34 @@ class LeAudioClientImpl : public LeAudioClient { groupStateMachine_->StopStream(group); return; } } [[fallthrough]]; case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY: /* Timeout happen on the Java layer before native got ready with the * device */ DisconnectDevice(leAudioDevice); return; case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY: /* Java is not aware about autoconnect actions, * therefore this should not happen. */ LOG_WARN("Should not happen - disconnect device"); DisconnectDevice(leAudioDevice); return; case DeviceConnectState::DISCONNECTED: case DeviceConnectState::DISCONNECTING: case DeviceConnectState::CONNECTING_AUTOCONNECT: case DeviceConnectState::PENDING_REMOVAL: case DeviceConnectState::REMOVING: LOG_WARN("%s, invalid state %s", ADDRESS_TO_LOGGABLE_CSTR(address), bluetooth::common::ToString(connection_state).c_str()); break; } /* If this is a device which is a part of the group which is connected, * lets start backgroup connect */ BackgroundConnectIfGroupConnected(leAudioDevice); BackgroundConnectIfNeeded(leAudioDevice); } void DisconnectDevice(LeAudioDevice* leAudioDevice, Loading
system/bta/le_audio/devices.cc +1 −1 Original line number Diff line number Diff line Loading @@ -2157,7 +2157,7 @@ void LeAudioDeviceGroup::Dump(int fd, int active_group_id) { /* LeAudioDevice Class methods implementation */ void LeAudioDevice::SetConnectionState(DeviceConnectState state) { LOG_DEBUG(" %s --> %s", LOG_DEBUG("%s, %s --> %s", ADDRESS_TO_LOGGABLE_CSTR(address_), bluetooth::common::ToString(connection_state_).c_str(), bluetooth::common::ToString(state).c_str()); connection_state_ = state; Loading
system/bta/le_audio/le_audio_client_test.cc +212 −1 Original line number Diff line number Diff line Loading @@ -2266,7 +2266,7 @@ class UnicastTestNoInit : public Test { gatt::MockBtaGattQueue mock_gatt_queue_; tBTA_GATTC_CBACK* gatt_callback; const uint8_t gatt_if = 0xfe; uint8_t global_conn_id = 1; uint16_t global_conn_id = 1; le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_; std::map<int, LeAudioDeviceGroup*> streaming_groups; Loading Loading @@ -3164,6 +3164,217 @@ TEST_F(UnicastTest, RemoveTwoEarbudsCsisGrouped) { Mock::VerifyAndClearExpectations(&mock_btif_storage_); } TEST_F(UnicastTest, RemoveDeviceWhenConnected) { const RawAddress test_address0 = GetTestAddress(0); int group_id = bluetooth::groups::kGroupUnknown; uint16_t conn_id = 1; SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED)) .WillOnce(DoAll(SaveArg<1>(&group_id))); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) .Times(1); ConnectLeAudio(test_address0); ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)) .Times(1); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); LeAudioClient::Get()->RemoveDevice(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_gatt_queue_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, RemoveDeviceWhenConnecting) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = 1; /* Prepare mock to not inject connect event so the device can stay in * CONNECTING state*/ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)) .Times(1); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)) .Times(1); LeAudioClient::Get()->RemoveDevice(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, RemoveDeviceWhenGettingConnectionReady) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = 1; /* Prepare mock to not inject Service Search Complete*/ ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)) .Times(1); LeAudioClient::Get()->RemoveDevice(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, DisconnectDeviceWhenConnected) { const RawAddress test_address0 = GetTestAddress(0); int group_id = bluetooth::groups::kGroupUnknown; uint16_t conn_id = 1; SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED)) .WillOnce(DoAll(SaveArg<1>(&group_id))); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) .Times(1); ConnectLeAudio(test_address0); ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)) .Times(1); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); LeAudioClient::Get()->Disconnect(test_address0); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_btif_storage_); Mock::VerifyAndClearExpectations(&mock_gatt_queue_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, DisconnectDeviceWhenConnecting) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = 1; /* Prepare mock to not inject connect event so the device can stay in * CONNECTING state*/ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); /* Prepare on call mock on Close - to not trigger Inject Disconnection, as it * is done in default mock. */ ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return())); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)) .Times(1); LeAudioClient::Get()->Disconnect(test_address0); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } TEST_F(UnicastTest, DisconnectDeviceWhenGettingConnectionReady) { const RawAddress test_address0 = GetTestAddress(0); uint16_t conn_id = global_conn_id; /* Prepare mock to not inject Service Search Complete*/ ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)) .WillByDefault(DoAll(Return())); SetSampleDatabaseEarbudsValid( conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(0); ConnectLeAudio(test_address0); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1)); EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1); EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)) .Times(0); LeAudioClient::Get()->Disconnect(test_address0); } TEST_F(UnicastTest, RemoveWhileStreaming) { const RawAddress test_address0 = GetTestAddress(0); int group_id = bluetooth::groups::kGroupUnknown; Loading