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

Commit e77fbcba authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Handling hearing aid devices correctly

This CL handles broacasts on the Hearing Aid profile, which was ignored.

In addition, we don't receive the broadcast about the bond state of
BT devices since what we're interested in is "connected devices" not
"paired devices".
When a new device is paired/forgotten, it becomes connected/disconnected so
it is sufficient to see connection state of devices.

Bug: 157282893
Test: manually w/ A2dp devices repeating pair/forget.
Change-Id: Ie66544ba4cb82fc6002f6265613df1e7f1201a92
parent f28c0b6f
Loading
Loading
Loading
Loading
+12 −40
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.media;
package com.android.server.media;


import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO;

import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothA2dp;
@@ -100,9 +102,6 @@ class BluetoothRouteProvider {
        // Bluetooth on/off broadcasts
        // Bluetooth on/off broadcasts
        addEventReceiver(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedReceiver());
        addEventReceiver(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedReceiver());


        // Pairing broadcasts
        addEventReceiver(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedReceiver());

        DeviceStateChangedRecevier deviceStateChangedReceiver = new DeviceStateChangedRecevier();
        DeviceStateChangedRecevier deviceStateChangedReceiver = new DeviceStateChangedRecevier();
        addEventReceiver(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, deviceStateChangedReceiver);
        addEventReceiver(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, deviceStateChangedReceiver);
        addEventReceiver(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, deviceStateChangedReceiver);
        addEventReceiver(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, deviceStateChangedReceiver);
@@ -129,19 +128,12 @@ class BluetoothRouteProvider {


        BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(routeId);
        BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(routeId);
        if (btRouteInfo == null) {
        if (btRouteInfo == null) {
            Slog.w(TAG, "setActiveDevice: unknown route id=" + routeId);
            Slog.w(TAG, "transferTo: unknown route id=" + routeId);
            return;
            return;
        }
        }
        BluetoothA2dp a2dpProfile = mA2dpProfile;
        BluetoothHearingAid hearingAidProfile = mHearingAidProfile;


        if (a2dpProfile != null
        if (mBluetoothAdapter != null) {
                && btRouteInfo.connectedProfiles.get(BluetoothProfile.A2DP, false)) {
            mBluetoothAdapter.setActiveDevice(btRouteInfo.btDevice, ACTIVE_DEVICE_AUDIO);
            a2dpProfile.setActiveDevice(btRouteInfo.btDevice);
        }
        if (hearingAidProfile != null
                && btRouteInfo.connectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
            hearingAidProfile.setActiveDevice(btRouteInfo.btDevice);
        }
        }
    }
    }


@@ -149,13 +141,8 @@ class BluetoothRouteProvider {
     * Clears the active device for all known profiles.
     * Clears the active device for all known profiles.
     */
     */
    private void clearActiveDevices() {
    private void clearActiveDevices() {
        BluetoothA2dp a2dpProfile = mA2dpProfile;
        if (mBluetoothAdapter != null) {
        BluetoothHearingAid hearingAidProfile = mHearingAidProfile;
            mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_AUDIO);
        if (a2dpProfile != null) {
            a2dpProfile.setActiveDevice(null);
        }
        if (hearingAidProfile != null) {
            hearingAidProfile.setActiveDevice(null);
        }
        }
    }
    }


@@ -274,7 +261,6 @@ class BluetoothRouteProvider {
            return;
            return;
        }
        }


        // Update volume when the connection state is changed.
        MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.route)
        MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.route)
                .setConnectionState(state);
                .setConnectionState(state);
        builder.setType(btRoute.getRouteType());
        builder.setType(btRoute.getRouteType());
@@ -321,7 +307,7 @@ class BluetoothRouteProvider {
                default:
                default:
                    return;
                    return;
            }
            }
            //TODO: Check a pair of HAP devices whether there exist two or more active devices.
            //TODO(b/157708273): Handle two active devices in the binaural case.
            for (BluetoothDevice device : proxy.getConnectedDevices()) {
            for (BluetoothDevice device : proxy.getConnectedDevices()) {
                BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
                BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
                if (btRoute == null) {
                if (btRoute == null) {
@@ -383,29 +369,12 @@ class BluetoothRouteProvider {
        }
        }
    }
    }


    private class BondStateChangedReceiver implements BluetoothEventReceiver {
        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                    BluetoothDevice.ERROR);
            BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
            if (bondState == BluetoothDevice.BOND_BONDED && btRoute == null) {
                btRoute = createBluetoothRoute(device);
                if (btRoute.connectedProfiles.size() > 0) {
                    mBluetoothRoutes.put(device.getAddress(), btRoute);
                    notifyBluetoothRoutesUpdated();
                }
            } else if (bondState == BluetoothDevice.BOND_NONE
                    && mBluetoothRoutes.remove(device.getAddress()) != null) {
                notifyBluetoothRoutesUpdated();
            }
        }
    }

    private class DeviceStateChangedRecevier implements BluetoothEventReceiver {
    private class DeviceStateChangedRecevier implements BluetoothEventReceiver {
        @Override
        @Override
        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
            switch (intent.getAction()) {
            switch (intent.getAction()) {
                case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
                case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
                case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED:
                    if (mSelectedRoute == null
                    if (mSelectedRoute == null
                            || !mSelectedRoute.btDevice.equals(device)) {
                            || !mSelectedRoute.btDevice.equals(device)) {
                        if (mSelectedRoute != null) {
                        if (mSelectedRoute != null) {
@@ -424,6 +393,9 @@ class BluetoothRouteProvider {
                case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
                case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
                    handleConnectionStateChanged(BluetoothProfile.A2DP, intent, device);
                    handleConnectionStateChanged(BluetoothProfile.A2DP, intent, device);
                    break;
                    break;
                case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
                    handleConnectionStateChanged(BluetoothProfile.HEARING_AID, intent, device);
                    break;
            }
            }
        }
        }