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

Commit 08b9ee36 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Track LE hearing aid connected devices" into tm-qpr-dev

parents c7541283 4237e571
Loading
Loading
Loading
Loading
+94 −3
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.SuppressLint;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
@@ -116,6 +117,8 @@ class ActiveDeviceManager {
    private static final int MESSAGE_HEARING_AID_ACTION_ACTIVE_DEVICE_CHANGED = 6;
    private static final int MESSAGE_LE_AUDIO_ACTION_CONNECTION_STATE_CHANGED = 8;
    private static final int MESSAGE_LE_AUDIO_ACTION_ACTIVE_DEVICE_CHANGED = 9;
    private static final int MESSAGE_HAP_ACTION_CONNECTION_STATE_CHANGED = 10;
    private static final int MESSAGE_HAP_ACTION_ACTIVE_DEVICE_CHANGED = 11;

    private final AdapterService mAdapterService;
    private final ServiceFactory mFactory;
@@ -127,10 +130,12 @@ class ActiveDeviceManager {
    private final List<BluetoothDevice> mA2dpConnectedDevices = new LinkedList<>();
    private final List<BluetoothDevice> mHfpConnectedDevices = new LinkedList<>();
    private final List<BluetoothDevice> mLeAudioConnectedDevices = new LinkedList<>();
    private final List<BluetoothDevice> mLeHearingAidConnectedDevices = new LinkedList<>();
    private BluetoothDevice mA2dpActiveDevice = null;
    private BluetoothDevice mHfpActiveDevice = null;
    private BluetoothDevice mHearingAidActiveDevice = null;
    private BluetoothDevice mLeAudioActiveDevice = null;
    private BluetoothDevice mLeHearingAidActiveDevice = null;

    // Broadcast receiver for all changes
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -174,6 +179,14 @@ class ActiveDeviceManager {
                    mHandler.obtainMessage(MESSAGE_LE_AUDIO_ACTION_ACTIVE_DEVICE_CHANGED,
                            intent).sendToTarget();
                    break;
                case BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED:
                    mHandler.obtainMessage(MESSAGE_HAP_ACTION_CONNECTION_STATE_CHANGED,
                            intent).sendToTarget();
                    break;
                case BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE:
                    mHandler.obtainMessage(MESSAGE_HAP_ACTION_ACTIVE_DEVICE_CHANGED,
                            intent).sendToTarget();
                    break;
                default:
                    Log.e(TAG, "Received unexpected intent, action=" + action);
                    break;
@@ -223,7 +236,7 @@ class ActiveDeviceManager {
                            break;      // The device is already connected
                        }
                        mA2dpConnectedDevices.add(device);
                        if (mHearingAidActiveDevice == null) {
                        if (mHearingAidActiveDevice == null && mLeHearingAidActiveDevice == null) {
                            // New connected device: select it as active
                            setA2dpActiveDevice(device);
                            setLeAudioActiveDevice(null);
@@ -285,7 +298,7 @@ class ActiveDeviceManager {
                            break;      // The device is already connected
                        }
                        mHfpConnectedDevices.add(device);
                        if (mHearingAidActiveDevice == null) {
                        if (mHearingAidActiveDevice == null && mLeHearingAidActiveDevice == null) {
                            // New connected device: select it as active
                            setHfpActiveDevice(device);
                            setLeAudioActiveDevice(null);
@@ -364,7 +377,7 @@ class ActiveDeviceManager {
                            break;      // The device is already connected
                        }
                        mLeAudioConnectedDevices.add(device);
                        if (mHearingAidActiveDevice == null) {
                        if (mHearingAidActiveDevice == null && mLeHearingAidActiveDevice == null) {
                            // New connected device: select it as active
                            setLeAudioActiveDevice(device);
                            setA2dpActiveDevice(null);
@@ -407,6 +420,79 @@ class ActiveDeviceManager {
                    mLeAudioActiveDevice = device;
                }
                break;

                case MESSAGE_HAP_ACTION_CONNECTION_STATE_CHANGED: {
                    Intent intent = (Intent) msg.obj;
                    BluetoothDevice device =
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    int prevState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
                    int nextState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
                    if (prevState == nextState) {
                        // Nothing has changed
                        break;
                    }
                    if (nextState == BluetoothProfile.STATE_CONNECTED) {
                        // Device connected
                        if (DBG) {
                            Log.d(TAG, "handleMessage(MESSAGE_HAP_ACTION_CONNECTION_STATE"
                                    + "_CHANGED): device " + device + " connected");
                        }
                        if (mLeHearingAidConnectedDevices.contains(device)) {
                            break;      // The device is already connected
                        }
                        mLeHearingAidConnectedDevices.add(device);
                        if (!mLeAudioConnectedDevices.contains(device)) {
                            mLeAudioConnectedDevices.add(device);
                        }
                        // New connected device: select it as active
                        setLeAudioActiveDevice(device);
                        if (mLeAudioActiveDevice == device) {
                            // setLeAudioActiveDevice succeed
                            mLeHearingAidActiveDevice = device;
                        }
                        setA2dpActiveDevice(null);
                        setHfpActiveDevice(null);
                        break;
                    }
                    if (prevState == BluetoothProfile.STATE_CONNECTED) {
                        // Device disconnected
                        if (DBG) {
                            Log.d(TAG, "handleMessage(MESSAGE_HAP_ACTION_CONNECTION_STATE"
                                    + "_CHANGED): device " + device + " disconnected");
                        }
                        mLeHearingAidConnectedDevices.remove(device);
                        mLeAudioConnectedDevices.remove(device);
                        // mLeAudioConnectedDevices should contain all of
                        // mLeHearingAidConnectedDevices. Call setLeAudioActiveDevice(null)
                        // only if there are no LE audio devices.
                        if (mLeAudioConnectedDevices.isEmpty()
                                && Objects.equals(mLeHearingAidConnectedDevices, device)) {
                            setLeAudioActiveDevice(null);
                        }
                    }
                }
                break;

                case MESSAGE_HAP_ACTION_ACTIVE_DEVICE_CHANGED: {
                    Intent intent = (Intent) msg.obj;
                    BluetoothDevice device =
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    if (device != null && !mLeAudioConnectedDevices.contains(device)) {
                        mLeAudioConnectedDevices.add(device);
                    }
                    if (DBG) {
                        Log.d(TAG, "handleMessage(MESSAGE_HAP_ACTION_ACTIVE_DEVICE_CHANGED): "
                                + "device= " + device);
                    }
                    // Just assign locally the new value
                    if (device != null && !Objects.equals(mLeHearingAidActiveDevice, device)) {
                        setA2dpActiveDevice(null);
                        setHfpActiveDevice(null);
                        setHearingAidActiveDevice(null);
                    }
                    mLeHearingAidActiveDevice = mLeAudioActiveDevice = device;
                }
                break;
            }
        }
    }
@@ -477,6 +563,8 @@ class ActiveDeviceManager {
        filter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
        filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
        filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
        filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
        filter.addAction(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE);
        mAdapterService.registerReceiver(mReceiver, filter);

        mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
@@ -565,6 +653,9 @@ class ActiveDeviceManager {
            return;
        }
        mLeAudioActiveDevice = device;
        if (device == null) {
            mLeHearingAidActiveDevice = null;
        }
    }

    private void resetState() {
+55 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.*;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
@@ -107,7 +108,7 @@ public class ActiveDeviceManagerTest {
        mA2dpHeadsetDevice = TestUtils.getTestDevice(mAdapter, 2);
        mHearingAidDevice = TestUtils.getTestDevice(mAdapter, 3);
        mLeAudioDevice = TestUtils.getTestDevice(mAdapter, 4);
        mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 4);
        mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 5);
    }

    @After
@@ -472,6 +473,29 @@ public class ActiveDeviceManagerTest {
        Assert.assertEquals(null, mActiveDeviceManager.getLeAudioActiveDevice());
    }

    /**
     * One LE Hearing Aid is connected.
     */
    @Test
    public void onlyLeHearingAIdConnected_setHeadsetActive() {
        leAudioConnected(mLeAudioDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice);
    }

    /**
     * LE audio is connected after LE Hearing Aid device.
     * Keep LE hearing Aid active.
     */
    @Test
    public void leAudioConnectedAfterLeHearingAid_setLeAudioActiveShouldNotBeCalled() {
        leHearingAidConnected(mSecondaryAudioDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice);

        leAudioConnected(mLeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());
        verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice);
    }

    /**
     * A wired audio device is connected. Then all active devices are set to null.
     */
@@ -590,4 +614,34 @@ public class ActiveDeviceManagerTest {
        mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
    }

    /**
     * Helper to indicate LE Hearing Aid connected for a device.
     */
    private void leHearingAidConnected(BluetoothDevice device) {
        Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
        mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
    }

    /**
     * Helper to indicate LE Hearing Aid disconnected for a device.
     */
    private void leHearingAidDisconnected(BluetoothDevice device) {
        Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED);
        mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
    }

    /**
     * Helper to indicate LE Audio Hearing Aid device changed for a device.
     */
    private void leHearingAidActiveDeviceChanged(BluetoothDevice device) {
        Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
    }
}