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

Commit 6f3decfc authored by Sungsoo Lim's avatar Sungsoo Lim Committed by Gerrit Code Review
Browse files

Merge "Migrate the fallback device logic of A2dp and Hfp into AudioRoutingManager" into main

parents 4accb24f f9d15a0a
Loading
Loading
Loading
Loading
+82 −67
Original line number Original line Diff line number Diff line
@@ -334,6 +334,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                return;
                return;
            }
            }
            mHearingAidConnectedDevices.add(device);
            mHearingAidConnectedDevices.add(device);
        }
        // New connected device: select it as active
        // New connected device: select it as active
        if (setHearingAidActiveDevice(device)) {
        if (setHearingAidActiveDevice(device)) {
            setA2dpActiveDevice(null, true);
            setA2dpActiveDevice(null, true);
@@ -341,7 +342,6 @@ public class AudioRoutingManager extends ActiveDeviceManager {
            setLeAudioActiveDevice(null, true);
            setLeAudioActiveDevice(null, true);
        }
        }
    }
    }
    }


    private void handleLeAudioConnected(BluetoothDevice device) {
    private void handleLeAudioConnected(BluetoothDevice device) {
        synchronized (mLock) {
        synchronized (mLock) {
@@ -675,13 +675,13 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                            hearingAidService.getConnectedPeerDevices(hiSyncId));
                            hearingAidService.getConnectedPeerDevices(hiSyncId));
                }
                }
            }
            }
        }
        if (device != null) {
        if (device != null) {
            setA2dpActiveDevice(null, true);
            setA2dpActiveDevice(null, true);
            setHfpActiveDevice(null);
            setHfpActiveDevice(null);
            setLeAudioActiveDevice(null, true);
            setLeAudioActiveDevice(null, true);
        }
        }
    }
    }
    }


    private void handleLeAudioActiveDeviceChanged(BluetoothDevice device) {
    private void handleLeAudioActiveDeviceChanged(BluetoothDevice device) {
        synchronized (mLock) {
        synchronized (mLock) {
@@ -854,14 +854,15 @@ public class AudioRoutingManager extends ActiveDeviceManager {


    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    private boolean setHfpActiveDevice(BluetoothDevice device) {
    private boolean setHfpActiveDevice(BluetoothDevice device) {
        synchronized (mLock) {
        if (DBG) {
        if (DBG) {
            Log.d(TAG, "setHfpActiveDevice(" + device + ")");
            Log.d(TAG, "setHfpActiveDevice(" + device + ")");
        }
        }
        synchronized (mLock) {
            if (mPendingActiveDevice != null) {
            if (mPendingActiveDevice != null) {
                mHandler.removeCallbacksAndMessages(mPendingActiveDevice);
                mHandler.removeCallbacksAndMessages(mPendingActiveDevice);
                mPendingActiveDevice = null;
                mPendingActiveDevice = null;
            }
            }
        }
        final HeadsetService headsetService = mFactory.getHeadsetService();
        final HeadsetService headsetService = mFactory.getHeadsetService();
        if (headsetService == null) {
        if (headsetService == null) {
            return false;
            return false;
@@ -875,6 +876,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
        if (!headsetService.setActiveDevice(device)) {
        if (!headsetService.setActiveDevice(device)) {
            return false;
            return false;
        }
        }
        synchronized (mLock) {
            mHfpActiveDevice = device;
            mHfpActiveDevice = device;
        }
        }
        return true;
        return true;
@@ -938,7 +940,6 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                            + ")"
                            + ")"
                            + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
                            + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
        }
        }
        synchronized (mLock) {
        final LeAudioService leAudioService = mFactory.getLeAudioService();
        final LeAudioService leAudioService = mFactory.getLeAudioService();
        if (leAudioService == null) {
        if (leAudioService == null) {
            return false;
            return false;
@@ -954,6 +955,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
            return false;
            return false;
        }
        }


        synchronized (mLock) {
            mLeAudioActiveDevice = device;
            mLeAudioActiveDevice = device;
            if (device == null) {
            if (device == null) {
                mLeHearingAidActiveDevice = null;
                mLeHearingAidActiveDevice = null;
@@ -1025,45 +1027,33 @@ public class AudioRoutingManager extends ActiveDeviceManager {
            }
            }
        }
        }


        A2dpService a2dpService = mFactory.getA2dpService();
        List<BluetoothDevice> hfpFallbackCandidates = removeWatchDevices(mHfpConnectedDevices);
        BluetoothDevice a2dpFallbackDevice = null;
        List<BluetoothDevice> fallbackCandidates = new ArrayList<>();
        if (a2dpService != null) {
        fallbackCandidates.addAll(mLeAudioConnectedDevices);
            a2dpFallbackDevice = a2dpService.getFallbackDevice();
        }


        HeadsetService headsetService = mFactory.getHeadsetService();
        HeadsetService headsetService = mFactory.getHeadsetService();
        BluetoothDevice headsetFallbackDevice = null;
        if (headsetService != null) {
            headsetFallbackDevice = headsetService.getFallbackDevice();
        }

        List<BluetoothDevice> connectedDevices = new ArrayList<>();
        connectedDevices.addAll(mLeAudioConnectedDevices);
        switch (mAudioManager.getMode()) {
        switch (mAudioManager.getMode()) {
            case AudioManager.MODE_NORMAL:
            case AudioManager.MODE_NORMAL:
                if (a2dpFallbackDevice != null) {
                fallbackCandidates.addAll(mA2dpConnectedDevices);
                    connectedDevices.add(a2dpFallbackDevice);
                }
                break;
                break;
            case AudioManager.MODE_RINGTONE:
            case AudioManager.MODE_RINGTONE:
                if (headsetFallbackDevice != null && headsetService.isInbandRingingEnabled()) {
                if (headsetService.isInbandRingingEnabled()) {
                    connectedDevices.add(headsetFallbackDevice);
                    fallbackCandidates.addAll(hfpFallbackCandidates);
                }
                }
                break;
                break;
            default:
            default:
                if (headsetFallbackDevice != null) {
                fallbackCandidates.addAll(hfpFallbackCandidates);
                    connectedDevices.add(headsetFallbackDevice);
        }
        }
        }
        BluetoothDevice device =
        BluetoothDevice device = mDbManager.getMostRecentlyConnectedDevicesInList(connectedDevices);
                mDbManager.getMostRecentlyConnectedDevicesInList(fallbackCandidates);
        if (device != null) {
        if (device != null) {
            if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
            if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
                if (Objects.equals(a2dpFallbackDevice, device)) {
                if (mA2dpConnectedDevices.contains(device)) {
                    if (DBG) {
                    if (DBG) {
                        Log.d(TAG, "Found an A2DP fallback device: " + device);
                        Log.d(TAG, "Found an A2DP fallback device: " + device);
                    }
                    }
                    setA2dpActiveDevice(device);
                    setA2dpActiveDevice(device);
                    if (Objects.equals(headsetFallbackDevice, device)) {
                    if (hfpFallbackCandidates.contains(device)) {
                        setHfpActiveDevice(device);
                        setHfpActiveDevice(device);
                    } else {
                    } else {
                        setHfpActiveDevice(null);
                        setHfpActiveDevice(null);
@@ -1089,13 +1079,13 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                    setHearingAidActiveDevice(null, true);
                    setHearingAidActiveDevice(null, true);
                }
                }
            } else {
            } else {
                if (Objects.equals(headsetFallbackDevice, device)) {
                if (hfpFallbackCandidates.contains(device)) {
                    if (DBG) {
                    if (DBG) {
                        Log.d(TAG, "Found a HFP fallback device: " + device);
                        Log.d(TAG, "Found a HFP fallback device: " + device);
                    }
                    }
                    setHfpActiveDevice(device);
                    setHfpActiveDevice(device);
                    if (Objects.equals(a2dpFallbackDevice, device)) {
                    if (mA2dpConnectedDevices.contains(device)) {
                        setA2dpActiveDevice(a2dpFallbackDevice);
                        setA2dpActiveDevice(device);
                    } else {
                    } else {
                        setA2dpActiveDevice(null, true);
                        setA2dpActiveDevice(null, true);
                    }
                    }
@@ -1144,6 +1134,31 @@ public class AudioRoutingManager extends ActiveDeviceManager {
        }
        }
    }
    }


    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    List<BluetoothDevice> removeWatchDevices(List<BluetoothDevice> devices) {
        List<BluetoothDevice> fallbackCandidates;
        synchronized (mLock) {
            fallbackCandidates = new ArrayList<>(devices);
        }
        List<BluetoothDevice> uninterestedCandidates = new ArrayList<>();
        for (BluetoothDevice device : fallbackCandidates) {
            byte[] deviceType =
                    mDbManager.getCustomMeta(device, BluetoothDevice.METADATA_DEVICE_TYPE);
            BluetoothClass deviceClass = device.getBluetoothClass();
            if ((deviceClass != null
                            && deviceClass.getMajorDeviceClass()
                                    == BluetoothClass.Device.WEARABLE_WRIST_WATCH)
                    || (deviceType != null
                            && BluetoothDevice.DEVICE_TYPE_WATCH.equals(new String(deviceType)))) {
                uninterestedCandidates.add(device);
            }
        }
        for (BluetoothDevice device : uninterestedCandidates) {
            fallbackCandidates.remove(device);
        }
        return fallbackCandidates;
    }

    @VisibleForTesting
    @VisibleForTesting
    BluetoothDevice getA2dpActiveDevice() {
    BluetoothDevice getA2dpActiveDevice() {
        synchronized (mLock) {
        synchronized (mLock) {
+0 −26
Original line number Original line Diff line number Diff line
@@ -62,7 +62,6 @@ import org.mockito.MockitoAnnotations;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.Objects;


@MediumTest
@MediumTest
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidJUnit4.class)
@@ -146,31 +145,6 @@ public class AudioRoutingManagerTest {
        when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(mHearingAidHiSyncId);
        when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(mHearingAidHiSyncId);
        when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId))
        when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId))
                .thenReturn(connectedHearingAidDevices);
                .thenReturn(connectedHearingAidDevices);

        when(mA2dpService.getFallbackDevice())
                .thenAnswer(
                        invocation -> {
                            if (!mDeviceConnectionStack.isEmpty()
                                    && Objects.equals(
                                            mA2dpDevice,
                                            mDeviceConnectionStack.get(
                                                    mDeviceConnectionStack.size() - 1))) {
                                return mA2dpDevice;
                            }
                            return null;
                        });
        when(mHeadsetService.getFallbackDevice())
                .thenAnswer(
                        invocation -> {
                            if (!mDeviceConnectionStack.isEmpty()
                                    && Objects.equals(
                                            mHeadsetDevice,
                                            mDeviceConnectionStack.get(
                                                    mDeviceConnectionStack.size() - 1))) {
                                return mHeadsetDevice;
                            }
                            return null;
                        });
    }
    }


    @After
    @After