Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +34 −14 Original line number Diff line number Diff line Loading @@ -502,11 +502,7 @@ class ActiveDeviceManager { mLeAudioConnectedDevices.add(device); } // New connected device: select it as active setLeAudioActiveDevice(device); if (mLeAudioActiveDevice == device) { // setLeAudioActiveDevice succeed mLeHearingAidActiveDevice = device; } setLeHearingAidActiveDevice(device); setA2dpActiveDevice(null); setHfpActiveDevice(null); break; Loading @@ -522,7 +518,7 @@ class ActiveDeviceManager { // mLeAudioConnectedDevices should contain all of // mLeHearingAidConnectedDevices. Call setLeAudioActiveDevice(null) // only if there are no LE audio devices. if (Objects.equals(mLeHearingAidConnectedDevices, device)) { if (Objects.equals(mLeHearingAidActiveDevice, device)) { if (mLeAudioConnectedDevices.isEmpty()) { setLeAudioActiveDevice(null); } Loading Loading @@ -718,6 +714,14 @@ class ActiveDeviceManager { } } private void setLeHearingAidActiveDevice(BluetoothDevice device) { setLeAudioActiveDevice(device); if (mLeAudioActiveDevice == device) { // setLeAudioActiveDevice succeed mLeHearingAidActiveDevice = device; } } private void setFallbackDeviceActive() { if (DBG) { Log.d(TAG, "setFallbackDeviceActive"); Loading @@ -726,11 +730,18 @@ class ActiveDeviceManager { if (dbManager == null) { return; } List<BluetoothDevice> connectedHearingAidDevices = new LinkedList<>(); if (!mHearingAidConnectedDevices.isEmpty()) { connectedHearingAidDevices.addAll(mHearingAidConnectedDevices); } if (!mLeHearingAidConnectedDevices.isEmpty()) { connectedHearingAidDevices.addAll(mLeHearingAidConnectedDevices); } if (!connectedHearingAidDevices.isEmpty()) { BluetoothDevice device = dbManager.getMostRecentlyConnectedDevicesInList(mHearingAidConnectedDevices); dbManager.getMostRecentlyConnectedDevicesInList(connectedHearingAidDevices); if (device != null) { if (mHearingAidConnectedDevices.contains(device)) { if (DBG) { Log.d(TAG, "set hearing aid device active: " + device); } Loading @@ -738,6 +749,15 @@ class ActiveDeviceManager { setA2dpActiveDevice(null); setHfpActiveDevice(null); setLeAudioActiveDevice(null); } else { if (DBG) { Log.d(TAG, "set LE hearing aid device active: " + device); } setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setHfpActiveDevice(null); } return; } } Loading android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +103 −48 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.List; Loading @@ -62,7 +63,11 @@ public class ActiveDeviceManagerTest { private BluetoothDevice mA2dpHeadsetDevice; private BluetoothDevice mHearingAidDevice; private BluetoothDevice mLeAudioDevice; private BluetoothDevice mLeHearingAidDevice; private BluetoothDevice mSecondaryAudioDevice; private BluetoothDevice mMostRecentDevice; private boolean mFallbackToA2dp; private boolean mFallbackToHfp; private ActiveDeviceManager mActiveDeviceManager; private static final int TIMEOUT_MS = 1000; Loading @@ -85,6 +90,7 @@ public class ActiveDeviceManagerTest { // Set up mocks and test assets MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); when(mAdapterService.getSystemServiceName(AudioManager.class)) .thenReturn(Context.AUDIO_SERVICE); Loading @@ -93,12 +99,6 @@ public class ActiveDeviceManagerTest { when(mServiceFactory.getHeadsetService()).thenReturn(mHeadsetService); when(mServiceFactory.getHearingAidService()).thenReturn(mHearingAidService); when(mServiceFactory.getLeAudioService()).thenReturn(mLeAudioService); when(mA2dpService.setActiveDevice(any())).thenReturn(true); when(mHeadsetService.setActiveDevice(any())).thenReturn(true); when(mHearingAidService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.setActiveDevice(any())).thenReturn(true); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())) .thenReturn(mSecondaryAudioDevice); mActiveDeviceManager = new ActiveDeviceManager(mAdapterService, mServiceFactory); mActiveDeviceManager.start(); Loading @@ -110,7 +110,46 @@ public class ActiveDeviceManagerTest { mA2dpHeadsetDevice = TestUtils.getTestDevice(mAdapter, 2); mHearingAidDevice = TestUtils.getTestDevice(mAdapter, 3); mLeAudioDevice = TestUtils.getTestDevice(mAdapter, 4); mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 5); mLeHearingAidDevice = TestUtils.getTestDevice(mAdapter, 5); mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 6); mMostRecentDevice = null; when(mA2dpService.setActiveDevice(any())).thenAnswer(invocation -> { BluetoothDevice device = invocation.getArgument(0); BluetoothDevice fallbackDevice = device; if (device == null && mFallbackToA2dp) { fallbackDevice = mA2dpDevice; } when(mA2dpService.getFallbackDevice()).thenReturn(fallbackDevice); return true; }); when(mHeadsetService.setActiveDevice(any())).thenAnswer(invocation -> { BluetoothDevice device = invocation.getArgument(0); BluetoothDevice fallbackDevice = device; if (device == null && mFallbackToHfp) { fallbackDevice = mHeadsetDevice; } when(mHeadsetService.getFallbackDevice()).thenReturn(fallbackDevice); return true; }); when(mHearingAidService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.setActiveDevice(any())).thenReturn(true); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); if (devices == null || devices.size() == 0) { return null; } else if (mMostRecentDevice != null && devices.contains(mMostRecentDevice)) { return mMostRecentDevice; } else if (devices.contains(mLeHearingAidDevice)) { return mLeHearingAidDevice; } else if (devices.contains(mHearingAidDevice)) { return mHearingAidDevice; } else { return devices.get(0); } } ); } @After Loading Loading @@ -243,7 +282,6 @@ public class ActiveDeviceManagerTest { Assert.assertEquals(mHeadsetDevice, mActiveDeviceManager.getHfpActiveDevice()); } /** * Two Headsets are connected and the current active is then disconnected. * Should then set active device to fallback device. Loading Loading @@ -481,23 +519,18 @@ public class ActiveDeviceManagerTest { */ @Test public void leAudioAndA2dpConnectedThenA2dpDisconnected_fallbackToLeAudio() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); a2dpConnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); return (devices != null && devices.contains(mLeAudioDevice)) ? mLeAudioDevice : null; } ); Mockito.clearInvocations(mLeAudioService); a2dpDisconnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS).atLeast(1)).setActiveDevice(isNull()); verify(mLeAudioService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); } /** Loading @@ -506,23 +539,18 @@ public class ActiveDeviceManagerTest { */ @Test public void a2dpAndLeAudioConnectedThenLeAudioDisconnected_fallbackToA2dp() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); a2dpConnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mA2dpService.getFallbackDevice()).thenReturn(mA2dpDevice); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); return (devices != null && devices.contains(mA2dpDevice)) ? mA2dpDevice : null; } ); Mockito.clearInvocations(mA2dpService); leAudioDisconnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS).atLeast(1)).setActiveDevice(isNull()); verify(mA2dpService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); } /** Loading @@ -547,6 +575,8 @@ public class ActiveDeviceManagerTest { */ @Test public void activeDeviceDisconnected_fallbackToHearingAid() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); hearingAidConnected(mHearingAidDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice); Loading @@ -560,23 +590,6 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice); verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); if (devices == null) { return null; } else if (devices.contains(mA2dpDevice)) { return mA2dpDevice; } else if (devices.contains(mLeAudioDevice)) { return mLeAudioDevice; } else if (devices.contains(mHearingAidDevice)) { return mHearingAidDevice; } else { return devices.get(0); } } ); a2dpDisconnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS).atLeast(1)).setActiveDevice(isNull()); verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)) Loading @@ -587,9 +600,9 @@ public class ActiveDeviceManagerTest { * One LE Hearing Aid is connected. */ @Test public void onlyLeHearingAIdConnected_setHeadsetActive() { leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); public void onlyLeHearingAIdConnected_setLeAudioActive() { leHearingAidConnected(mLeHearingAidDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); } /** Loading @@ -598,14 +611,42 @@ public class ActiveDeviceManagerTest { */ @Test public void leAudioConnectedAfterLeHearingAid_setLeAudioActiveShouldNotBeCalled() { leHearingAidConnected(mSecondaryAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); leHearingAidConnected(mLeHearingAidDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); leAudioConnected(mLeAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice); } /** * Test connect/disconnect of devices. * Hearing Aid, LE Hearing Aid, A2DP connected, then LE hearing Aid and hearing aid * disconnected. */ @Test public void activeDeviceChange_withHearingAidLeHearingAidAndA2dpDevices() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); hearingAidConnected(mHearingAidDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice); leHearingAidConnected(mLeHearingAidDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); a2dpConnected(mA2dpDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); Mockito.clearInvocations(mHearingAidService, mA2dpService); leHearingAidDisconnected(mLeHearingAidDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); hearingAidDisconnected(mHearingAidDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); } /** * A wired audio device is connected. Then all active devices are set to null. */ Loading @@ -631,6 +672,8 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; mFallbackToA2dp = true; } /** Loading @@ -642,6 +685,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mFallbackToA2dp = false; } /** Loading @@ -651,6 +695,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -662,6 +707,8 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; mFallbackToHfp = true; } /** Loading @@ -673,6 +720,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mFallbackToHfp = false; } /** Loading @@ -682,6 +730,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -693,6 +742,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -713,6 +763,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -724,6 +775,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -744,6 +796,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -755,6 +808,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -775,5 +829,6 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } } Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +34 −14 Original line number Diff line number Diff line Loading @@ -502,11 +502,7 @@ class ActiveDeviceManager { mLeAudioConnectedDevices.add(device); } // New connected device: select it as active setLeAudioActiveDevice(device); if (mLeAudioActiveDevice == device) { // setLeAudioActiveDevice succeed mLeHearingAidActiveDevice = device; } setLeHearingAidActiveDevice(device); setA2dpActiveDevice(null); setHfpActiveDevice(null); break; Loading @@ -522,7 +518,7 @@ class ActiveDeviceManager { // mLeAudioConnectedDevices should contain all of // mLeHearingAidConnectedDevices. Call setLeAudioActiveDevice(null) // only if there are no LE audio devices. if (Objects.equals(mLeHearingAidConnectedDevices, device)) { if (Objects.equals(mLeHearingAidActiveDevice, device)) { if (mLeAudioConnectedDevices.isEmpty()) { setLeAudioActiveDevice(null); } Loading Loading @@ -718,6 +714,14 @@ class ActiveDeviceManager { } } private void setLeHearingAidActiveDevice(BluetoothDevice device) { setLeAudioActiveDevice(device); if (mLeAudioActiveDevice == device) { // setLeAudioActiveDevice succeed mLeHearingAidActiveDevice = device; } } private void setFallbackDeviceActive() { if (DBG) { Log.d(TAG, "setFallbackDeviceActive"); Loading @@ -726,11 +730,18 @@ class ActiveDeviceManager { if (dbManager == null) { return; } List<BluetoothDevice> connectedHearingAidDevices = new LinkedList<>(); if (!mHearingAidConnectedDevices.isEmpty()) { connectedHearingAidDevices.addAll(mHearingAidConnectedDevices); } if (!mLeHearingAidConnectedDevices.isEmpty()) { connectedHearingAidDevices.addAll(mLeHearingAidConnectedDevices); } if (!connectedHearingAidDevices.isEmpty()) { BluetoothDevice device = dbManager.getMostRecentlyConnectedDevicesInList(mHearingAidConnectedDevices); dbManager.getMostRecentlyConnectedDevicesInList(connectedHearingAidDevices); if (device != null) { if (mHearingAidConnectedDevices.contains(device)) { if (DBG) { Log.d(TAG, "set hearing aid device active: " + device); } Loading @@ -738,6 +749,15 @@ class ActiveDeviceManager { setA2dpActiveDevice(null); setHfpActiveDevice(null); setLeAudioActiveDevice(null); } else { if (DBG) { Log.d(TAG, "set LE hearing aid device active: " + device); } setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setHfpActiveDevice(null); } return; } } Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +103 −48 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.List; Loading @@ -62,7 +63,11 @@ public class ActiveDeviceManagerTest { private BluetoothDevice mA2dpHeadsetDevice; private BluetoothDevice mHearingAidDevice; private BluetoothDevice mLeAudioDevice; private BluetoothDevice mLeHearingAidDevice; private BluetoothDevice mSecondaryAudioDevice; private BluetoothDevice mMostRecentDevice; private boolean mFallbackToA2dp; private boolean mFallbackToHfp; private ActiveDeviceManager mActiveDeviceManager; private static final int TIMEOUT_MS = 1000; Loading @@ -85,6 +90,7 @@ public class ActiveDeviceManagerTest { // Set up mocks and test assets MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); when(mAdapterService.getSystemServiceName(AudioManager.class)) .thenReturn(Context.AUDIO_SERVICE); Loading @@ -93,12 +99,6 @@ public class ActiveDeviceManagerTest { when(mServiceFactory.getHeadsetService()).thenReturn(mHeadsetService); when(mServiceFactory.getHearingAidService()).thenReturn(mHearingAidService); when(mServiceFactory.getLeAudioService()).thenReturn(mLeAudioService); when(mA2dpService.setActiveDevice(any())).thenReturn(true); when(mHeadsetService.setActiveDevice(any())).thenReturn(true); when(mHearingAidService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.setActiveDevice(any())).thenReturn(true); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())) .thenReturn(mSecondaryAudioDevice); mActiveDeviceManager = new ActiveDeviceManager(mAdapterService, mServiceFactory); mActiveDeviceManager.start(); Loading @@ -110,7 +110,46 @@ public class ActiveDeviceManagerTest { mA2dpHeadsetDevice = TestUtils.getTestDevice(mAdapter, 2); mHearingAidDevice = TestUtils.getTestDevice(mAdapter, 3); mLeAudioDevice = TestUtils.getTestDevice(mAdapter, 4); mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 5); mLeHearingAidDevice = TestUtils.getTestDevice(mAdapter, 5); mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 6); mMostRecentDevice = null; when(mA2dpService.setActiveDevice(any())).thenAnswer(invocation -> { BluetoothDevice device = invocation.getArgument(0); BluetoothDevice fallbackDevice = device; if (device == null && mFallbackToA2dp) { fallbackDevice = mA2dpDevice; } when(mA2dpService.getFallbackDevice()).thenReturn(fallbackDevice); return true; }); when(mHeadsetService.setActiveDevice(any())).thenAnswer(invocation -> { BluetoothDevice device = invocation.getArgument(0); BluetoothDevice fallbackDevice = device; if (device == null && mFallbackToHfp) { fallbackDevice = mHeadsetDevice; } when(mHeadsetService.getFallbackDevice()).thenReturn(fallbackDevice); return true; }); when(mHearingAidService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.setActiveDevice(any())).thenReturn(true); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); if (devices == null || devices.size() == 0) { return null; } else if (mMostRecentDevice != null && devices.contains(mMostRecentDevice)) { return mMostRecentDevice; } else if (devices.contains(mLeHearingAidDevice)) { return mLeHearingAidDevice; } else if (devices.contains(mHearingAidDevice)) { return mHearingAidDevice; } else { return devices.get(0); } } ); } @After Loading Loading @@ -243,7 +282,6 @@ public class ActiveDeviceManagerTest { Assert.assertEquals(mHeadsetDevice, mActiveDeviceManager.getHfpActiveDevice()); } /** * Two Headsets are connected and the current active is then disconnected. * Should then set active device to fallback device. Loading Loading @@ -481,23 +519,18 @@ public class ActiveDeviceManagerTest { */ @Test public void leAudioAndA2dpConnectedThenA2dpDisconnected_fallbackToLeAudio() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); a2dpConnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); return (devices != null && devices.contains(mLeAudioDevice)) ? mLeAudioDevice : null; } ); Mockito.clearInvocations(mLeAudioService); a2dpDisconnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS).atLeast(1)).setActiveDevice(isNull()); verify(mLeAudioService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); } /** Loading @@ -506,23 +539,18 @@ public class ActiveDeviceManagerTest { */ @Test public void a2dpAndLeAudioConnectedThenLeAudioDisconnected_fallbackToA2dp() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); a2dpConnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mA2dpService.getFallbackDevice()).thenReturn(mA2dpDevice); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); return (devices != null && devices.contains(mA2dpDevice)) ? mA2dpDevice : null; } ); Mockito.clearInvocations(mA2dpService); leAudioDisconnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS).atLeast(1)).setActiveDevice(isNull()); verify(mA2dpService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); } /** Loading @@ -547,6 +575,8 @@ public class ActiveDeviceManagerTest { */ @Test public void activeDeviceDisconnected_fallbackToHearingAid() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); hearingAidConnected(mHearingAidDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice); Loading @@ -560,23 +590,6 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice); verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mDatabaseManager.getMostRecentlyConnectedDevicesInList(any())).thenAnswer( invocation -> { List<BluetoothDevice> devices = invocation.getArgument(0); if (devices == null) { return null; } else if (devices.contains(mA2dpDevice)) { return mA2dpDevice; } else if (devices.contains(mLeAudioDevice)) { return mLeAudioDevice; } else if (devices.contains(mHearingAidDevice)) { return mHearingAidDevice; } else { return devices.get(0); } } ); a2dpDisconnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS).atLeast(1)).setActiveDevice(isNull()); verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)) Loading @@ -587,9 +600,9 @@ public class ActiveDeviceManagerTest { * One LE Hearing Aid is connected. */ @Test public void onlyLeHearingAIdConnected_setHeadsetActive() { leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); public void onlyLeHearingAIdConnected_setLeAudioActive() { leHearingAidConnected(mLeHearingAidDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); } /** Loading @@ -598,14 +611,42 @@ public class ActiveDeviceManagerTest { */ @Test public void leAudioConnectedAfterLeHearingAid_setLeAudioActiveShouldNotBeCalled() { leHearingAidConnected(mSecondaryAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); leHearingAidConnected(mLeHearingAidDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); leAudioConnected(mLeAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice); } /** * Test connect/disconnect of devices. * Hearing Aid, LE Hearing Aid, A2DP connected, then LE hearing Aid and hearing aid * disconnected. */ @Test public void activeDeviceChange_withHearingAidLeHearingAidAndA2dpDevices() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); hearingAidConnected(mHearingAidDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice); leHearingAidConnected(mLeHearingAidDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); a2dpConnected(mA2dpDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); Mockito.clearInvocations(mHearingAidService, mA2dpService); leHearingAidDisconnected(mLeHearingAidDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); hearingAidDisconnected(mHearingAidDevice); verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); } /** * A wired audio device is connected. Then all active devices are set to null. */ Loading @@ -631,6 +672,8 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; mFallbackToA2dp = true; } /** Loading @@ -642,6 +685,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mFallbackToA2dp = false; } /** Loading @@ -651,6 +695,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -662,6 +707,8 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; mFallbackToHfp = true; } /** Loading @@ -673,6 +720,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mFallbackToHfp = false; } /** Loading @@ -682,6 +730,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -693,6 +742,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -713,6 +763,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -724,6 +775,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -744,6 +796,7 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -755,6 +808,7 @@ public class ActiveDeviceManagerTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } /** Loading @@ -775,5 +829,6 @@ public class ActiveDeviceManagerTest { Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mMostRecentDevice = device; } }