Merge "LeAudio: Set communication device when LeAudio is used" am: 59790a5b1d
Original change: https://android-review.googlesource.com/c/platform/packages/services/Telecomm/+/1927389
Change-Id: If1860a81a9e4c328e6bda20705644a75a211279c
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java b/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
index a1a181c..50f75b1 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
@@ -23,6 +23,8 @@
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 @@
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 @@
BluetoothProfile.HEARING_AID);
bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
BluetoothProfile.LE_AUDIO);
+ mAudioManager = context.getSystemService(AudioManager.class);
}
}
@@ -377,6 +382,7 @@
}
}
disconnectSco();
+ clearLeAudioCommunicationDevice();
}
}
@@ -388,6 +394,67 @@
}
}
+ 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 @@
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");
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
index dba2c36..44a60c4 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
@@ -606,6 +606,9 @@
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,11 +777,13 @@
}
if (bluetoothLeAudio != null) {
- for (BluetoothDevice device : bluetoothLeAudio.getActiveDevices()) {
- if (device != null) {
- leAudioActiveDevice = device;
- activeDevices++;
- break;
+ if (mDeviceManager.isLeAudioCommunicationDevice()) {
+ for (BluetoothDevice device : bluetoothLeAudio.getActiveDevices()) {
+ if (device != null) {
+ leAudioActiveDevice = device;
+ activeDevices++;
+ break;
+ }
}
}
}
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
index cfd3b37..7bd0d0b 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
@@ -24,6 +24,8 @@
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.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 @@
@Mock BluetoothAdapter mAdapter;
@Mock BluetoothHearingAid mBluetoothHearingAid;
@Mock BluetoothLeAudio mBluetoothLeAudio;
+ @Mock AudioManager mockAudioManager;
BluetoothDeviceManager mBluetoothDeviceManager;
BluetoothProfile.ServiceListener serviceListenerUnderTest;
@@ -91,6 +97,8 @@
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 @@
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 @@
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
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index 2463847..94c4321 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -53,6 +53,7 @@
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 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";