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

Commit cfb38512 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

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



Change-Id: I7b8535ead174d8db9c5ecef12f444d01fc287fab
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents ef047045 6f3decfc
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