Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +17 −5 Original line number Diff line number Diff line Loading @@ -1076,16 +1076,19 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac BluetoothDevice a2dpFallbackDevice = null; if (a2dpService != null) { a2dpFallbackDevice = a2dpService.getFallbackDevice(); Log.d(TAG, "a2dpFallbackDevice: " + a2dpFallbackDevice); } HeadsetService headsetService = mFactory.getHeadsetService(); BluetoothDevice headsetFallbackDevice = null; if (headsetService != null) { headsetFallbackDevice = headsetService.getFallbackDevice(); Log.d(TAG, "headsetFallbackDevice: " + headsetFallbackDevice); } List<BluetoothDevice> connectedDevices = new ArrayList<>(); connectedDevices.addAll(mLeAudioConnectedDevices); Log.d(TAG, "Audio mode: " + mAudioManager.getMode()); switch (mAudioManager.getMode()) { case AudioManager.MODE_NORMAL: if (a2dpFallbackDevice != null) { Loading @@ -1107,15 +1110,20 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac Log.d(TAG, "No fallback devices are found"); return false; } Log.d(TAG, "Most recently connected device: " + device); if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) { if (Objects.equals(a2dpFallbackDevice, device)) { Log.d(TAG, "Found an A2DP fallback device: " + device); setA2dpActiveDevice(device); if (Flags.alwaysFallbackToAvailableDevice()) { setHfpActiveDevice(headsetFallbackDevice); } else { if (Objects.equals(headsetFallbackDevice, device)) { setHfpActiveDevice(device); } else { setHfpActiveDevice(null); } } /* If dual mode is enabled, LEA will be made active once all supported classic audio profiles are made active for the device. */ if (!Utils.isDualModeAudioEnabled()) { Loading @@ -1138,11 +1146,15 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac if (Objects.equals(headsetFallbackDevice, device)) { Log.d(TAG, "Found a HFP fallback device: " + device); setHfpActiveDevice(device); if (Flags.alwaysFallbackToAvailableDevice()) { setA2dpActiveDevice(a2dpFallbackDevice); } else { if (Objects.equals(a2dpFallbackDevice, device)) { setA2dpActiveDevice(a2dpFallbackDevice); } else { setA2dpActiveDevice(null, true); } } if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } Loading android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +72 −0 Original line number Diff line number Diff line Loading @@ -509,6 +509,78 @@ public class ActiveDeviceManagerTest { Mockito.clearInvocations(mA2dpService); } @Test @EnableFlags(Flags.FLAG_ALWAYS_FALLBACK_TO_AVAILABLE_DEVICE) public void a2dpHeadsetActivated_checkFallbackMeachanismOneA2dpOneHeadset() { // Active call when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL); // Connect 1st device a2dpConnected(mA2dpHeadsetDevice, true); headsetConnected(mA2dpHeadsetDevice, true); a2dpActiveDeviceChanged(mA2dpHeadsetDevice); headsetActiveDeviceChanged(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpHeadsetDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); // Disable audio for the first device when(mA2dpService.getFallbackDevice()).thenReturn(null); when(mA2dpService.removeActiveDevice(anyBoolean())).thenReturn(true); when(mHeadsetService.getFallbackDevice()).thenReturn(mA2dpHeadsetDevice); mDatabaseManager.setProfileConnectionPolicy( mA2dpHeadsetDevice, BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); a2dpDisconnected(mA2dpHeadsetDevice); verify(mHeadsetService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).removeActiveDevice(anyBoolean()); a2dpActiveDeviceChanged(null); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(null); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); // Connect 2nd device a2dpConnected(mSecondaryAudioDevice, true); headsetConnected(mSecondaryAudioDevice, true); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); a2dpActiveDeviceChanged(mSecondaryAudioDevice); headsetActiveDeviceChanged(mSecondaryAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(mSecondaryAudioDevice); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mSecondaryAudioDevice); // Disable phone calls for the second device when(mA2dpService.getFallbackDevice()).thenReturn(mSecondaryAudioDevice); when(mHeadsetService.getFallbackDevice()).thenReturn(mA2dpHeadsetDevice); mDatabaseManager.setProfileConnectionPolicy( mSecondaryAudioDevice, BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); headsetDisconnected(mSecondaryAudioDevice); verify(mHeadsetService, timeout(TIMEOUT_MS).times(3)).setActiveDevice(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mSecondaryAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(mSecondaryAudioDevice); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); } @Test public void hfpActivated_whileActivatingA2dpHeadset() { headsetConnected(mHeadsetDevice, false); Loading Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +17 −5 Original line number Diff line number Diff line Loading @@ -1076,16 +1076,19 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac BluetoothDevice a2dpFallbackDevice = null; if (a2dpService != null) { a2dpFallbackDevice = a2dpService.getFallbackDevice(); Log.d(TAG, "a2dpFallbackDevice: " + a2dpFallbackDevice); } HeadsetService headsetService = mFactory.getHeadsetService(); BluetoothDevice headsetFallbackDevice = null; if (headsetService != null) { headsetFallbackDevice = headsetService.getFallbackDevice(); Log.d(TAG, "headsetFallbackDevice: " + headsetFallbackDevice); } List<BluetoothDevice> connectedDevices = new ArrayList<>(); connectedDevices.addAll(mLeAudioConnectedDevices); Log.d(TAG, "Audio mode: " + mAudioManager.getMode()); switch (mAudioManager.getMode()) { case AudioManager.MODE_NORMAL: if (a2dpFallbackDevice != null) { Loading @@ -1107,15 +1110,20 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac Log.d(TAG, "No fallback devices are found"); return false; } Log.d(TAG, "Most recently connected device: " + device); if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) { if (Objects.equals(a2dpFallbackDevice, device)) { Log.d(TAG, "Found an A2DP fallback device: " + device); setA2dpActiveDevice(device); if (Flags.alwaysFallbackToAvailableDevice()) { setHfpActiveDevice(headsetFallbackDevice); } else { if (Objects.equals(headsetFallbackDevice, device)) { setHfpActiveDevice(device); } else { setHfpActiveDevice(null); } } /* If dual mode is enabled, LEA will be made active once all supported classic audio profiles are made active for the device. */ if (!Utils.isDualModeAudioEnabled()) { Loading @@ -1138,11 +1146,15 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac if (Objects.equals(headsetFallbackDevice, device)) { Log.d(TAG, "Found a HFP fallback device: " + device); setHfpActiveDevice(device); if (Flags.alwaysFallbackToAvailableDevice()) { setA2dpActiveDevice(a2dpFallbackDevice); } else { if (Objects.equals(a2dpFallbackDevice, device)) { setA2dpActiveDevice(a2dpFallbackDevice); } else { setA2dpActiveDevice(null, true); } } if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +72 −0 Original line number Diff line number Diff line Loading @@ -509,6 +509,78 @@ public class ActiveDeviceManagerTest { Mockito.clearInvocations(mA2dpService); } @Test @EnableFlags(Flags.FLAG_ALWAYS_FALLBACK_TO_AVAILABLE_DEVICE) public void a2dpHeadsetActivated_checkFallbackMeachanismOneA2dpOneHeadset() { // Active call when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL); // Connect 1st device a2dpConnected(mA2dpHeadsetDevice, true); headsetConnected(mA2dpHeadsetDevice, true); a2dpActiveDeviceChanged(mA2dpHeadsetDevice); headsetActiveDeviceChanged(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpHeadsetDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); // Disable audio for the first device when(mA2dpService.getFallbackDevice()).thenReturn(null); when(mA2dpService.removeActiveDevice(anyBoolean())).thenReturn(true); when(mHeadsetService.getFallbackDevice()).thenReturn(mA2dpHeadsetDevice); mDatabaseManager.setProfileConnectionPolicy( mA2dpHeadsetDevice, BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); a2dpDisconnected(mA2dpHeadsetDevice); verify(mHeadsetService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).removeActiveDevice(anyBoolean()); a2dpActiveDeviceChanged(null); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(null); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); // Connect 2nd device a2dpConnected(mSecondaryAudioDevice, true); headsetConnected(mSecondaryAudioDevice, true); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); a2dpActiveDeviceChanged(mSecondaryAudioDevice); headsetActiveDeviceChanged(mSecondaryAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(mSecondaryAudioDevice); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mSecondaryAudioDevice); // Disable phone calls for the second device when(mA2dpService.getFallbackDevice()).thenReturn(mSecondaryAudioDevice); when(mHeadsetService.getFallbackDevice()).thenReturn(mA2dpHeadsetDevice); mDatabaseManager.setProfileConnectionPolicy( mSecondaryAudioDevice, BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); headsetDisconnected(mSecondaryAudioDevice); verify(mHeadsetService, timeout(TIMEOUT_MS).times(3)).setActiveDevice(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mSecondaryAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); assertThat(mActiveDeviceManager.getA2dpActiveDevice()).isEqualTo(mSecondaryAudioDevice); assertThat(mActiveDeviceManager.getHfpActiveDevice()).isEqualTo(mA2dpHeadsetDevice); } @Test public void hfpActivated_whileActivatingA2dpHeadset() { headsetConnected(mHeadsetDevice, false); Loading