Loading system/bta/le_audio/client.cc +59 −14 Original line number Diff line number Diff line Loading @@ -2142,6 +2142,31 @@ class LeAudioClientImpl : public LeAudioClient { ); } void autoConnect(RawAddress address) { auto leAudioDevice = leAudioDevices_.FindByAddress(address); if (leAudioDevice == nullptr) { LOG_WARN("Device %s not valid anymore", ADDRESS_TO_LOGGABLE_CSTR(address)); return; } BackgroundConnectIfNeeded(leAudioDevice); } void scheduleAutoConnect(RawAddress& address) { LOG_INFO("Schedule auto connect %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); do_in_main_thread_delayed( FROM_HERE, base::BindOnce(&LeAudioClientImpl::autoConnect, base::Unretained(this), address), #if BASE_VER < 931007 base::TimeDelta::FromMilliseconds(kAutoConnectAfterOwnDisconnectDelayMs) #else base::Milliseconds(kDeviceAttachDelayMs) #endif ); } void recoveryReconnect(RawAddress address) { LOG_INFO("Reconnecting to %s after timeout on state machine.", ADDRESS_TO_LOGGABLE_CSTR(address)); Loading Loading @@ -2245,14 +2270,33 @@ class LeAudioClientImpl : public LeAudioClient { return; } if (reason != GATT_CONN_TERMINATE_LOCAL_HOST || leAudioDevice->autoconnect_flag_) { if (reason == GATT_CONN_TERMINATE_LOCAL_HOST) { if (leAudioDevice->autoconnect_flag_) { /* In this case ACL might not yet been disconnected */ scheduleAutoConnect(address); } else { /* Just acknowledge disconnected state*/ leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); } return; } /* Remote disconnects from us or Timeout happens */ /* In this case ACL is disconnected */ if (reason == GATT_CONN_TIMEOUT) { leAudioDevice->SetConnectionState( DeviceConnectState::CONNECTING_AUTOCONNECT); if (reason == GATT_CONN_TIMEOUT) { /* If timeout try to reconnect for 30 sec.*/ BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false); } else { return; } /* In other disconnect resons we act based on the autoconnect_flag_ */ if (leAudioDevice->autoconnect_flag_) { leAudioDevice->SetConnectionState( DeviceConnectState::CONNECTING_AUTOCONNECT); BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false); if (group->IsAnyDeviceConnected()) { /* If all set is disconnecting, let's give it some time. Loading @@ -2261,8 +2305,8 @@ class LeAudioClientImpl : public LeAudioClient { */ scheduleGroupConnectedCheck(leAudioDevice->group_id_); } } } else { /* Just acknowledge disconnected state*/ leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); } } Loading Loading @@ -5195,6 +5239,7 @@ class LeAudioClientImpl : public LeAudioClient { tBTM_BLE_CONN_TYPE reconnection_mode_; static constexpr uint64_t kGroupConnectedWatchDelayMs = 3000; static constexpr uint64_t kRecoveryReconnectDelayMs = 2000; static constexpr uint64_t kAutoConnectAfterOwnDisconnectDelayMs = 1000; static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] = "persist.bluetooth.leaudio.notify.idle.during.call"; Loading system/bta/le_audio/le_audio_client_test.cc +34 −3 Original line number Diff line number Diff line Loading @@ -2490,6 +2490,40 @@ TEST_F(UnicastTest, ConnectRemoteDisconnectOneEarbud) { SyncOnMainLoop(); } /* same as above case except the disconnect is initiated by remote */ TEST_F(UnicastTest, ConnectRemoteDisconnectOnTimeoutOneEarbud) { const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); ConnectLeAudio(test_address0); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::DISCONNECTED, test_address0)) .Times(1); /* Remove default action on the direct connect */ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)) .WillByDefault(Return()); /* For remote disconnection, expect stack to try background re-connect */ EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT); SyncOnMainLoop(); /* For background connect, test needs to Inject Connected Event */ InjectConnectedEvent(test_address0, 1); SyncOnMainLoop(); } TEST_F(UnicastTest, ConnectTwoEarbudsCsisGrouped) { uint8_t group_size = 2; int group_id = 2; Loading Loading @@ -4171,9 +4205,6 @@ TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnect) { EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) .Times(1); EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_ALLOW_LIST, _)) .Times(1); EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1); DisconnectLeAudio(test_address0, 1); Loading Loading
system/bta/le_audio/client.cc +59 −14 Original line number Diff line number Diff line Loading @@ -2142,6 +2142,31 @@ class LeAudioClientImpl : public LeAudioClient { ); } void autoConnect(RawAddress address) { auto leAudioDevice = leAudioDevices_.FindByAddress(address); if (leAudioDevice == nullptr) { LOG_WARN("Device %s not valid anymore", ADDRESS_TO_LOGGABLE_CSTR(address)); return; } BackgroundConnectIfNeeded(leAudioDevice); } void scheduleAutoConnect(RawAddress& address) { LOG_INFO("Schedule auto connect %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); do_in_main_thread_delayed( FROM_HERE, base::BindOnce(&LeAudioClientImpl::autoConnect, base::Unretained(this), address), #if BASE_VER < 931007 base::TimeDelta::FromMilliseconds(kAutoConnectAfterOwnDisconnectDelayMs) #else base::Milliseconds(kDeviceAttachDelayMs) #endif ); } void recoveryReconnect(RawAddress address) { LOG_INFO("Reconnecting to %s after timeout on state machine.", ADDRESS_TO_LOGGABLE_CSTR(address)); Loading Loading @@ -2245,14 +2270,33 @@ class LeAudioClientImpl : public LeAudioClient { return; } if (reason != GATT_CONN_TERMINATE_LOCAL_HOST || leAudioDevice->autoconnect_flag_) { if (reason == GATT_CONN_TERMINATE_LOCAL_HOST) { if (leAudioDevice->autoconnect_flag_) { /* In this case ACL might not yet been disconnected */ scheduleAutoConnect(address); } else { /* Just acknowledge disconnected state*/ leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); } return; } /* Remote disconnects from us or Timeout happens */ /* In this case ACL is disconnected */ if (reason == GATT_CONN_TIMEOUT) { leAudioDevice->SetConnectionState( DeviceConnectState::CONNECTING_AUTOCONNECT); if (reason == GATT_CONN_TIMEOUT) { /* If timeout try to reconnect for 30 sec.*/ BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false); } else { return; } /* In other disconnect resons we act based on the autoconnect_flag_ */ if (leAudioDevice->autoconnect_flag_) { leAudioDevice->SetConnectionState( DeviceConnectState::CONNECTING_AUTOCONNECT); BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false); if (group->IsAnyDeviceConnected()) { /* If all set is disconnecting, let's give it some time. Loading @@ -2261,8 +2305,8 @@ class LeAudioClientImpl : public LeAudioClient { */ scheduleGroupConnectedCheck(leAudioDevice->group_id_); } } } else { /* Just acknowledge disconnected state*/ leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); } } Loading Loading @@ -5195,6 +5239,7 @@ class LeAudioClientImpl : public LeAudioClient { tBTM_BLE_CONN_TYPE reconnection_mode_; static constexpr uint64_t kGroupConnectedWatchDelayMs = 3000; static constexpr uint64_t kRecoveryReconnectDelayMs = 2000; static constexpr uint64_t kAutoConnectAfterOwnDisconnectDelayMs = 1000; static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] = "persist.bluetooth.leaudio.notify.idle.during.call"; Loading
system/bta/le_audio/le_audio_client_test.cc +34 −3 Original line number Diff line number Diff line Loading @@ -2490,6 +2490,40 @@ TEST_F(UnicastTest, ConnectRemoteDisconnectOneEarbud) { SyncOnMainLoop(); } /* same as above case except the disconnect is initiated by remote */ TEST_F(UnicastTest, ConnectRemoteDisconnectOnTimeoutOneEarbud) { const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo, codec_spec_conf::kLeAudioLocationStereo); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); ConnectLeAudio(test_address0); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::DISCONNECTED, test_address0)) .Times(1); /* Remove default action on the direct connect */ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)) .WillByDefault(Return()); /* For remote disconnection, expect stack to try background re-connect */ EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT); SyncOnMainLoop(); /* For background connect, test needs to Inject Connected Event */ InjectConnectedEvent(test_address0, 1); SyncOnMainLoop(); } TEST_F(UnicastTest, ConnectTwoEarbudsCsisGrouped) { uint8_t group_size = 2; int group_id = 2; Loading Loading @@ -4171,9 +4205,6 @@ TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnect) { EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) .Times(1); EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_ALLOW_LIST, _)) .Times(1); EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1); DisconnectLeAudio(test_address0, 1); Loading