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

Commit 955aeff9 authored by Sungsoo Lim's avatar Sungsoo Lim Committed by Automerger Merge Worker
Browse files

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

Merge "Migrate the fallback device logic of A2dp and Hfp into AudioRoutingManager" into main am: 6f3decfc am: cfb38512 am: 2e703fb7

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2758686



Change-Id: Ib79dfe283cae72fc3da878deaa4c7d1f6d3c77c4
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 7f012032 2e703fb7
Loading
Loading
Loading
Loading
+82 −67
Original line number Diff line number Diff line
@@ -334,6 +334,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                return;
            }
            mHearingAidConnectedDevices.add(device);
        }
        // New connected device: select it as active
        if (setHearingAidActiveDevice(device)) {
            setA2dpActiveDevice(null, true);
@@ -341,7 +342,6 @@ public class AudioRoutingManager extends ActiveDeviceManager {
            setLeAudioActiveDevice(null, true);
        }
    }
    }

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

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

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

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

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

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

        List<BluetoothDevice> connectedDevices = new ArrayList<>();
        connectedDevices.addAll(mLeAudioConnectedDevices);
        switch (mAudioManager.getMode()) {
            case AudioManager.MODE_NORMAL:
                if (a2dpFallbackDevice != null) {
                    connectedDevices.add(a2dpFallbackDevice);
                }
                fallbackCandidates.addAll(mA2dpConnectedDevices);
                break;
            case AudioManager.MODE_RINGTONE:
                if (headsetFallbackDevice != null && headsetService.isInbandRingingEnabled()) {
                    connectedDevices.add(headsetFallbackDevice);
                if (headsetService.isInbandRingingEnabled()) {
                    fallbackCandidates.addAll(hfpFallbackCandidates);
                }
                break;
            default:
                if (headsetFallbackDevice != null) {
                    connectedDevices.add(headsetFallbackDevice);
                fallbackCandidates.addAll(hfpFallbackCandidates);
        }
        }
        BluetoothDevice device = mDbManager.getMostRecentlyConnectedDevicesInList(connectedDevices);
        BluetoothDevice device =
                mDbManager.getMostRecentlyConnectedDevicesInList(fallbackCandidates);
        if (device != null) {
            if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
                if (Objects.equals(a2dpFallbackDevice, device)) {
                if (mA2dpConnectedDevices.contains(device)) {
                    if (DBG) {
                        Log.d(TAG, "Found an A2DP fallback device: " + device);
                    }
                    setA2dpActiveDevice(device);
                    if (Objects.equals(headsetFallbackDevice, device)) {
                    if (hfpFallbackCandidates.contains(device)) {
                        setHfpActiveDevice(device);
                    } else {
                        setHfpActiveDevice(null);
@@ -1089,13 +1079,13 @@ public class AudioRoutingManager extends ActiveDeviceManager {
                    setHearingAidActiveDevice(null, true);
                }
            } else {
                if (Objects.equals(headsetFallbackDevice, device)) {
                if (hfpFallbackCandidates.contains(device)) {
                    if (DBG) {
                        Log.d(TAG, "Found a HFP fallback device: " + device);
                    }
                    setHfpActiveDevice(device);
                    if (Objects.equals(a2dpFallbackDevice, device)) {
                        setA2dpActiveDevice(a2dpFallbackDevice);
                    if (mA2dpConnectedDevices.contains(device)) {
                        setA2dpActiveDevice(device);
                    } else {
                        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
    BluetoothDevice getA2dpActiveDevice() {
        synchronized (mLock) {
+0 −26
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ import org.mockito.MockitoAnnotations;

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

@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -146,31 +145,6 @@ public class AudioRoutingManagerTest {
        when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(mHearingAidHiSyncId);
        when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId))
                .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