Loading system/bta/le_audio/state_machine.cc +14 −2 Original line number Diff line number Diff line Loading @@ -623,14 +623,26 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return; } /* If group is in Idle and not transitioning, just update the current group /* If group is in Idle and not transitioning, update the current group * audio context availability which could change due to disconnected group * member. */ if ((group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) && !group->IsInTransition()) { LOG(INFO) << __func__ << " group: " << group->group_id_ << " is in IDLE"; LOG_INFO("group: %d is in IDLE", group->group_id_); group->UpdateAudioContextTypeAvailability(); /* When OnLeAudioDeviceSetStateTimeout happens, group will transition * to IDLE, and after that an ACL disconnect will be triggered. We need * to check if CIG is created and if it is, remove it so it can be created * again after reconnect. Otherwise we will get Command Disallowed on CIG * Create when starting stream. */ if (group->GetCigState() == CigState::CREATED) { LOG_INFO("CIG is in CREATED state so removing CIG for Group %d", group->group_id_); RemoveCigForGroup(group); } return; } Loading system/bta/le_audio/state_machine_test.cc +26 −0 Original line number Diff line number Diff line Loading @@ -2788,6 +2788,32 @@ TEST_F(StateMachineTest, testStateTransitionTimeoutOnIdleState) { ASSERT_TRUE(fake_osi_alarm_set_on_mloop_.cb == nullptr); } TEST_F(StateMachineTest, testStateIdleNotifyAclDisconnectedRemoveCig) { const auto context_type = kContextTypeRingtone; const int leaudio_group_id = 4; // Prepare fake connected device group auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type); group->SetCigState(types::CigState::CREATED); // Assert current state ASSERT_TRUE(group->GetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE); ASSERT_FALSE(group->IsInTransition()); ASSERT_TRUE(group->GetCigState() == types::CigState::CREATED); // Expect RemoveCig to be called EXPECT_CALL(*mock_iso_manager_, RemoveCig(group->group_id_, _)).Times(1); // Disconnect device auto* leAudioDevice = group->GetFirstDevice(); LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected( group, leAudioDevice); // Assert Cig state transition to NONE after REMOVING ASSERT_TRUE(group->GetCigState() == types::CigState::NONE); } TEST_F(StateMachineTest, testStateTransitionTimeout) { const auto context_type = kContextTypeRingtone; const int leaudio_group_id = 4; Loading Loading
system/bta/le_audio/state_machine.cc +14 −2 Original line number Diff line number Diff line Loading @@ -623,14 +623,26 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return; } /* If group is in Idle and not transitioning, just update the current group /* If group is in Idle and not transitioning, update the current group * audio context availability which could change due to disconnected group * member. */ if ((group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) && !group->IsInTransition()) { LOG(INFO) << __func__ << " group: " << group->group_id_ << " is in IDLE"; LOG_INFO("group: %d is in IDLE", group->group_id_); group->UpdateAudioContextTypeAvailability(); /* When OnLeAudioDeviceSetStateTimeout happens, group will transition * to IDLE, and after that an ACL disconnect will be triggered. We need * to check if CIG is created and if it is, remove it so it can be created * again after reconnect. Otherwise we will get Command Disallowed on CIG * Create when starting stream. */ if (group->GetCigState() == CigState::CREATED) { LOG_INFO("CIG is in CREATED state so removing CIG for Group %d", group->group_id_); RemoveCigForGroup(group); } return; } Loading
system/bta/le_audio/state_machine_test.cc +26 −0 Original line number Diff line number Diff line Loading @@ -2788,6 +2788,32 @@ TEST_F(StateMachineTest, testStateTransitionTimeoutOnIdleState) { ASSERT_TRUE(fake_osi_alarm_set_on_mloop_.cb == nullptr); } TEST_F(StateMachineTest, testStateIdleNotifyAclDisconnectedRemoveCig) { const auto context_type = kContextTypeRingtone; const int leaudio_group_id = 4; // Prepare fake connected device group auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type); group->SetCigState(types::CigState::CREATED); // Assert current state ASSERT_TRUE(group->GetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE); ASSERT_FALSE(group->IsInTransition()); ASSERT_TRUE(group->GetCigState() == types::CigState::CREATED); // Expect RemoveCig to be called EXPECT_CALL(*mock_iso_manager_, RemoveCig(group->group_id_, _)).Times(1); // Disconnect device auto* leAudioDevice = group->GetFirstDevice(); LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected( group, leAudioDevice); // Assert Cig state transition to NONE after REMOVING ASSERT_TRUE(group->GetCigState() == types::CigState::NONE); } TEST_F(StateMachineTest, testStateTransitionTimeout) { const auto context_type = kContextTypeRingtone; const int leaudio_group_id = 4; Loading