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

Commit e78816e3 authored by Sungsoo Lim's avatar Sungsoo Lim
Browse files

Refactoring: Audio Routing Handler (Step 3)

This CL refactors connection and activation events to be handled in
the AudioRoutingHandler. This will remove the mLock and migrate the
variables guarded by the mLock into the handler.

It will also remove the priority of hearing aid devices so that they
are activated at the same level as other BT devices.

This CL refactors the connection events of hearing aid, and more CLs
will follow.

Bug: 299023147
Test: atest BluetoothInstrumentationTests
Change-Id: I60a21b601676294a2bd6eb27473286f37323517a
parent 27bd31f4
Loading
Loading
Loading
Loading
+35 −68
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -131,17 +130,10 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                case BluetoothProfile.A2DP:
                case BluetoothProfile.HEADSET:
                case BluetoothProfile.LE_AUDIO:
                    mHandler.post(() -> mHandler.handleDeviceConnected(device, profile));
                    break;
                case BluetoothProfile.HEARING_AID:
                    mHandler.post(
                            () -> {
                                AudioRoutingHandler.AudioRoutingDevice arDevice =
                                        mHandler.getAudioRoutingDevice(device);
                                arDevice.connectedProfiles.add(profile);
                                handleHearingAidConnected(device);
                            });
                    mHandler.post(() -> mHandler.handleDeviceConnected(device, profile));
                    break;

                case BluetoothProfile.HAP_CLIENT:
                    mHandler.post(
                            () -> {
@@ -157,16 +149,8 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                case BluetoothProfile.A2DP:
                case BluetoothProfile.HEADSET:
                case BluetoothProfile.LE_AUDIO:
                    mHandler.post(() -> mHandler.handleDeviceDisconnected(device, profile));
                    break;
                case BluetoothProfile.HEARING_AID:
                    mHandler.post(
                            () -> {
                                AudioRoutingHandler.AudioRoutingDevice arDevice =
                                        mHandler.getAudioRoutingDevice(device);
                                arDevice.connectedProfiles.remove(profile);
                                handleHearingAidDisconnected(device);
                            });
                    mHandler.post(() -> mHandler.handleDeviceDisconnected(device, profile));
                    break;
                case BluetoothProfile.HAP_CLIENT:
                    mHandler.post(
@@ -194,7 +178,9 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                mHandler.post(
                        () -> {
                            if (device != null) {
                                mHandler.mActiveDevices.put(profile, Arrays.asList(device));
                                ArrayList<BluetoothDevice> devices = new ArrayList<>();
                                devices.add(device);
                                mHandler.mActiveDevices.put(profile, devices);
                            } else {
                                mHandler.mActiveDevices.remove(profile);
                            }
@@ -205,7 +191,9 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                mHandler.post(
                        () -> {
                            if (device != null) {
                                mHandler.mActiveDevices.put(profile, Arrays.asList(device));
                                ArrayList<BluetoothDevice> devices = new ArrayList<>();
                                devices.add(device);
                                mHandler.mActiveDevices.put(profile, devices);
                            } else {
                                mHandler.mActiveDevices.remove(profile);
                            }
@@ -216,7 +204,9 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                mHandler.post(
                        () -> {
                            if (device != null) {
                                mHandler.mActiveDevices.put(profile, Arrays.asList(device));
                                ArrayList<BluetoothDevice> devices = new ArrayList<>();
                                devices.add(device);
                                mHandler.mActiveDevices.put(profile, devices);
                            } else {
                                mHandler.mActiveDevices.remove(profile);
                            }
@@ -227,7 +217,9 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                mHandler.post(
                        () -> {
                            if (device != null) {
                                mHandler.mActiveDevices.put(profile, Arrays.asList(device));
                                ArrayList<BluetoothDevice> devices = new ArrayList<>();
                                devices.add(device);
                                mHandler.mActiveDevices.put(profile, devices);
                            } else {
                                mHandler.mActiveDevices.remove(profile);
                            }
@@ -246,27 +238,6 @@ public class AudioRoutingManager extends ActiveDeviceManager {
        }
    }

    private void handleHearingAidConnected(BluetoothDevice device) {
        synchronized (mLock) {
            if (DBG) {
                Log.d(TAG, "handleHearingAidConnected: " + device);
            }
            if (mHearingAidConnectedDevices.contains(device)) {
                if (DBG) {
                    Log.d(TAG, "This device is already connected: " + device);
                }
                return;
            }
            mHearingAidConnectedDevices.add(device);
        }
        // New connected device: select it as active
        if (setHearingAidActiveDevice(device)) {
            setA2dpActiveDevice(null, true);
            setHfpActiveDevice(null);
            setLeAudioActiveDevice(null, true);
        }
    }

    private void handleHapConnected(BluetoothDevice device) {
        synchronized (mLock) {
            if (DBG) {
@@ -294,25 +265,6 @@ public class AudioRoutingManager extends ActiveDeviceManager {
        }
    }

    private void handleHearingAidDisconnected(BluetoothDevice device) {
        synchronized (mLock) {
            if (DBG) {
                Log.d(
                        TAG,
                        "handleHearingAidDisconnected: "
                                + device
                                + ", mHearingAidActiveDevices="
                                + mHearingAidActiveDevices);
            }
            mHearingAidConnectedDevices.remove(device);
            if (mHearingAidActiveDevices.remove(device) && mHearingAidActiveDevices.isEmpty()) {
                if (!setFallbackDeviceActiveLocked()) {
                    setHearingAidActiveDevice(null, false);
                }
            }
        }
    }

    private void handleHapDisconnected(BluetoothDevice device) {
        synchronized (mLock) {
            if (DBG) {
@@ -740,7 +692,6 @@ public class AudioRoutingManager extends ActiveDeviceManager {
            mHearingAidActiveDevices.clear();
            mHearingAidActiveDevices.addAll(hearingAidService.getConnectedPeerDevices(hiSyncId));
        }
        mHandler.mActiveDevices.put(BluetoothProfile.HEARING_AID, Arrays.asList(device));
        return true;
    }

@@ -1094,6 +1045,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                    case BluetoothProfile.HEADSET -> mHfpConnectedDevices.add(device);
                    case BluetoothProfile.A2DP -> mA2dpConnectedDevices.add(device);
                    case BluetoothProfile.LE_AUDIO -> mLeAudioConnectedDevices.add(device);
                    case BluetoothProfile.HEARING_AID -> mHearingAidConnectedDevices.add(device);
                }
            }
            if (isWatch(device)) {
@@ -1132,6 +1084,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                    case BluetoothProfile.HEADSET -> mHfpConnectedDevices.remove(device);
                    case BluetoothProfile.A2DP -> mA2dpConnectedDevices.remove(device);
                    case BluetoothProfile.LE_AUDIO -> mLeAudioConnectedDevices.remove(device);
                    case BluetoothProfile.HEARING_AID -> mHearingAidConnectedDevices.remove(device);
                }
            }
            List<BluetoothDevice> activeDevices = mActiveDevices.get(profile);
@@ -1338,14 +1291,14 @@ public class AudioRoutingManager extends ActiveDeviceManager {

            private boolean canActivateTogether(
                    int profile, BluetoothDevice device, List<BluetoothDevice> group) {
                if (group == null || group.isEmpty()) {
                if (device == null || group == null || group.isEmpty()) {
                    return false;
                }
                switch (profile) {
                    // TODO: handle HAP_CLIENT and HEARING_AID
                    case BluetoothProfile.LE_AUDIO:
                    // TODO: handle HAP_CLIENT
                    case BluetoothProfile.LE_AUDIO: {
                        final LeAudioService leAudioService = mFactory.getLeAudioService();
                        if (leAudioService == null || device == null) {
                        if (leAudioService == null) {
                            return false;
                        }
                        int groupId = leAudioService.getGroupId(device);
@@ -1353,6 +1306,20 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                                && groupId == leAudioService.getGroupId(group.get(0))) {
                            return true;
                        }
                        break;
                    }
                    case BluetoothProfile.HEARING_AID: {
                        final HearingAidService hearingAidService = mFactory.getHearingAidService();
                        if (hearingAidService == null) {
                            return false;
                        }
                        long hiSyncId = hearingAidService.getHiSyncId(device);
                        if (hiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID
                                && hiSyncId == hearingAidService.getHiSyncId(group.get(0))) {
                            return true;
                        }
                        break;
                    }
                }
                return false;
            }
+8 −7
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ public class AudioRoutingManagerTest {
    private ArrayList<BluetoothDevice> mDeviceConnectionStack;
    private BluetoothDevice mMostRecentDevice;
    private AudioRoutingManager mAudioRoutingManager;
    private long mHearingAidHiSyncId = 1010;
    private static final long HEARING_AID_HISYNC_ID = 1010;

    private static final int TIMEOUT_MS = 1_000;
    private static final int A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS =
@@ -156,8 +156,8 @@ public class AudioRoutingManagerTest {

        List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>();
        connectedHearingAidDevices.add(mHearingAidDevice);
        when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(mHearingAidHiSyncId);
        when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId))
        when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(HEARING_AID_HISYNC_ID);
        when(mHearingAidService.getConnectedPeerDevices(HEARING_AID_HISYNC_ID))
                .thenReturn(connectedHearingAidDevices);
    }

@@ -557,8 +557,9 @@ public class AudioRoutingManagerTest {
        List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>();
        connectedHearingAidDevices.add(mHearingAidDevice);
        connectedHearingAidDevices.add(mSecondaryAudioDevice);
        when(mHearingAidService.getHiSyncId(mSecondaryAudioDevice)).thenReturn(mHearingAidHiSyncId);
        when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId))
        when(mHearingAidService.getHiSyncId(mSecondaryAudioDevice))
                .thenReturn(HEARING_AID_HISYNC_ID);
        when(mHearingAidService.getConnectedPeerDevices(HEARING_AID_HISYNC_ID))
                .thenReturn(connectedHearingAidDevices);

        hearingAidConnected(mHearingAidDevice);
@@ -867,8 +868,8 @@ public class AudioRoutingManagerTest {
        List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>();
        connectedHearingAidDevices.add(mSecondaryAudioDevice);
        when(mHearingAidService.getHiSyncId(mSecondaryAudioDevice))
                .thenReturn(mHearingAidHiSyncId + 1);
        when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId + 1))
                .thenReturn(HEARING_AID_HISYNC_ID + 1);
        when(mHearingAidService.getConnectedPeerDevices(HEARING_AID_HISYNC_ID + 1))
                .thenReturn(connectedHearingAidDevices);

        hearingAidConnected(mSecondaryAudioDevice);