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

Commit ea9881f3 authored by Grzegorz Kołodziejczyk's avatar Grzegorz Kołodziejczyk
Browse files

Set communication device when device become active Bluetooth device

There is no need to double time set device as communication device.
First one when connecting audio in Telecomm and second time when device
becomes active (send ACTIVE_DEVICE_CHANGED broadcast intent).

Only already active device can be communication device, it can be
directly set (not changing audio device).

Tag: #feature
Bug: 258555681
Test: atest GoogleBluetoothInstrumentationTests
Change-Id: I559e1ba6880cd6d429031b81622bf30c981526e2
parent 3fa4d5b0
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -558,7 +558,7 @@ public class BluetoothDeviceManager {

    // 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) {
    public boolean connectAudio(String address, boolean switchingBtDevices) {
        if (mLeAudioDevicesByAddress.containsKey(address)) {
            if (mBluetoothLeAudioService == null) {
                Log.w(this, "Attempting to turn on audio when the le audio service is null");
@@ -567,8 +567,16 @@ public class BluetoothDeviceManager {
            BluetoothDevice device = mLeAudioDevicesByAddress.get(address);
            if (mBluetoothAdapter.setActiveDevice(
                    device, BluetoothAdapter.ACTIVE_DEVICE_ALL)) {

                /* ACTION_ACTIVE_DEVICE_CHANGED intent will trigger setting communication device.
                 * Only after receiving ACTION_ACTIVE_DEVICE_CHANGED it is known that device that
                 * will be audio switched to is available to be choose as communication device */
                if (!switchingBtDevices) {
                    return setLeAudioCommunicationDevice();
                }

                return true;
            }
            return false;
        } else if (mHearingAidDevicesByAddress.containsKey(address)) {
            if (mBluetoothHearingAid == null) {
@@ -578,8 +586,16 @@ public class BluetoothDeviceManager {
            if (mBluetoothAdapter.setActiveDevice(
                    mHearingAidDevicesByAddress.get(address),
                    BluetoothAdapter.ACTIVE_DEVICE_ALL)) {

                /* ACTION_ACTIVE_DEVICE_CHANGED intent will trigger setting communication device.
                 * Only after receiving ACTION_ACTIVE_DEVICE_CHANGED it is known that device that
                 * will be audio switched to is available to be choose as communication device */
                if (!switchingBtDevices) {
                    return setHearingAidCommunicationDevice();
                }

                return true;
            }
            return false;
        } else if (mHfpDevicesByAddress.containsKey(address)) {
            BluetoothDevice device = mHfpDevicesByAddress.get(address);
+1 −1
Original line number Diff line number Diff line
@@ -713,7 +713,7 @@ public class BluetoothRouteManager extends StateMachine {
            return null;
        }

        if (!mDeviceManager.connectAudio(actualAddress)) {
        if (!mDeviceManager.connectAudio(actualAddress, switchingBtDevices)) {
            boolean shouldRetry = retryCount < MAX_CONNECTION_RETRIES;
            Log.w(LOG_TAG, "Could not connect to %s. Will %s", actualAddress,
                    shouldRetry ? "retry" : "not retry");
+36 −5
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
                        BluetoothDeviceManager.DEVICE_TYPE_HEADSET));
        when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class),
                    eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true);
        mBluetoothDeviceManager.connectAudio(device1.getAddress());
        mBluetoothDeviceManager.connectAudio(device1.getAddress(), false);
        verify(mAdapter).setActiveDevice(device1, BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL);
        verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class),
                eq(BluetoothAdapter.ACTIVE_DEVICE_ALL));
@@ -415,12 +415,15 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        when(mockAudioManager.setCommunicationDevice(eq(mockAudioDeviceInfo)))
                .thenReturn(true);

        mBluetoothDeviceManager.connectAudio(device5.getAddress());
        mBluetoothDeviceManager.connectAudio(device5.getAddress(), false);
        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));

        receiverUnderTest.onReceive(mContext, buildActiveDeviceChangeActionIntent(device5,
                BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID));

        when(mockAudioManager.getCommunicationDevice()).thenReturn(mockAudioDeviceInfo);
        mBluetoothDeviceManager.disconnectAudio();
        verify(mockAudioManager).clearCommunicationDevice();
@@ -447,12 +450,15 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        when(mockAudioManager.setCommunicationDevice(mockAudioDeviceInfo))
                       .thenReturn(true);

        mBluetoothDeviceManager.connectAudio(device5.getAddress());
        mBluetoothDeviceManager.connectAudio(device5.getAddress(), false);
        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));

        receiverUnderTest.onReceive(mContext, buildActiveDeviceChangeActionIntent(device5,
                BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO));

        mBluetoothDeviceManager.disconnectAudio();
        verify(mockAudioManager).clearCommunicationDevice();
    }
@@ -471,7 +477,7 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1);
        when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class),
                eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true);
        mBluetoothDeviceManager.connectAudio(device5.getAddress());
        mBluetoothDeviceManager.connectAudio(device5.getAddress(), false);
        verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL);
        verify(mBluetoothHeadset, never()).connectAudio();
        verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class),
@@ -484,7 +490,7 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
                buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device5,
                        BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO));

        mBluetoothDeviceManager.connectAudio(device6.getAddress());
        mBluetoothDeviceManager.connectAudio(device6.getAddress(), false);
        verify(mAdapter).setActiveDevice(device6, BluetoothAdapter.ACTIVE_DEVICE_ALL);
    }

@@ -530,6 +536,31 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        return i;
    }


    private Intent buildActiveDeviceChangeActionIntent(BluetoothDevice device, int deviceType) {
        String intentString;

        switch (deviceType) {
            case BluetoothDeviceManager.DEVICE_TYPE_HEADSET:
                intentString = BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED;
                break;
            case BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID:
                intentString = BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED;
                break;
            case BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO:
                intentString = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED;
                break;
            default:
                return null;
        }

        Intent i = new Intent(intentString);
        i.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        return i;
    }

    private BluetoothDevice makeBluetoothDevice(String address) {
        Parcel p1 = Parcel.obtain();
        p1.writeString(address);
+3 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import java.util.stream.Stream;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.reset;
@@ -245,6 +246,7 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
    }

    private void verifyConnectionAttempt(BluetoothDevice device, int numTimes) {
        verify(mDeviceManager, times(numTimes)).connectAudio(device.getAddress());
        verify(mDeviceManager, times(numTimes)).connectAudio(eq(device.getAddress()),
            anyBoolean());
    }
}
+10 −5
Original line number Diff line number Diff line
@@ -359,18 +359,22 @@ public class BluetoothRouteTransitionTests extends TelecomTestCase {

        switch (mParams.expectedBluetoothInteraction) {
            case NONE:
                verify(mDeviceManager, never()).connectAudio(nullable(String.class));
                verify(mDeviceManager, never()).connectAudio(nullable(String.class),
                    any(boolean.class));
                break;
            case CONNECT:
                verify(mDeviceManager).connectAudio(mParams.expectedConnectionDevice.getAddress());
                verify(mDeviceManager).connectAudio(mParams.expectedConnectionDevice.getAddress(),
                    false);
                verify(mDeviceManager, never()).disconnectAudio();
                break;
            case CONNECT_SWITCH_DEVICE:
                verify(mDeviceManager).disconnectAudio();
                verify(mDeviceManager).connectAudio(mParams.expectedConnectionDevice.getAddress());
                verify(mDeviceManager).connectAudio(mParams.expectedConnectionDevice.getAddress(),
                    true);
            break;
            case DISCONNECT:
                verify(mDeviceManager, never()).connectAudio(nullable(String.class));
                verify(mDeviceManager, never()).connectAudio(nullable(String.class),
                    any(boolean.class));
                verify(mDeviceManager).disconnectAudio();
                break;
        }
@@ -402,7 +406,8 @@ public class BluetoothRouteTransitionTests extends TelecomTestCase {
        when(mDeviceManager.getBluetoothHeadset()).thenReturn(mBluetoothHeadset);
        when(mDeviceManager.getBluetoothHearingAid()).thenReturn(mBluetoothHearingAid);
        when(mDeviceManager.getLeAudioService()).thenReturn(mBluetoothLeAudio);
        when(mDeviceManager.connectAudio(nullable(String.class))).thenReturn(true);
        when(mDeviceManager.connectAudio(nullable(String.class), any(boolean.class)))
            .thenReturn(true);
        when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
                nullable(ContentResolver.class))).thenReturn(100000L);
        when(mTimeoutsAdapter.getBluetoothPendingTimeoutMillis(