Loading src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +86 −5 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ public class BluetoothDeviceManager { private boolean mLeAudioCallbackRegistered = false; private BluetoothLeAudio mBluetoothLeAudioService; private boolean mLeAudioSetAsCommunicationDevice = false; private boolean mHearingAidSetAsCommunicationDevice = false; private BluetoothDevice mBluetoothHearingAidActiveDeviceCache; private BluetoothAdapter mBluetoothAdapter; private AudioManager mAudioManager; Loading Loading @@ -396,6 +397,7 @@ public class BluetoothDeviceManager { public void disconnectAudio() { disconnectSco(); clearLeAudioCommunicationDevice(); clearHearingAidCommunicationDevice(); } public void disconnectSco() { Loading @@ -410,17 +412,43 @@ public class BluetoothDeviceManager { return mLeAudioSetAsCommunicationDevice; } public boolean isHearingAidSetAsCommunicationDevice() { return mHearingAidSetAsCommunicationDevice; } public void clearLeAudioCommunicationDevice() { if (!mLeAudioSetAsCommunicationDevice) { return; } mLeAudioSetAsCommunicationDevice = false; if (mAudioManager == null) { Log.i(this, " mAudioManager is null"); Log.i(this, "clearLeAudioCommunicationDevice: mAudioManager is null"); mLeAudioSetAsCommunicationDevice = false; return; } if (mAudioManager.getCommunicationDevice() != null && mAudioManager.getCommunicationDevice().getType() == AudioDeviceInfo.TYPE_BLE_HEADSET) { mAudioManager.clearCommunicationDevice(); mLeAudioSetAsCommunicationDevice = false; } } public void clearHearingAidCommunicationDevice() { if (!mHearingAidSetAsCommunicationDevice) { return; } if (mAudioManager == null) { Log.i(this, "clearHearingAidCommunicationDevice: mAudioManager is null"); mHearingAidSetAsCommunicationDevice = false; } if (mAudioManager.getCommunicationDevice() != null && mAudioManager.getCommunicationDevice().getType() == AudioDeviceInfo.TYPE_HEARING_AID) { mAudioManager.clearCommunicationDevice(); mHearingAidSetAsCommunicationDevice = false; } } public boolean setLeAudioCommunicationDevice() { Loading Loading @@ -456,6 +484,9 @@ public class BluetoothDeviceManager { return false; } // clear hearing aid communication device if set clearHearingAidCommunicationDevice(); // Turn BLE_OUT_HEADSET ON. boolean result = mAudioManager.setCommunicationDevice(bleHeadset); if (!result) { Loading @@ -467,6 +498,53 @@ public class BluetoothDeviceManager { return result; } public boolean setHearingAidCommunicationDevice() { Log.i(this, "setHearingAidCommunicationDevice"); if (mHearingAidSetAsCommunicationDevice) { Log.i(this, "mHearingAidSetAsCommunicationDevice already set"); return true; } if (mAudioManager == null) { Log.w(this, " mAudioManager is null"); return false; } AudioDeviceInfo hearingAid = null; List<AudioDeviceInfo> devices = mAudioManager.getAvailableCommunicationDevices(); if (devices.size() == 0) { Log.w(this, " No communication devices available."); return false; } for (AudioDeviceInfo device : devices) { Log.i(this, " Available device type: " + device.getType()); if (device.getType() == AudioDeviceInfo.TYPE_HEARING_AID) { hearingAid = device; break; } } if (hearingAid == null) { Log.w(this, " No hearingAid device available"); return false; } // clear LE audio communication device if set clearLeAudioCommunicationDevice(); // Turn hearing aid ON. boolean result = mAudioManager.setCommunicationDevice(hearingAid); if (!result) { Log.w(this, " Could not set hearingAid device"); } else { Log.i(this, " hearingAid device set"); mHearingAidSetAsCommunicationDevice = true; } return result; } // Connect audio to the bluetooth device at address, checking to see whether it's // le audio, hearing aid or a HFP device, and using the proper BT API. public boolean connectAudio(String address) { Loading @@ -486,9 +564,12 @@ public class BluetoothDeviceManager { Log.w(this, "Attempting to turn on audio when the hearing aid service is null"); return false; } return mBluetoothAdapter.setActiveDevice( if (mBluetoothAdapter.setActiveDevice( mHearingAidDevicesByAddress.get(address), BluetoothAdapter.ACTIVE_DEVICE_ALL); BluetoothAdapter.ACTIVE_DEVICE_ALL)) { return setHearingAidCommunicationDevice(); } return false; } else if (mHfpDevicesByAddress.containsKey(address)) { BluetoothDevice device = mHfpDevicesByAddress.get(address); if (mBluetoothHeadset == null) { Loading src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java +14 −6 Original line number Diff line number Diff line Loading @@ -381,7 +381,10 @@ public class BluetoothRouteManager extends StateMachine { break; case CONNECT_BT: if (!switchingBtDevices) { // Ignore connection to already connected device. // Ignore connection to already connected device but still notify // CallAudioRouteStateMachine since this might be a switch from other // to this already connected BT audio mListener.onBluetoothAudioConnected(); break; } Loading Loading @@ -621,6 +624,9 @@ public class BluetoothRouteManager extends StateMachine { } } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) { mHearingAidActiveDeviceCache = device; if (device == null) { mDeviceManager.clearHearingAidCommunicationDevice(); } } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) { mHfpActiveDeviceCache = device; } else { Loading Loading @@ -791,6 +797,7 @@ public class BluetoothRouteManager extends StateMachine { } if (bluetoothHearingAid != null) { if (mDeviceManager.isHearingAidSetAsCommunicationDevice()) { for (BluetoothDevice device : bluetoothAdapter.getActiveDevices( BluetoothProfile.HEARING_AID)) { if (device != null) { Loading @@ -800,6 +807,7 @@ public class BluetoothRouteManager extends StateMachine { } } } } if (bluetoothLeAudio != null) { if (mDeviceManager.isLeAudioCommunicationDevice()) { Loading src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java +10 −1 Original line number Diff line number Diff line Loading @@ -185,9 +185,18 @@ public class BluetoothStateReceiver extends BroadcastReceiver { * is set as communication device before we can say that BT_AUDIO_IS_ON */ if (!mBluetoothDeviceManager.setLeAudioCommunicationDevice()) { Log.w(LOG_TAG, "Device %s cannot be use as communication device.", device); Log.w(LOG_TAG, "Device %s cannot be use as LE audio communication device.", device); return; } } else { /* deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID */ if (!mBluetoothDeviceManager.setHearingAidCommunicationDevice()) { Log.w(LOG_TAG, "Device %s cannot be use as hearing aid communication device.", device); } } mBluetoothRouteManager.sendMessage(BT_AUDIO_IS_ON, args); } Loading tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java +18 −7 Original line number Diff line number Diff line Loading @@ -391,22 +391,33 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase { @SmallTest @Test public void testConnectDisconnectAudioHearingAid() { receiverUnderTest.setIsInCall(true); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); mBluetoothDeviceManager.connectAudio(device2.getAddress()); verify(mAdapter).setActiveDevice(device2, BluetoothAdapter.ACTIVE_DEVICE_ALL); AudioDeviceInfo mockAudioDeviceInfo = mock(AudioDeviceInfo.class); when(mockAudioDeviceInfo.getType()).thenReturn(AudioDeviceInfo.TYPE_HEARING_AID); List<AudioDeviceInfo> devices = new ArrayList<>(); devices.add(mockAudioDeviceInfo); when(mockAudioManager.getAvailableCommunicationDevices()) .thenReturn(devices); when(mockAudioManager.setCommunicationDevice(eq(mockAudioDeviceInfo))) .thenReturn(true); mBluetoothDeviceManager.connectAudio(device5.getAddress()); verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL); verify(mBluetoothHeadset, never()).connectAudio(); verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); when(mAdapter.getActiveDevices(eq(BluetoothProfile.HEARING_AID))) .thenReturn(Arrays.asList(device2, null)); when(mockAudioManager.getCommunicationDevice()).thenReturn(mockAudioDeviceInfo); mBluetoothDeviceManager.disconnectAudio(); verify(mBluetoothHeadset).disconnectAudio(); verify(mockAudioManager).clearCommunicationDevice(); } @SmallTest Loading tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ public class BluetoothRouteManagerTest extends TelecomTestCase { verifyConnectionAttempt(DEVICE1, 0); verifyConnectionAttempt(DEVICE2, 0); assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX + ":" + HEARING_AID_DEVICE.getAddress(), + ":" + DEVICE1.getAddress(), sm.getCurrentState().getName()); sm.quitNow(); } Loading Loading
src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +86 −5 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ public class BluetoothDeviceManager { private boolean mLeAudioCallbackRegistered = false; private BluetoothLeAudio mBluetoothLeAudioService; private boolean mLeAudioSetAsCommunicationDevice = false; private boolean mHearingAidSetAsCommunicationDevice = false; private BluetoothDevice mBluetoothHearingAidActiveDeviceCache; private BluetoothAdapter mBluetoothAdapter; private AudioManager mAudioManager; Loading Loading @@ -396,6 +397,7 @@ public class BluetoothDeviceManager { public void disconnectAudio() { disconnectSco(); clearLeAudioCommunicationDevice(); clearHearingAidCommunicationDevice(); } public void disconnectSco() { Loading @@ -410,17 +412,43 @@ public class BluetoothDeviceManager { return mLeAudioSetAsCommunicationDevice; } public boolean isHearingAidSetAsCommunicationDevice() { return mHearingAidSetAsCommunicationDevice; } public void clearLeAudioCommunicationDevice() { if (!mLeAudioSetAsCommunicationDevice) { return; } mLeAudioSetAsCommunicationDevice = false; if (mAudioManager == null) { Log.i(this, " mAudioManager is null"); Log.i(this, "clearLeAudioCommunicationDevice: mAudioManager is null"); mLeAudioSetAsCommunicationDevice = false; return; } if (mAudioManager.getCommunicationDevice() != null && mAudioManager.getCommunicationDevice().getType() == AudioDeviceInfo.TYPE_BLE_HEADSET) { mAudioManager.clearCommunicationDevice(); mLeAudioSetAsCommunicationDevice = false; } } public void clearHearingAidCommunicationDevice() { if (!mHearingAidSetAsCommunicationDevice) { return; } if (mAudioManager == null) { Log.i(this, "clearHearingAidCommunicationDevice: mAudioManager is null"); mHearingAidSetAsCommunicationDevice = false; } if (mAudioManager.getCommunicationDevice() != null && mAudioManager.getCommunicationDevice().getType() == AudioDeviceInfo.TYPE_HEARING_AID) { mAudioManager.clearCommunicationDevice(); mHearingAidSetAsCommunicationDevice = false; } } public boolean setLeAudioCommunicationDevice() { Loading Loading @@ -456,6 +484,9 @@ public class BluetoothDeviceManager { return false; } // clear hearing aid communication device if set clearHearingAidCommunicationDevice(); // Turn BLE_OUT_HEADSET ON. boolean result = mAudioManager.setCommunicationDevice(bleHeadset); if (!result) { Loading @@ -467,6 +498,53 @@ public class BluetoothDeviceManager { return result; } public boolean setHearingAidCommunicationDevice() { Log.i(this, "setHearingAidCommunicationDevice"); if (mHearingAidSetAsCommunicationDevice) { Log.i(this, "mHearingAidSetAsCommunicationDevice already set"); return true; } if (mAudioManager == null) { Log.w(this, " mAudioManager is null"); return false; } AudioDeviceInfo hearingAid = null; List<AudioDeviceInfo> devices = mAudioManager.getAvailableCommunicationDevices(); if (devices.size() == 0) { Log.w(this, " No communication devices available."); return false; } for (AudioDeviceInfo device : devices) { Log.i(this, " Available device type: " + device.getType()); if (device.getType() == AudioDeviceInfo.TYPE_HEARING_AID) { hearingAid = device; break; } } if (hearingAid == null) { Log.w(this, " No hearingAid device available"); return false; } // clear LE audio communication device if set clearLeAudioCommunicationDevice(); // Turn hearing aid ON. boolean result = mAudioManager.setCommunicationDevice(hearingAid); if (!result) { Log.w(this, " Could not set hearingAid device"); } else { Log.i(this, " hearingAid device set"); mHearingAidSetAsCommunicationDevice = true; } return result; } // Connect audio to the bluetooth device at address, checking to see whether it's // le audio, hearing aid or a HFP device, and using the proper BT API. public boolean connectAudio(String address) { Loading @@ -486,9 +564,12 @@ public class BluetoothDeviceManager { Log.w(this, "Attempting to turn on audio when the hearing aid service is null"); return false; } return mBluetoothAdapter.setActiveDevice( if (mBluetoothAdapter.setActiveDevice( mHearingAidDevicesByAddress.get(address), BluetoothAdapter.ACTIVE_DEVICE_ALL); BluetoothAdapter.ACTIVE_DEVICE_ALL)) { return setHearingAidCommunicationDevice(); } return false; } else if (mHfpDevicesByAddress.containsKey(address)) { BluetoothDevice device = mHfpDevicesByAddress.get(address); if (mBluetoothHeadset == null) { Loading
src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java +14 −6 Original line number Diff line number Diff line Loading @@ -381,7 +381,10 @@ public class BluetoothRouteManager extends StateMachine { break; case CONNECT_BT: if (!switchingBtDevices) { // Ignore connection to already connected device. // Ignore connection to already connected device but still notify // CallAudioRouteStateMachine since this might be a switch from other // to this already connected BT audio mListener.onBluetoothAudioConnected(); break; } Loading Loading @@ -621,6 +624,9 @@ public class BluetoothRouteManager extends StateMachine { } } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) { mHearingAidActiveDeviceCache = device; if (device == null) { mDeviceManager.clearHearingAidCommunicationDevice(); } } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) { mHfpActiveDeviceCache = device; } else { Loading Loading @@ -791,6 +797,7 @@ public class BluetoothRouteManager extends StateMachine { } if (bluetoothHearingAid != null) { if (mDeviceManager.isHearingAidSetAsCommunicationDevice()) { for (BluetoothDevice device : bluetoothAdapter.getActiveDevices( BluetoothProfile.HEARING_AID)) { if (device != null) { Loading @@ -800,6 +807,7 @@ public class BluetoothRouteManager extends StateMachine { } } } } if (bluetoothLeAudio != null) { if (mDeviceManager.isLeAudioCommunicationDevice()) { Loading
src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java +10 −1 Original line number Diff line number Diff line Loading @@ -185,9 +185,18 @@ public class BluetoothStateReceiver extends BroadcastReceiver { * is set as communication device before we can say that BT_AUDIO_IS_ON */ if (!mBluetoothDeviceManager.setLeAudioCommunicationDevice()) { Log.w(LOG_TAG, "Device %s cannot be use as communication device.", device); Log.w(LOG_TAG, "Device %s cannot be use as LE audio communication device.", device); return; } } else { /* deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID */ if (!mBluetoothDeviceManager.setHearingAidCommunicationDevice()) { Log.w(LOG_TAG, "Device %s cannot be use as hearing aid communication device.", device); } } mBluetoothRouteManager.sendMessage(BT_AUDIO_IS_ON, args); } Loading
tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java +18 −7 Original line number Diff line number Diff line Loading @@ -391,22 +391,33 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase { @SmallTest @Test public void testConnectDisconnectAudioHearingAid() { receiverUnderTest.setIsInCall(true); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); mBluetoothDeviceManager.connectAudio(device2.getAddress()); verify(mAdapter).setActiveDevice(device2, BluetoothAdapter.ACTIVE_DEVICE_ALL); AudioDeviceInfo mockAudioDeviceInfo = mock(AudioDeviceInfo.class); when(mockAudioDeviceInfo.getType()).thenReturn(AudioDeviceInfo.TYPE_HEARING_AID); List<AudioDeviceInfo> devices = new ArrayList<>(); devices.add(mockAudioDeviceInfo); when(mockAudioManager.getAvailableCommunicationDevices()) .thenReturn(devices); when(mockAudioManager.setCommunicationDevice(eq(mockAudioDeviceInfo))) .thenReturn(true); mBluetoothDeviceManager.connectAudio(device5.getAddress()); verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL); verify(mBluetoothHeadset, never()).connectAudio(); verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); when(mAdapter.getActiveDevices(eq(BluetoothProfile.HEARING_AID))) .thenReturn(Arrays.asList(device2, null)); when(mockAudioManager.getCommunicationDevice()).thenReturn(mockAudioDeviceInfo); mBluetoothDeviceManager.disconnectAudio(); verify(mBluetoothHeadset).disconnectAudio(); verify(mockAudioManager).clearCommunicationDevice(); } @SmallTest Loading
tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ public class BluetoothRouteManagerTest extends TelecomTestCase { verifyConnectionAttempt(DEVICE1, 0); verifyConnectionAttempt(DEVICE2, 0); assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX + ":" + HEARING_AID_DEVICE.getAddress(), + ":" + DEVICE1.getAddress(), sm.getCurrentState().getName()); sm.quitNow(); } Loading