Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +17 −2 Original line number Diff line number Diff line Loading @@ -1640,8 +1640,23 @@ public class CallAudioRouteStateMachine extends StateMachine { private void setSpeakerphoneOn(boolean on) { Log.i(this, "turning speaker phone %s", on); mAudioManager.setSpeakerphoneOn(on); mStatusBarNotifier.notifySpeakerphone(on); AudioDeviceInfo speakerDevice = null; for (AudioDeviceInfo info : mAudioManager.getAvailableCommunicationDevices()) { if (info.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) { speakerDevice = info; break; } } boolean speakerOn = false; if (speakerDevice != null && on) { boolean result = mAudioManager.setCommunicationDevice(speakerDevice); if (result) { speakerOn = true; } } else { mAudioManager.clearCommunicationDevice(); } mStatusBarNotifier.notifySpeakerphone(speakerOn); } private void setBluetoothOn(String address) { Loading src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -214,6 +214,10 @@ public class BluetoothDeviceManager { // Let's get devices which are a group leaders ArrayList<BluetoothDevice> devices = new ArrayList<>(); if (mGroupsByDevice.isEmpty() || mBluetoothLeAudioService == null) { return devices; } for (LinkedHashMap.Entry<BluetoothDevice, Integer> entry : mGroupsByDevice.entrySet()) { if (Objects.equals(entry.getKey(), mBluetoothLeAudioService.getConnectedGroupLeadDevice(entry.getValue()))) { Loading Loading @@ -330,6 +334,14 @@ public class BluetoothDeviceManager { Log.w(this, "LE audio service null when receiving device added broadcast"); return; } /* Check if group is known. */ if (!mGroupsByDevice.containsKey(device)) { int groupId = mBluetoothLeAudioService.getGroupId(device); /* If it is not yet assigned, then it will be provided in the callback */ if (groupId != BluetoothLeAudio.GROUP_ID_INVALID) { mGroupsByDevice.put(device, groupId); } } targetDeviceMap = mLeAudioDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEARING_AID) { if (mBluetoothHearingAid == null) { Loading tests/src/com/android/server/telecom/tests/BasicCallTests.java +7 −3 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.IContentProvider; import android.content.pm.PackageManager; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.net.Uri; import android.os.Binder; Loading Loading @@ -637,14 +638,17 @@ public class BasicCallTests extends TelecomSystemTest { mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER, null); waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); verify(audioManager, timeout(TEST_TIMEOUT)) .setSpeakerphoneOn(true); ArgumentCaptor<AudioDeviceInfo> infoArgumentCaptor = ArgumentCaptor.forClass(AudioDeviceInfo.class); verify(audioManager, timeout(TEST_TIMEOUT)).setCommunicationDevice( infoArgumentCaptor.capture()); assertEquals(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, infoArgumentCaptor.getValue().getType()); mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE, null); waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); // setSpeakerPhoneOn(false) gets called once during the call initiation phase verify(audioManager, timeout(TEST_TIMEOUT).atLeast(1)) .setSpeakerphoneOn(false); .clearCommunicationDevice(); mConnectionServiceFixtureA. sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE); Loading tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -195,6 +195,45 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase { assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); } @SmallTest @Test public void testLeAudioMissedGroupCallbackBeforeConnected() { /* This should be called on connection state changed */ when(mBluetoothLeAudio.getGroupId(device5)).thenReturn(1); when(mBluetoothLeAudio.getGroupId(device6)).thenReturn(1); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); assertEquals(1, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); } @SmallTest @Test public void testLeAudioGroupAvailableBeforeConnect() { /* Device is known (e.g. from storage) */ leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1); /* Make sure getGroupId is not called for known devices */ verify(mBluetoothLeAudio, never()).getGroupId(device5); verify(mBluetoothLeAudio, never()).getGroupId(device6); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); assertEquals(1, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); } @SmallTest @Test public void testHearingAidDedup() { Loading tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java +5 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.IAudioService; import android.os.HandlerThread; Loading Loading @@ -562,7 +563,10 @@ public class CallAudioRouteStateMachineTest extends TelecomTestCase { // Make sure that we've successfully switched to the active speaker route and that we've // called setSpeakerOn assertTrue(stateMachine.isInActiveState()); verify(mockAudioManager).setSpeakerphoneOn(true); ArgumentCaptor<AudioDeviceInfo> infoArgumentCaptor = ArgumentCaptor.forClass( AudioDeviceInfo.class); verify(mockAudioManager).setCommunicationDevice(infoArgumentCaptor.capture()); assertEquals(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, infoArgumentCaptor.getValue().getType()); } @SmallTest Loading Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +17 −2 Original line number Diff line number Diff line Loading @@ -1640,8 +1640,23 @@ public class CallAudioRouteStateMachine extends StateMachine { private void setSpeakerphoneOn(boolean on) { Log.i(this, "turning speaker phone %s", on); mAudioManager.setSpeakerphoneOn(on); mStatusBarNotifier.notifySpeakerphone(on); AudioDeviceInfo speakerDevice = null; for (AudioDeviceInfo info : mAudioManager.getAvailableCommunicationDevices()) { if (info.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) { speakerDevice = info; break; } } boolean speakerOn = false; if (speakerDevice != null && on) { boolean result = mAudioManager.setCommunicationDevice(speakerDevice); if (result) { speakerOn = true; } } else { mAudioManager.clearCommunicationDevice(); } mStatusBarNotifier.notifySpeakerphone(speakerOn); } private void setBluetoothOn(String address) { Loading
src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -214,6 +214,10 @@ public class BluetoothDeviceManager { // Let's get devices which are a group leaders ArrayList<BluetoothDevice> devices = new ArrayList<>(); if (mGroupsByDevice.isEmpty() || mBluetoothLeAudioService == null) { return devices; } for (LinkedHashMap.Entry<BluetoothDevice, Integer> entry : mGroupsByDevice.entrySet()) { if (Objects.equals(entry.getKey(), mBluetoothLeAudioService.getConnectedGroupLeadDevice(entry.getValue()))) { Loading Loading @@ -330,6 +334,14 @@ public class BluetoothDeviceManager { Log.w(this, "LE audio service null when receiving device added broadcast"); return; } /* Check if group is known. */ if (!mGroupsByDevice.containsKey(device)) { int groupId = mBluetoothLeAudioService.getGroupId(device); /* If it is not yet assigned, then it will be provided in the callback */ if (groupId != BluetoothLeAudio.GROUP_ID_INVALID) { mGroupsByDevice.put(device, groupId); } } targetDeviceMap = mLeAudioDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEARING_AID) { if (mBluetoothHearingAid == null) { Loading
tests/src/com/android/server/telecom/tests/BasicCallTests.java +7 −3 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.IContentProvider; import android.content.pm.PackageManager; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.net.Uri; import android.os.Binder; Loading Loading @@ -637,14 +638,17 @@ public class BasicCallTests extends TelecomSystemTest { mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER, null); waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); verify(audioManager, timeout(TEST_TIMEOUT)) .setSpeakerphoneOn(true); ArgumentCaptor<AudioDeviceInfo> infoArgumentCaptor = ArgumentCaptor.forClass(AudioDeviceInfo.class); verify(audioManager, timeout(TEST_TIMEOUT)).setCommunicationDevice( infoArgumentCaptor.capture()); assertEquals(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, infoArgumentCaptor.getValue().getType()); mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE, null); waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); // setSpeakerPhoneOn(false) gets called once during the call initiation phase verify(audioManager, timeout(TEST_TIMEOUT).atLeast(1)) .setSpeakerphoneOn(false); .clearCommunicationDevice(); mConnectionServiceFixtureA. sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE); Loading
tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -195,6 +195,45 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase { assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); } @SmallTest @Test public void testLeAudioMissedGroupCallbackBeforeConnected() { /* This should be called on connection state changed */ when(mBluetoothLeAudio.getGroupId(device5)).thenReturn(1); when(mBluetoothLeAudio.getGroupId(device6)).thenReturn(1); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); assertEquals(1, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); } @SmallTest @Test public void testLeAudioGroupAvailableBeforeConnect() { /* Device is known (e.g. from storage) */ leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1); /* Make sure getGroupId is not called for known devices */ verify(mBluetoothLeAudio, never()).getGroupId(device5); verify(mBluetoothLeAudio, never()).getGroupId(device6); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); receiverUnderTest.onReceive(mContext, buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); assertEquals(1, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); } @SmallTest @Test public void testHearingAidDedup() { Loading
tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java +5 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.IAudioService; import android.os.HandlerThread; Loading Loading @@ -562,7 +563,10 @@ public class CallAudioRouteStateMachineTest extends TelecomTestCase { // Make sure that we've successfully switched to the active speaker route and that we've // called setSpeakerOn assertTrue(stateMachine.isInActiveState()); verify(mockAudioManager).setSpeakerphoneOn(true); ArgumentCaptor<AudioDeviceInfo> infoArgumentCaptor = ArgumentCaptor.forClass( AudioDeviceInfo.class); verify(mockAudioManager).setCommunicationDevice(infoArgumentCaptor.capture()); assertEquals(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, infoArgumentCaptor.getValue().getType()); } @SmallTest Loading