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

Commit 6ee60434 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add support for Generic Telephone Bearer service (GTBS)" am: b8e22b66 am: 62e998f7

Original change: https://android-review.googlesource.com/c/platform/packages/services/Telecomm/+/1942896

Change-Id: I1b11436f1ebb3f2b95f37d828cb222d1ca68223e
parents fb6fb9e7 62e998f7
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -315,6 +315,9 @@
            <intent-filter>
            <intent-filter>
                <action android:name="android.bluetooth.IBluetoothHeadsetPhone"/>
                <action android:name="android.bluetooth.IBluetoothHeadsetPhone"/>
            </intent-filter>
            </intent-filter>
            <intent-filter>
                <action android:name="android.bluetooth.IBluetoothLeCallControlCallback" />
            </intent-filter>
        </service>
        </service>


        <service android:name=".components.TelecomService"
        <service android:name=".components.TelecomService"
+2 −2
Original line number Original line Diff line number Diff line
@@ -875,8 +875,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    return HANDLED;
                    return HANDLED;
                case SWITCH_FOCUS:
                case SWITCH_FOCUS:
                    if (msg.arg1 == NO_FOCUS) {
                    if (msg.arg1 == NO_FOCUS) {
                        // Only disconnect SCO audio here instead of routing away from BT entirely.
                        // Only disconnect audio here instead of routing away from BT entirely.
                        mBluetoothRouteManager.disconnectSco();
                        mBluetoothRouteManager.disconnectAudio();
                        reinitialize();
                        reinitialize();
                        mCallAudioManager.notifyAudioOperationsComplete();
                        mCallAudioManager.notifyAudioOperationsComplete();
                    } else if (msg.arg1 == RINGING_FOCUS
                    } else if (msg.arg1 == RINGING_FOCUS
+149 −23
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Context;
import android.telecom.Log;
import android.telecom.Log;
@@ -37,6 +38,11 @@ import java.util.List;
import java.util.Set;
import java.util.Set;


public class BluetoothDeviceManager {
public class BluetoothDeviceManager {

    public static final int DEVICE_TYPE_HEADSET = 0;
    public static final int DEVICE_TYPE_HEARING_AID = 1;
    public static final int DEVICE_TYPE_LE_AUDIO = 2;

    private final BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
    private final BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
            new BluetoothProfile.ServiceListener() {
            new BluetoothProfile.ServiceListener() {
                @Override
                @Override
@@ -52,6 +58,10 @@ public class BluetoothDeviceManager {
                                mBluetoothHearingAid = (BluetoothHearingAid) proxy;
                                mBluetoothHearingAid = (BluetoothHearingAid) proxy;
                                logString = "Got BluetoothHearingAid: "
                                logString = "Got BluetoothHearingAid: "
                                        + mBluetoothHearingAid;
                                        + mBluetoothHearingAid;
                            } else if (profile == BluetoothProfile.LE_AUDIO) {
                                mBluetoothLeAudioService = (BluetoothLeAudio) proxy;
                                logString = "Got BluetoothLeAudio: "
                                        + mBluetoothLeAudioService;
                            } else {
                            } else {
                                logString = "Connected to non-requested bluetooth service." +
                                logString = "Connected to non-requested bluetooth service." +
                                        " Not changing bluetooth headset.";
                                        " Not changing bluetooth headset.";
@@ -74,7 +84,8 @@ public class BluetoothDeviceManager {
                            if (profile == BluetoothProfile.HEADSET) {
                            if (profile == BluetoothProfile.HEADSET) {
                                mBluetoothHeadset = null;
                                mBluetoothHeadset = null;
                                lostServiceDevices = mHfpDevicesByAddress;
                                lostServiceDevices = mHfpDevicesByAddress;
                                mBluetoothRouteManager.onActiveDeviceChanged(null, false);
                                mBluetoothRouteManager.onActiveDeviceChanged(null,
                                        DEVICE_TYPE_HEADSET);
                                logString = "Lost BluetoothHeadset service. " +
                                logString = "Lost BluetoothHeadset service. " +
                                        "Removing all tracked devices";
                                        "Removing all tracked devices";
                            } else if (profile == BluetoothProfile.HEARING_AID) {
                            } else if (profile == BluetoothProfile.HEARING_AID) {
@@ -82,7 +93,15 @@ public class BluetoothDeviceManager {
                                logString = "Lost BluetoothHearingAid service. " +
                                logString = "Lost BluetoothHearingAid service. " +
                                        "Removing all tracked devices.";
                                        "Removing all tracked devices.";
                                lostServiceDevices = mHearingAidDevicesByAddress;
                                lostServiceDevices = mHearingAidDevicesByAddress;
                                mBluetoothRouteManager.onActiveDeviceChanged(null, true);
                                mBluetoothRouteManager.onActiveDeviceChanged(null,
                                        DEVICE_TYPE_HEARING_AID);
                            } else if (profile == BluetoothProfile.LE_AUDIO) {
                                mBluetoothLeAudioService = null;
                                logString = "Lost BluetoothLeAudio service. " +
                                        "Removing all tracked devices.";
                                lostServiceDevices = mLeAudioDevicesByAddress;
                                mBluetoothRouteManager.onActiveDeviceChanged(null,
                                        DEVICE_TYPE_LE_AUDIO);
                            } else {
                            } else {
                                return;
                                return;
                            }
                            }
@@ -108,6 +127,12 @@ public class BluetoothDeviceManager {
            new LinkedHashMap<>();
            new LinkedHashMap<>();
    private final LinkedHashMap<BluetoothDevice, Long> mHearingAidDeviceSyncIds =
    private final LinkedHashMap<BluetoothDevice, Long> mHearingAidDeviceSyncIds =
            new LinkedHashMap<>();
            new LinkedHashMap<>();
    private final LinkedHashMap<String, BluetoothDevice> mLeAudioDevicesByAddress =
            new LinkedHashMap<>();
    private final LinkedHashMap<BluetoothDevice, Integer> mGroupsByDevice =
            new LinkedHashMap<>();
    private int mGroupIdActive = BluetoothLeAudio.GROUP_ID_INVALID;
    private int mGroupIdPending = BluetoothLeAudio.GROUP_ID_INVALID;
    private final LocalLog mLocalLog = new LocalLog(20);
    private final LocalLog mLocalLog = new LocalLog(20);


    // This lock only protects internal state -- it doesn't lock on anything going into Telecom.
    // This lock only protects internal state -- it doesn't lock on anything going into Telecom.
@@ -116,6 +141,7 @@ public class BluetoothDeviceManager {
    private BluetoothRouteManager mBluetoothRouteManager;
    private BluetoothRouteManager mBluetoothRouteManager;
    private BluetoothHeadset mBluetoothHeadset;
    private BluetoothHeadset mBluetoothHeadset;
    private BluetoothHearingAid mBluetoothHearingAid;
    private BluetoothHearingAid mBluetoothHearingAid;
    private BluetoothLeAudio mBluetoothLeAudioService;
    private BluetoothDevice mBluetoothHearingAidActiveDeviceCache;
    private BluetoothDevice mBluetoothHearingAidActiveDeviceCache;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothAdapter mBluetoothAdapter;


@@ -126,6 +152,8 @@ public class BluetoothDeviceManager {
                    BluetoothProfile.HEADSET);
                    BluetoothProfile.HEADSET);
            bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
            bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
                    BluetoothProfile.HEARING_AID);
                    BluetoothProfile.HEARING_AID);
            bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
                    BluetoothProfile.LE_AUDIO);
        }
        }
    }
    }


@@ -133,9 +161,20 @@ public class BluetoothDeviceManager {
        mBluetoothRouteManager = brm;
        mBluetoothRouteManager = brm;
    }
    }


    private List<BluetoothDevice> getLeAudioConnectedDevices() {
        synchronized (mLock) {
            // Filter out disconnected devices and/or those that have no group assigned
            ArrayList<BluetoothDevice> devices = new ArrayList<>(mGroupsByDevice.keySet());
            devices.removeIf(device -> !mLeAudioDevicesByAddress.containsValue(device));
            return devices;
        }
    }

    public int getNumConnectedDevices() {
    public int getNumConnectedDevices() {
        synchronized (mLock) {
        synchronized (mLock) {
            return mHfpDevicesByAddress.size() + mHearingAidDevicesByAddress.size();
            return mHfpDevicesByAddress.size() +
                    mHearingAidDevicesByAddress.size() +
                    getLeAudioConnectedDevices().size();
        }
        }
    }
    }


@@ -143,6 +182,7 @@ public class BluetoothDeviceManager {
        synchronized (mLock) {
        synchronized (mLock) {
            ArrayList<BluetoothDevice> result = new ArrayList<>(mHfpDevicesByAddress.values());
            ArrayList<BluetoothDevice> result = new ArrayList<>(mHfpDevicesByAddress.values());
            result.addAll(mHearingAidDevicesByAddress.values());
            result.addAll(mHearingAidDevicesByAddress.values());
            result.addAll(getLeAudioConnectedDevices());
            return Collections.unmodifiableCollection(result);
            return Collections.unmodifiableCollection(result);
        }
        }
    }
    }
@@ -177,6 +217,31 @@ public class BluetoothDeviceManager {
                seenHiSyncIds.add(hiSyncId);
                seenHiSyncIds.add(hiSyncId);
            }
            }
        }
        }

        Set<Integer> seenGroupIds = new LinkedHashSet<>();
        if (mBluetoothAdapter != null) {
            for (BluetoothDevice device : mBluetoothAdapter.getActiveDevices(
                        BluetoothProfile.LE_AUDIO)) {
                if (device != null) {
                    result.add(device);
                    seenGroupIds.add(mGroupsByDevice.getOrDefault(device, -1));
                    break;
                }
            }
        }
        synchronized (mLock) {
            for (BluetoothDevice d : getLeAudioConnectedDevices()) {
                int groupId = mGroupsByDevice.getOrDefault(d,
                        BluetoothLeAudio.GROUP_ID_INVALID);
                if (groupId == BluetoothLeAudio.GROUP_ID_INVALID
                        || seenGroupIds.contains(groupId)) {
                    continue;
                }
                result.add(d);
                seenGroupIds.add(groupId);
            }
        }

        return Collections.unmodifiableCollection(result);
        return Collections.unmodifiableCollection(result);
    }
    }


@@ -192,6 +257,10 @@ public class BluetoothDeviceManager {
        return mBluetoothHearingAid;
        return mBluetoothHearingAid;
    }
    }


    public BluetoothLeAudio getLeAudioService() {
        return mBluetoothLeAudioService;
    }

    public void setHeadsetServiceForTesting(BluetoothHeadset bluetoothHeadset) {
    public void setHeadsetServiceForTesting(BluetoothHeadset bluetoothHeadset) {
        mBluetoothHeadset = bluetoothHeadset;
        mBluetoothHeadset = bluetoothHeadset;
    }
    }
@@ -200,12 +269,33 @@ public class BluetoothDeviceManager {
        mBluetoothHearingAid = bluetoothHearingAid;
        mBluetoothHearingAid = bluetoothHearingAid;
    }
    }


    void onDeviceConnected(BluetoothDevice device, boolean isHearingAid) {
    public void setLeAudioServiceForTesting(BluetoothLeAudio bluetoothLeAudio) {
        mLocalLog.log("Device connected -- address: " + device.getAddress() + " isHeadingAid: "
        mBluetoothLeAudioService = bluetoothLeAudio;
                + isHearingAid);
    }

    public static String getDeviceTypeString(int deviceType) {
        switch (deviceType) {
            case DEVICE_TYPE_LE_AUDIO:
                return "LeAudio";
            case DEVICE_TYPE_HEARING_AID:
                return "HearingAid";
            case DEVICE_TYPE_HEADSET:
                return "HFP";
            default:
                return "unknown type";
        }
    }

    void onDeviceConnected(BluetoothDevice device, int deviceType) {
        synchronized (mLock) {
        synchronized (mLock) {
            LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
            LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
            if (isHearingAid) {
            if (deviceType == DEVICE_TYPE_LE_AUDIO) {
                if (mBluetoothLeAudioService == null) {
                    Log.w(this, "LE audio service null when receiving device added broadcast");
                    return;
                }
                targetDeviceMap = mLeAudioDevicesByAddress;
            } else if (deviceType == DEVICE_TYPE_HEARING_AID) {
                if (mBluetoothHearingAid == null) {
                if (mBluetoothHearingAid == null) {
                    Log.w(this, "Hearing aid service null when receiving device added broadcast");
                    Log.w(this, "Hearing aid service null when receiving device added broadcast");
                    return;
                    return;
@@ -213,12 +303,16 @@ public class BluetoothDeviceManager {
                long hiSyncId = mBluetoothHearingAid.getHiSyncId(device);
                long hiSyncId = mBluetoothHearingAid.getHiSyncId(device);
                mHearingAidDeviceSyncIds.put(device, hiSyncId);
                mHearingAidDeviceSyncIds.put(device, hiSyncId);
                targetDeviceMap = mHearingAidDevicesByAddress;
                targetDeviceMap = mHearingAidDevicesByAddress;
            } else {
            } else if (deviceType == DEVICE_TYPE_HEADSET) {
                if (mBluetoothHeadset == null) {
                if (mBluetoothHeadset == null) {
                    Log.w(this, "Headset service null when receiving device added broadcast");
                    Log.w(this, "Headset service null when receiving device added broadcast");
                    return;
                    return;
                }
                }
                targetDeviceMap = mHfpDevicesByAddress;
                targetDeviceMap = mHfpDevicesByAddress;
            } else {
                Log.w(this, "Device: " + device.getAddress() + " with invalid type: "
                            + getDeviceTypeString(deviceType));
                return;
            }
            }
            if (!targetDeviceMap.containsKey(device.getAddress())) {
            if (!targetDeviceMap.containsKey(device.getAddress())) {
                targetDeviceMap.put(device.getAddress(), device);
                targetDeviceMap.put(device.getAddress(), device);
@@ -227,16 +321,22 @@ public class BluetoothDeviceManager {
        }
        }
    }
    }


    void onDeviceDisconnected(BluetoothDevice device, boolean isHearingAid) {
    void onDeviceDisconnected(BluetoothDevice device, int deviceType) {
        mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " isHeadingAid: "
        mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " deviceType: "
                + isHearingAid);
                + deviceType);
        synchronized (mLock) {
        synchronized (mLock) {
            LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
            LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
            if (isHearingAid) {
            if (deviceType == DEVICE_TYPE_LE_AUDIO) {
                targetDeviceMap = mLeAudioDevicesByAddress;
            } else if (deviceType == DEVICE_TYPE_HEARING_AID) {
                mHearingAidDeviceSyncIds.remove(device);
                mHearingAidDeviceSyncIds.remove(device);
                targetDeviceMap = mHearingAidDevicesByAddress;
                targetDeviceMap = mHearingAidDevicesByAddress;
            } else {
            } else if (deviceType == DEVICE_TYPE_HEADSET) {
                targetDeviceMap = mHfpDevicesByAddress;
                targetDeviceMap = mHfpDevicesByAddress;
            } else {
                Log.w(this, "Device: " + device.getAddress() + " with invalid type: "
                            + getDeviceTypeString(deviceType));
                return;
            }
            }
            if (targetDeviceMap.containsKey(device.getAddress())) {
            if (targetDeviceMap.containsKey(device.getAddress())) {
                targetDeviceMap.remove(device.getAddress());
                targetDeviceMap.remove(device.getAddress());
@@ -245,17 +345,35 @@ public class BluetoothDeviceManager {
        }
        }
    }
    }


    public void disconnectAudio() {
    void onGroupNodeAdded(BluetoothDevice device, int groupId) {
        if (mBluetoothAdapter != null) {
        Log.i(this, device.getAddress() + " group added " + groupId);
            for (BluetoothDevice device: mBluetoothAdapter.getActiveDevices(
        if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) {
                        BluetoothProfile.HEARING_AID)) {
            Log.w(this, "invalid parameter");
                if (device != null) {
            return;
                    mBluetoothAdapter.removeActiveDevice(BluetoothAdapter.ACTIVE_DEVICE_ALL);
        }

        synchronized (mLock) {
            mGroupsByDevice.put(device, groupId);
        }
    }

    void onGroupNodeRemoved(BluetoothDevice device, int groupId) {
        if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) {
            Log.w(this, "invalid parameter");
            return;
        }
        }

        synchronized (mLock) {
            mGroupsByDevice.remove(device);
        }
        }
    }
    }

    public void disconnectAudio() {
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.removeActiveDevice(BluetoothAdapter.ACTIVE_DEVICE_ALL);
            disconnectSco();
            disconnectSco();
        }
        }
    }


    public void disconnectSco() {
    public void disconnectSco() {
        if (mBluetoothHeadset == null) {
        if (mBluetoothHeadset == null) {
@@ -265,10 +383,18 @@ public class BluetoothDeviceManager {
        }
        }
    }
    }


    // Connect audio to the bluetooth device at address, checking to see whether it's a hearing aid
    // Connect audio to the bluetooth device at address, checking to see whether it's
    // or a HFP device, and using the proper BT API.
    // le audio, hearing aid or a HFP device, and using the proper BT API.
    public boolean connectAudio(String address) {
    public boolean connectAudio(String address) {
        if (mHearingAidDevicesByAddress.containsKey(address)) {
        if (mLeAudioDevicesByAddress.containsKey(address)) {
            if (mBluetoothLeAudioService == null) {
                Log.w(this, "Attempting to turn on audio when the le audio service is null");
                return false;
            }
            BluetoothDevice device = mLeAudioDevicesByAddress.get(address);
            return mBluetoothAdapter.setActiveDevice(
                    device, BluetoothAdapter.ACTIVE_DEVICE_ALL);
        } else if (mHearingAidDevicesByAddress.containsKey(address)) {
            if (mBluetoothHearingAid == null) {
            if (mBluetoothHearingAid == null) {
                Log.w(this, "Attempting to turn on audio when the hearing aid service is null");
                Log.w(this, "Attempting to turn on audio when the hearing aid service is null");
                return false;
                return false;
+75 −25
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothLeAudio;
import android.content.Context;
import android.content.Context;
import android.os.Message;
import android.os.Message;
import android.telecom.Log;
import android.telecom.Log;
@@ -35,10 +36,12 @@ import com.android.internal.util.StateMachine;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.Timeouts;
import com.android.server.telecom.Timeouts;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
import java.util.Optional;
import java.util.Optional;
@@ -294,7 +297,7 @@ public class BluetoothRouteManager extends StateMachine {
                        break;
                        break;
                    case BT_AUDIO_IS_ON:
                    case BT_AUDIO_IS_ON:
                        if (Objects.equals(mDeviceAddress, address)) {
                        if (Objects.equals(mDeviceAddress, address)) {
                            Log.i(LOG_TAG, "HFP connection success for device %s.", mDeviceAddress);
                            Log.i(LOG_TAG, "BT connection success for device %s.", mDeviceAddress);
                            transitionTo(mAudioConnectedStates.get(mDeviceAddress));
                            transitionTo(mAudioConnectedStates.get(mDeviceAddress));
                        } else {
                        } else {
                            Log.w(LOG_TAG, "In connecting state for device %s but %s" +
                            Log.w(LOG_TAG, "In connecting state for device %s but %s" +
@@ -451,6 +454,7 @@ public class BluetoothRouteManager extends StateMachine {
    // Tracks the active devices in the BT stack (HFP or hearing aid).
    // Tracks the active devices in the BT stack (HFP or hearing aid).
    private BluetoothDevice mHfpActiveDeviceCache = null;
    private BluetoothDevice mHfpActiveDeviceCache = null;
    private BluetoothDevice mHearingAidActiveDeviceCache = null;
    private BluetoothDevice mHearingAidActiveDeviceCache = null;
    private BluetoothDevice mLeAudioActiveDeviceCache = null;
    private BluetoothDevice mMostRecentlyReportedActiveDevice = null;
    private BluetoothDevice mMostRecentlyReportedActiveDevice = null;


    public BluetoothRouteManager(Context context, TelecomSystem.SyncRoot lock,
    public BluetoothRouteManager(Context context, TelecomSystem.SyncRoot lock,
@@ -548,8 +552,8 @@ public class BluetoothRouteManager extends StateMachine {
        sendMessage(DISCONNECT_HFP, args);
        sendMessage(DISCONNECT_HFP, args);
    }
    }


    public void disconnectSco() {
    public void disconnectAudio() {
        mDeviceManager.disconnectSco();
        mDeviceManager.disconnectAudio();
    }
    }


    public void cacheHearingAidDevice() {
    public void cacheHearingAidDevice() {
@@ -582,19 +586,37 @@ public class BluetoothRouteManager extends StateMachine {
        mListener.onBluetoothDeviceListChanged();
        mListener.onBluetoothDeviceListChanged();
    }
    }


    public void onActiveDeviceChanged(BluetoothDevice device, boolean isHearingAid) {
    public void onAudioOn(String address) {
        boolean wasActiveDevicePresent = mHearingAidActiveDeviceCache != null
        Session session = Log.createSubsession();
                || mHfpActiveDeviceCache != null;
        SomeArgs args = SomeArgs.obtain();
        if (isHearingAid) {
        args.arg1 = session;
        args.arg2 = address;
        sendMessage(BT_AUDIO_IS_ON, args);
    }

    public void onAudioLost(String address) {
        Session session = Log.createSubsession();
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = session;
        args.arg2 = address;
        sendMessage(BT_AUDIO_LOST, args);
    }

    public void onActiveDeviceChanged(BluetoothDevice device, int deviceType) {
        boolean wasActiveDevicePresent = hasBtActiveDevice();
        if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO) {
            mLeAudioActiveDeviceCache = device;
        } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) {
            mHearingAidActiveDeviceCache = device;
            mHearingAidActiveDeviceCache = device;
        } else {
        } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) {
            mHfpActiveDeviceCache = device;
            mHfpActiveDeviceCache = device;
        } else {
            return;
        }
        }


        if (device != null) mMostRecentlyReportedActiveDevice = device;
        if (device != null) mMostRecentlyReportedActiveDevice = device;


        boolean isActiveDevicePresent = mHearingAidActiveDeviceCache != null
        boolean isActiveDevicePresent = hasBtActiveDevice();
                || mHfpActiveDeviceCache != null;


        if (wasActiveDevicePresent && !isActiveDevicePresent) {
        if (wasActiveDevicePresent && !isActiveDevicePresent) {
            mListener.onBluetoothActiveDeviceGone();
            mListener.onBluetoothActiveDeviceGone();
@@ -604,7 +626,9 @@ public class BluetoothRouteManager extends StateMachine {
    }
    }


    public boolean hasBtActiveDevice() {
    public boolean hasBtActiveDevice() {
        return mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null;
        return mLeAudioActiveDeviceCache != null ||
                mHearingAidActiveDeviceCache != null ||
                mHfpActiveDeviceCache != null;
    }
    }


    public Collection<BluetoothDevice> getConnectedDevices() {
    public Collection<BluetoothDevice> getConnectedDevices() {
@@ -682,6 +706,9 @@ public class BluetoothRouteManager extends StateMachine {
        if (mHearingAidActiveDeviceCache != null) {
        if (mHearingAidActiveDeviceCache != null) {
            return mHearingAidActiveDeviceCache.getAddress();
            return mHearingAidActiveDeviceCache.getAddress();
        }
        }
        if (mLeAudioActiveDeviceCache != null) {
            return mLeAudioActiveDeviceCache.getAddress();
        }
        return null;
        return null;
    }
    }


@@ -705,29 +732,33 @@ public class BluetoothRouteManager extends StateMachine {
        BluetoothAdapter bluetoothAdapter = mDeviceManager.getBluetoothAdapter();
        BluetoothAdapter bluetoothAdapter = mDeviceManager.getBluetoothAdapter();
        BluetoothHeadset bluetoothHeadset = mDeviceManager.getBluetoothHeadset();
        BluetoothHeadset bluetoothHeadset = mDeviceManager.getBluetoothHeadset();
        BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getBluetoothHearingAid();
        BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getBluetoothHearingAid();
        BluetoothLeAudio bluetoothLeAudio = mDeviceManager.getLeAudioService();


        BluetoothDevice hfpAudioOnDevice = null;
        BluetoothDevice hfpAudioOnDevice = null;
        BluetoothDevice hearingAidActiveDevice = null;
        BluetoothDevice hearingAidActiveDevice = null;
        BluetoothDevice leAudioActiveDevice = null;


        if (bluetoothAdapter == null) {
        if (bluetoothAdapter == null) {
            Log.i(this, "getBluetoothAudioConnectedDevice: no adapter available.");
            Log.i(this, "getBluetoothAudioConnectedDevice: no adapter available.");
            return null;
            return null;
        }
        }
        if (bluetoothHeadset == null && bluetoothHearingAid == null) {
        if (bluetoothHeadset == null && bluetoothHearingAid == null && bluetoothLeAudio == null) {
            Log.i(this, "getBluetoothAudioConnectedDevice: no service available.");
            Log.i(this, "getBluetoothAudioConnectedDevice: no service available.");
            return null;
            return null;
        }
        }


        int activeDevices = 0;
        if (bluetoothHeadset != null) {
        if (bluetoothHeadset != null) {
            for (BluetoothDevice device : bluetoothAdapter.getActiveDevices(
            for (BluetoothDevice device : bluetoothAdapter.getActiveDevices(
                        BluetoothProfile.HEADSET)) {
                        BluetoothProfile.HEADSET)) {
                hfpAudioOnDevice = device;
                hfpAudioOnDevice = device;
                break;
                break;
            }
            }

            if (bluetoothHeadset.getAudioState(hfpAudioOnDevice)
            if (bluetoothHeadset.getAudioState(hfpAudioOnDevice)
                    == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                    == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                hfpAudioOnDevice = null;
                hfpAudioOnDevice = null;
            } else {
                activeDevices++;
            }
            }
        }
        }


@@ -736,24 +767,41 @@ public class BluetoothRouteManager extends StateMachine {
                        BluetoothProfile.HEARING_AID)) {
                        BluetoothProfile.HEARING_AID)) {
                if (device != null) {
                if (device != null) {
                    hearingAidActiveDevice = device;
                    hearingAidActiveDevice = device;
                    activeDevices++;
                    break;
                    break;
                }
                }
            }
            }
        }
        }


        // Return the active device reported by either HFP or hearing aid. If both are reporting
        if (bluetoothLeAudio != null) {
        // active devices, go with the most recent one as reported by the receiver.
            for (BluetoothDevice device : bluetoothLeAudio.getActiveDevices()) {
        if (hfpAudioOnDevice != null) {
                if (device != null) {
            if (hearingAidActiveDevice != null) {
                    leAudioActiveDevice = device;
                Log.i(this, "Both HFP and hearing aid are reporting active devices. Going with"
                    activeDevices++;
                        + " the most recently reported active device: %s");
                    break;
                }
            }
        }

        // Return the active device reported by either HFP, hearing aid or le audio. If more than
        // one is reporting active devices, go with the most recent one as reported by the receiver.
        if (activeDevices > 1) {
            Log.i(this, "More than one profile reporting active devices. Going with the most"
                    + " recently reported active device: %s", mMostRecentlyReportedActiveDevice);
            return mMostRecentlyReportedActiveDevice;
            return mMostRecentlyReportedActiveDevice;
        }
        }
            return hfpAudioOnDevice;

        if (leAudioActiveDevice != null) {
            return leAudioActiveDevice;
        }
        }

        if (hearingAidActiveDevice != null) {
            return hearingAidActiveDevice;
            return hearingAidActiveDevice;
        }
        }


        return hfpAudioOnDevice;
    }

    /**
    /**
     * Check if in-band ringing is currently enabled. In-band ringing could be disabled during an
     * Check if in-band ringing is currently enabled. In-band ringing could be disabled during an
     * active connection.
     * active connection.
@@ -847,10 +895,12 @@ public class BluetoothRouteManager extends StateMachine {
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    public void setActiveDeviceCacheForTesting(BluetoothDevice device, boolean isHearingAid) {
    public void setActiveDeviceCacheForTesting(BluetoothDevice device, int deviceType) {
        if (isHearingAid) {
        if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO) {
          mLeAudioActiveDeviceCache = device;
        } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) {
            mHearingAidActiveDeviceCache = device;
            mHearingAidActiveDeviceCache = device;
        } else {
        } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) {
            mHfpActiveDeviceCache = device;
            mHfpActiveDeviceCache = device;
        }
        }
    }
    }
+61 −12

File changed.

Preview size limit exceeded, changes collapsed.

Loading