Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0fee4ae2 authored by Charlie Boutier's avatar Charlie Boutier Committed by Android (Google) Code Review
Browse files

Merge "Hearing Aid: Connect route when right HA is connected first" into main

parents 8c15cdc1 28ba74c4
Loading
Loading
Loading
Loading
+36 −7
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -134,7 +135,8 @@ public class BluetoothRouteManager extends StateMachine {
        @Override
        public void enter() {
            BluetoothDevice erroneouslyConnectedDevice = getBluetoothAudioConnectedDevice();
            if (erroneouslyConnectedDevice != null) {
            if (erroneouslyConnectedDevice != null &&
                !erroneouslyConnectedDevice.equals(mHearingAidActiveDeviceCache)) {
                Log.w(LOG_TAG, "Entering AudioOff state but device %s appears to be connected. " +
                        "Switching to audio-on state for that device.", erroneouslyConnectedDevice);
                // change this to just transition to the new audio on state
@@ -252,6 +254,27 @@ public class BluetoothRouteManager extends StateMachine {
            SomeArgs args = (SomeArgs) msg.obj;
            String address = (String) args.arg2;
            boolean switchingBtDevices = !Objects.equals(mDeviceAddress, address);

            if (switchingBtDevices == true) { // check if it is an hearing aid pair
                BluetoothAdapter bluetoothAdapter = mDeviceManager.getBluetoothAdapter();
                if (bluetoothAdapter != null) {
                    List<BluetoothDevice> activeHearingAids =
                      bluetoothAdapter.getActiveDevices(BluetoothProfile.HEARING_AID);
                    for (BluetoothDevice hearingAid : activeHearingAids) {
                        if (hearingAid != null) {
                            String hearingAidAddress = hearingAid.getAddress();
                            if (hearingAidAddress != null) {
                                if (hearingAidAddress.equals(address) ||
                                    hearingAidAddress.equals(mDeviceAddress)) {
                                    switchingBtDevices = false;
                                    break;
                                }
                            }
                        }
                    }

                }
            }
            try {
                switch (msg.what) {
                    case NEW_DEVICE_CONNECTED:
@@ -868,8 +891,13 @@ public class BluetoothRouteManager extends StateMachine {
                : mDeviceManager.isHearingAidSetAsCommunicationDevice();
        if (bluetoothHearingAid != null) {
            if (isHearingAidSetForCommunication) {
                for (BluetoothDevice device : bluetoothAdapter.getActiveDevices(
                        BluetoothProfile.HEARING_AID)) {
                List<BluetoothDevice> hearingAidsActiveDevices = bluetoothAdapter.getActiveDevices(
                        BluetoothProfile.HEARING_AID);
                if (hearingAidsActiveDevices.contains(mHearingAidActiveDeviceCache)) {
                    hearingAidActiveDevice = mHearingAidActiveDeviceCache;
                    activeDevices++;
                } else {
                    for (BluetoothDevice device : hearingAidsActiveDevices) {
                        if (device != null) {
                            hearingAidActiveDevice = device;
                            activeDevices++;
@@ -878,6 +906,7 @@ public class BluetoothRouteManager extends StateMachine {
                    }
                }
            }
        }

        boolean isLeAudioSetForCommunication =
                mFeatureFlags.callAudioCommunicationDeviceRefactor()
+75 −11
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -37,6 +38,8 @@ import android.os.Parcel;
import android.telecom.Log;
import android.test.suitebuilder.annotation.SmallTest;

import android.media.AudioDeviceInfo;

import com.android.internal.os.SomeArgs;
import com.android.server.telecom.CallAudioCommunicationDeviceTracker;
import com.android.server.telecom.TelecomSystem;
@@ -62,7 +65,14 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
    static final BluetoothDevice DEVICE1 = makeBluetoothDevice("00:00:00:00:00:01");
    static final BluetoothDevice DEVICE2 = makeBluetoothDevice("00:00:00:00:00:02");
    static final BluetoothDevice DEVICE3 = makeBluetoothDevice("00:00:00:00:00:03");
    static final BluetoothDevice HEARING_AID_DEVICE = makeBluetoothDevice("00:00:00:00:00:04");
    static final BluetoothDevice HEARING_AID_DEVICE_LEFT = makeBluetoothDevice("CA:FE:DE:CA:00:01");
    static final BluetoothDevice HEARING_AID_DEVICE_RIGHT =
      makeBluetoothDevice("CA:FE:DE:CA:00:02");
    // See HearingAidService#getActiveDevices
    // Note: It is really important that the left HA is the first one. The left HA is always
    // in the first index (0) and the right one in the second index (1).
    static final BluetoothDevice[] HEARING_AIDS =
      new BluetoothDevice[]{HEARING_AID_DEVICE_LEFT, HEARING_AID_DEVICE_RIGHT};

    @Mock private BluetoothAdapter mBluetoothAdapter;
    @Mock private BluetoothDeviceManager mDeviceManager;
@@ -85,6 +95,59 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
        super.tearDown();
    }

    @SmallTest
    @Test
    public void testConnectLeftHearingAidWhenLeftIsActive() {
        BluetoothRouteManager sm = setupStateMachine(
                BluetoothRouteManager.AUDIO_OFF_STATE_NAME, HEARING_AID_DEVICE_LEFT);
        sm.onActiveDeviceChanged(HEARING_AID_DEVICE_LEFT,
            BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID);
        when(mDeviceManager.connectAudio(anyString(), anyBoolean())).thenReturn(true);
        when(mDeviceManager.isHearingAidSetAsCommunicationDevice()).thenReturn(true);

        setupConnectedDevices(null, HEARING_AIDS, null, null, HEARING_AIDS, null);
        when(mBluetoothHeadset.getAudioState(nullable(BluetoothDevice.class)))
          .thenReturn(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);

        executeRoutingAction(sm,
            BluetoothRouteManager.NEW_DEVICE_CONNECTED, HEARING_AID_DEVICE_LEFT.getAddress());

        executeRoutingAction(sm,
            BluetoothRouteManager.CONNECT_BT, HEARING_AID_DEVICE_LEFT.getAddress());

        assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
            + ":" + HEARING_AID_DEVICE_LEFT.getAddress(), sm.getCurrentState().getName());

        sm.quitNow();
    }

    @SmallTest
    @Test
    public void testConnectRightHearingAidWhenLeftIsActive() {
        BluetoothRouteManager sm = setupStateMachine(
                BluetoothRouteManager.AUDIO_OFF_STATE_NAME, HEARING_AID_DEVICE_RIGHT);
        sm.onActiveDeviceChanged(HEARING_AID_DEVICE_LEFT,
            BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID);
        when(mDeviceManager.connectAudio(anyString(), anyBoolean())).thenReturn(true);
        when(mDeviceManager.isHearingAidSetAsCommunicationDevice()).thenReturn(true);


        setupConnectedDevices(null, HEARING_AIDS, null, null, HEARING_AIDS, null);
        when(mBluetoothHeadset.getAudioState(nullable(BluetoothDevice.class)))
          .thenReturn(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);

        executeRoutingAction(sm,
            BluetoothRouteManager.NEW_DEVICE_CONNECTED, HEARING_AID_DEVICE_LEFT.getAddress());

        executeRoutingAction(sm,
            BluetoothRouteManager.CONNECT_BT, HEARING_AID_DEVICE_LEFT.getAddress());

        assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
            + ":" + HEARING_AID_DEVICE_LEFT.getAddress(), sm.getCurrentState().getName());

        sm.quitNow();
    }

    @SmallTest
    @Test
    public void testConnectBtRetryWhileNotConnected() {
@@ -113,15 +176,15 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
        BluetoothRouteManager sm = setupStateMachine(
                BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, DEVICE1);
        setupConnectedDevices(new BluetoothDevice[]{DEVICE1},
                new BluetoothDevice[]{HEARING_AID_DEVICE}, new BluetoothDevice[]{DEVICE2},
                DEVICE1, HEARING_AID_DEVICE, DEVICE2);
                HEARING_AIDS, new BluetoothDevice[]{DEVICE2},
                DEVICE1,  HEARING_AIDS, DEVICE2);
        sm.onActiveDeviceChanged(DEVICE1, BluetoothDeviceManager.DEVICE_TYPE_HEADSET);
        sm.onActiveDeviceChanged(DEVICE2, BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO);
        sm.onActiveDeviceChanged(HEARING_AID_DEVICE,
        sm.onActiveDeviceChanged(HEARING_AID_DEVICE_LEFT,
                BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID);
        executeRoutingAction(sm, BluetoothRouteManager.BT_AUDIO_LOST, DEVICE1.getAddress());

        verifyConnectionAttempt(HEARING_AID_DEVICE, 0);
        verifyConnectionAttempt(HEARING_AID_DEVICE_LEFT, 0);
        verifyConnectionAttempt(DEVICE1, 0);
        verifyConnectionAttempt(DEVICE2, 0);
        assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
@@ -176,11 +239,11 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
    @Test
    public void testSkipInactiveBtDeviceWhenEvaluateActualState() {
        BluetoothRouteManager sm = setupStateMachine(
                BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, HEARING_AID_DEVICE);
        setupConnectedDevices(null, new BluetoothDevice[]{HEARING_AID_DEVICE},
                null, null, HEARING_AID_DEVICE, null);
                BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, HEARING_AID_DEVICE_LEFT);
        setupConnectedDevices(null, HEARING_AIDS,
                null, null, HEARING_AIDS, null);
        executeRoutingAction(sm, BluetoothRouteManager.BT_AUDIO_LOST,
                HEARING_AID_DEVICE.getAddress());
                HEARING_AID_DEVICE_LEFT.getAddress());
        assertEquals(BluetoothRouteManager.AUDIO_OFF_STATE_NAME, sm.getCurrentState().getName());
        sm.quitNow();
    }
@@ -227,10 +290,11 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {

    private void setupConnectedDevices(BluetoothDevice[] hfpDevices,
            BluetoothDevice[] hearingAidDevices, BluetoothDevice[] leAudioDevices,
            BluetoothDevice hfpActiveDevice, BluetoothDevice hearingAidActiveDevice,
            BluetoothDevice hfpActiveDevice, BluetoothDevice[] hearingAidActiveDevices,
            BluetoothDevice leAudioDevice) {
        if (hfpDevices == null) hfpDevices = new BluetoothDevice[]{};
        if (hearingAidDevices == null) hearingAidDevices = new BluetoothDevice[]{};
        if (hearingAidActiveDevices == null) hearingAidActiveDevices = new BluetoothDevice[]{};
        if (leAudioDevice == null) leAudioDevices = new BluetoothDevice[]{};

        when(mDeviceManager.getNumConnectedDevices()).thenReturn(
@@ -249,7 +313,7 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
        when(mBluetoothHearingAid.getConnectedDevices())
                .thenReturn(Arrays.asList(hearingAidDevices));
        when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.HEARING_AID)))
                .thenReturn(Arrays.asList(hearingAidActiveDevice, null));
                .thenReturn(Arrays.asList(hearingAidActiveDevices));
        when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.LE_AUDIO)))
                .thenReturn(Arrays.asList(leAudioDevice, null));
    }