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

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

Merge "LeAudio: Set communication device when LeAudio is used" am: 59790a5b...

Merge "LeAudio: Set communication device when LeAudio is used" am: 59790a5b am: b71e3c9f am: 73a64aae

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

Change-Id: I367402e07436d2988950f41e6c396f6e53a3148a
parents 98c136b9 73a64aae
Loading
Loading
Loading
Loading
+72 −2
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
import android.media.AudioDeviceInfo;
import android.telecom.Log;
import android.util.LocalLog;

@@ -142,8 +144,10 @@ public class BluetoothDeviceManager {
    private BluetoothHeadset mBluetoothHeadset;
    private BluetoothHearingAid mBluetoothHearingAid;
    private BluetoothLeAudio mBluetoothLeAudioService;
    private boolean mLeAudioSetAsCommunicationDevice = false;
    private BluetoothDevice mBluetoothHearingAidActiveDeviceCache;
    private BluetoothAdapter mBluetoothAdapter;
    private AudioManager mAudioManager;

    public BluetoothDeviceManager(Context context, BluetoothAdapter bluetoothAdapter) {
        if (bluetoothAdapter != null) {
@@ -154,6 +158,7 @@ public class BluetoothDeviceManager {
                    BluetoothProfile.HEARING_AID);
            bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
                    BluetoothProfile.LE_AUDIO);
            mAudioManager = context.getSystemService(AudioManager.class);
        }
    }

@@ -377,6 +382,7 @@ public class BluetoothDeviceManager {
                }
            }
            disconnectSco();
            clearLeAudioCommunicationDevice();
        }
    }

@@ -388,6 +394,67 @@ public class BluetoothDeviceManager {
        }
    }

    public boolean isLeAudioCommunicationDevice() {
        return mLeAudioSetAsCommunicationDevice;
    }

    public void clearLeAudioCommunicationDevice() {
        if (!mLeAudioSetAsCommunicationDevice) {
            return;
        }
        mLeAudioSetAsCommunicationDevice = false;

        if (mAudioManager == null) {
            Log.i(this, " mAudioManager is null");
            return;
        }
        mAudioManager.clearCommunicationDevice();
    }

    public boolean setLeAudioCommunicationDevice() {
        Log.i(this, "setLeAudioCommunicationDevice");

        if (mLeAudioSetAsCommunicationDevice) {
            Log.i(this, "setLeAudioCommunicationDevice already set");
            return true;
        }

        if (mAudioManager == null) {
            Log.w(this, " mAudioManager is null");
            return false;
        }

        AudioDeviceInfo bleHeadset = null;
        List<AudioDeviceInfo> devices = mAudioManager.getAvailableCommunicationDevices();
        if (devices.size() == 0) {
            Log.w(this, " No communication devices available.");
            return false;
        }

        for (AudioDeviceInfo device : devices) {
            Log.i(this, " Available device type:  " + device.getType());
            if (device.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET) {
                bleHeadset = device;
                break;
            }
        }

        if (bleHeadset == null) {
            Log.w(this, " No bleHeadset device available");
            return false;
        }

        // Turn BLE_OUT_HEADSET ON.
        boolean result = mAudioManager.setCommunicationDevice(bleHeadset);
        if (!result) {
            Log.w(this, " Could not set bleHeadset device");
        } else {
            Log.i(this, " bleHeadset device set");
            mLeAudioSetAsCommunicationDevice = true;
        }
        return result;
    }

    // Connect audio to the bluetooth device at address, checking to see whether it's
    // le audio, hearing aid or a HFP device, and using the proper BT API.
    public boolean connectAudio(String address) {
@@ -397,8 +464,11 @@ public class BluetoothDeviceManager {
                return false;
            }
            BluetoothDevice device = mLeAudioDevicesByAddress.get(address);
            return mBluetoothAdapter.setActiveDevice(
                    device, BluetoothAdapter.ACTIVE_DEVICE_ALL);
            if (mBluetoothAdapter.setActiveDevice(
                    device, BluetoothAdapter.ACTIVE_DEVICE_ALL)) {
                return setLeAudioCommunicationDevice();
            }
            return false;
        } else if (mHearingAidDevicesByAddress.containsKey(address)) {
            if (mBluetoothHearingAid == null) {
                Log.w(this, "Attempting to turn on audio when the hearing aid service is null");
+10 −5
Original line number Diff line number Diff line
@@ -606,6 +606,9 @@ public class BluetoothRouteManager extends StateMachine {
        boolean wasActiveDevicePresent = hasBtActiveDevice();
        if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO) {
            mLeAudioActiveDeviceCache = device;
            if (device == null) {
                mDeviceManager.clearLeAudioCommunicationDevice();
            }
        } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) {
            mHearingAidActiveDeviceCache = device;
        } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) {
@@ -774,6 +777,7 @@ public class BluetoothRouteManager extends StateMachine {
        }

        if (bluetoothLeAudio != null) {
            if (mDeviceManager.isLeAudioCommunicationDevice()) {
                for (BluetoothDevice device : bluetoothLeAudio.getActiveDevices()) {
                    if (device != null) {
                        leAudioActiveDevice = device;
@@ -782,6 +786,7 @@ public class BluetoothRouteManager extends StateMachine {
                    }
                }
            }
        }

        // 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.
+20 −2
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Parcel;
import android.test.suitebuilder.annotation.SmallTest;

@@ -44,12 +46,15 @@ import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

@RunWith(JUnit4.class)
public class BluetoothDeviceManagerTest extends TelecomTestCase {
@@ -58,6 +63,7 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
    @Mock BluetoothAdapter mAdapter;
    @Mock BluetoothHearingAid mBluetoothHearingAid;
    @Mock BluetoothLeAudio mBluetoothLeAudio;
    @Mock AudioManager mockAudioManager;

    BluetoothDeviceManager mBluetoothDeviceManager;
    BluetoothProfile.ServiceListener serviceListenerUnderTest;
@@ -91,6 +97,8 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        mBluetoothDeviceManager = new BluetoothDeviceManager(mContext, mAdapter);
        mBluetoothDeviceManager.setBluetoothRouteManager(mRouteManager);

        mockAudioManager = mContext.getSystemService(AudioManager.class);

        ArgumentCaptor<BluetoothProfile.ServiceListener> serviceCaptor =
                ArgumentCaptor.forClass(BluetoothProfile.ServiceListener.class);
        verify(mAdapter).getProfileProxy(eq(mContext),
@@ -368,6 +376,17 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
                buildGroupNodeStatusChangedIntent(1, device5, BluetoothLeAudio.GROUP_NODE_ADDED));
        when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class),
                eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true);

        AudioDeviceInfo mockAudioDeviceInfo = mock(AudioDeviceInfo.class);
        when(mockAudioDeviceInfo.getType()).thenReturn(AudioDeviceInfo.TYPE_BLE_HEADSET);
        List<AudioDeviceInfo> devices = new ArrayList<>();
        devices.add(mockAudioDeviceInfo);

        when(mockAudioManager.getAvailableCommunicationDevices())
                        .thenReturn(devices);
        when(mockAudioManager.setCommunicationDevice(mockAudioDeviceInfo))
                       .thenReturn(true);

        mBluetoothDeviceManager.connectAudio(device5.getAddress());
        verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL);
        verify(mBluetoothHeadset, never()).connectAudio();
@@ -375,8 +394,7 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
                eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL));

        mBluetoothDeviceManager.disconnectAudio();
        // TODO: Add a test here to verify that LE audio is de-selected
        // verify(mAdapter).removeActiveDevice(BluetoothAdapter.ACTIVE_DEVICE_ALL);
        verify(mockAudioManager).clearCommunicationDevice();
    }

    @SmallTest
+6 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.content.res.Resources;
import android.hardware.SensorPrivacyManager;
import android.location.Country;
import android.location.CountryDetector;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
@@ -489,6 +490,11 @@ public class ComponentContextFixture implements TestFixture<Context> {
        public int getStreamVolume(int streamValueUnused) {
            return mAudioStreamValue;
        }

        @Override
        public boolean setCommunicationDevice(AudioDeviceInfo device) {
            return true;
        }
    }

    private static final String PACKAGE_NAME = "com.android.server.telecom.tests";