Loading AndroidManifest.xml +0 −3 Original line number Diff line number Diff line Loading @@ -315,9 +315,6 @@ <intent-filter> <action android:name="android.bluetooth.IBluetoothHeadsetPhone"/> </intent-filter> <intent-filter> <action android:name="android.bluetooth.IBluetoothLeCallControlCallback" /> </intent-filter> </service> <service android:name=".components.TelecomService" Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +2 −2 Original line number Diff line number Diff line Loading @@ -875,8 +875,8 @@ public class CallAudioRouteStateMachine extends StateMachine { return HANDLED; case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { // Only disconnect audio here instead of routing away from BT entirely. mBluetoothRouteManager.disconnectAudio(); // Only disconnect SCO audio here instead of routing away from BT entirely. mBluetoothRouteManager.disconnectSco(); reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } else if (msg.arg1 == RINGING_FOCUS Loading src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +23 −149 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.telecom.Log; Loading @@ -38,11 +37,6 @@ import java.util.List; import java.util.Set; 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 = new BluetoothProfile.ServiceListener() { @Override Loading @@ -58,10 +52,6 @@ public class BluetoothDeviceManager { mBluetoothHearingAid = (BluetoothHearingAid) proxy; logString = "Got BluetoothHearingAid: " + mBluetoothHearingAid; } else if (profile == BluetoothProfile.LE_AUDIO) { mBluetoothLeAudioService = (BluetoothLeAudio) proxy; logString = "Got BluetoothLeAudio: " + mBluetoothLeAudioService; } else { logString = "Connected to non-requested bluetooth service." + " Not changing bluetooth headset."; Loading @@ -84,8 +74,7 @@ public class BluetoothDeviceManager { if (profile == BluetoothProfile.HEADSET) { mBluetoothHeadset = null; lostServiceDevices = mHfpDevicesByAddress; mBluetoothRouteManager.onActiveDeviceChanged(null, DEVICE_TYPE_HEADSET); mBluetoothRouteManager.onActiveDeviceChanged(null, false); logString = "Lost BluetoothHeadset service. " + "Removing all tracked devices"; } else if (profile == BluetoothProfile.HEARING_AID) { Loading @@ -93,15 +82,7 @@ public class BluetoothDeviceManager { logString = "Lost BluetoothHearingAid service. " + "Removing all tracked devices."; lostServiceDevices = mHearingAidDevicesByAddress; 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); mBluetoothRouteManager.onActiveDeviceChanged(null, true); } else { return; } Loading @@ -127,12 +108,6 @@ public class BluetoothDeviceManager { new LinkedHashMap<>(); private final LinkedHashMap<BluetoothDevice, Long> mHearingAidDeviceSyncIds = 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); // This lock only protects internal state -- it doesn't lock on anything going into Telecom. Loading @@ -141,7 +116,6 @@ public class BluetoothDeviceManager { private BluetoothRouteManager mBluetoothRouteManager; private BluetoothHeadset mBluetoothHeadset; private BluetoothHearingAid mBluetoothHearingAid; private BluetoothLeAudio mBluetoothLeAudioService; private BluetoothDevice mBluetoothHearingAidActiveDeviceCache; private BluetoothAdapter mBluetoothAdapter; Loading @@ -152,8 +126,6 @@ public class BluetoothDeviceManager { BluetoothProfile.HEADSET); bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener, BluetoothProfile.HEARING_AID); bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO); } } Loading @@ -161,20 +133,9 @@ public class BluetoothDeviceManager { 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() { synchronized (mLock) { return mHfpDevicesByAddress.size() + mHearingAidDevicesByAddress.size() + getLeAudioConnectedDevices().size(); return mHfpDevicesByAddress.size() + mHearingAidDevicesByAddress.size(); } } Loading @@ -182,7 +143,6 @@ public class BluetoothDeviceManager { synchronized (mLock) { ArrayList<BluetoothDevice> result = new ArrayList<>(mHfpDevicesByAddress.values()); result.addAll(mHearingAidDevicesByAddress.values()); result.addAll(getLeAudioConnectedDevices()); return Collections.unmodifiableCollection(result); } } Loading Loading @@ -217,31 +177,6 @@ public class BluetoothDeviceManager { 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); } Loading @@ -257,10 +192,6 @@ public class BluetoothDeviceManager { return mBluetoothHearingAid; } public BluetoothLeAudio getLeAudioService() { return mBluetoothLeAudioService; } public void setHeadsetServiceForTesting(BluetoothHeadset bluetoothHeadset) { mBluetoothHeadset = bluetoothHeadset; } Loading @@ -269,33 +200,12 @@ public class BluetoothDeviceManager { mBluetoothHearingAid = bluetoothHearingAid; } public void setLeAudioServiceForTesting(BluetoothLeAudio bluetoothLeAudio) { mBluetoothLeAudioService = bluetoothLeAudio; } 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) { void onDeviceConnected(BluetoothDevice device, boolean isHearingAid) { mLocalLog.log("Device connected -- address: " + device.getAddress() + " isHeadingAid: " + isHearingAid); synchronized (mLock) { LinkedHashMap<String, BluetoothDevice> targetDeviceMap; 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 (isHearingAid) { if (mBluetoothHearingAid == null) { Log.w(this, "Hearing aid service null when receiving device added broadcast"); return; Loading @@ -303,16 +213,12 @@ public class BluetoothDeviceManager { long hiSyncId = mBluetoothHearingAid.getHiSyncId(device); mHearingAidDeviceSyncIds.put(device, hiSyncId); targetDeviceMap = mHearingAidDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEADSET) { } else { if (mBluetoothHeadset == null) { Log.w(this, "Headset service null when receiving device added broadcast"); return; } targetDeviceMap = mHfpDevicesByAddress; } else { Log.w(this, "Device: " + device.getAddress() + " with invalid type: " + getDeviceTypeString(deviceType)); return; } if (!targetDeviceMap.containsKey(device.getAddress())) { targetDeviceMap.put(device.getAddress(), device); Loading @@ -321,22 +227,16 @@ public class BluetoothDeviceManager { } } void onDeviceDisconnected(BluetoothDevice device, int deviceType) { mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " deviceType: " + deviceType); void onDeviceDisconnected(BluetoothDevice device, boolean isHearingAid) { mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " isHeadingAid: " + isHearingAid); synchronized (mLock) { LinkedHashMap<String, BluetoothDevice> targetDeviceMap; if (deviceType == DEVICE_TYPE_LE_AUDIO) { targetDeviceMap = mLeAudioDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEARING_AID) { if (isHearingAid) { mHearingAidDeviceSyncIds.remove(device); targetDeviceMap = mHearingAidDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEADSET) { targetDeviceMap = mHfpDevicesByAddress; } else { Log.w(this, "Device: " + device.getAddress() + " with invalid type: " + getDeviceTypeString(deviceType)); return; targetDeviceMap = mHfpDevicesByAddress; } if (targetDeviceMap.containsKey(device.getAddress())) { targetDeviceMap.remove(device.getAddress()); Loading @@ -345,35 +245,17 @@ public class BluetoothDeviceManager { } } void onGroupNodeAdded(BluetoothDevice device, int groupId) { Log.i(this, device.getAddress() + " group added " + groupId); if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { Log.w(this, "invalid parameter"); return; } 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) { for (BluetoothDevice device: mBluetoothAdapter.getActiveDevices( BluetoothProfile.HEARING_AID)) { if (device != null) { mBluetoothAdapter.removeActiveDevice(BluetoothAdapter.ACTIVE_DEVICE_ALL); disconnectSco(); } } } disconnectSco(); } public void disconnectSco() { if (mBluetoothHeadset == null) { Loading @@ -383,18 +265,10 @@ public class BluetoothDeviceManager { } } // 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. // Connect audio to the bluetooth device at address, checking to see whether it's a hearing aid // or a HFP device, and using the proper BT API. public boolean connectAudio(String 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 (mHearingAidDevicesByAddress.containsKey(address)) { if (mBluetoothHearingAid == null) { Log.w(this, "Attempting to turn on audio when the hearing aid service is null"); return false; Loading src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java +25 −75 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothLeAudio; import android.content.Context; import android.os.Message; import android.telecom.Log; Loading @@ -36,12 +35,10 @@ import com.android.internal.util.StateMachine; import com.android.server.telecom.TelecomSystem; import com.android.server.telecom.Timeouts; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; Loading Loading @@ -297,7 +294,7 @@ public class BluetoothRouteManager extends StateMachine { break; case BT_AUDIO_IS_ON: if (Objects.equals(mDeviceAddress, address)) { Log.i(LOG_TAG, "BT connection success for device %s.", mDeviceAddress); Log.i(LOG_TAG, "HFP connection success for device %s.", mDeviceAddress); transitionTo(mAudioConnectedStates.get(mDeviceAddress)); } else { Log.w(LOG_TAG, "In connecting state for device %s but %s" + Loading Loading @@ -454,7 +451,6 @@ public class BluetoothRouteManager extends StateMachine { // Tracks the active devices in the BT stack (HFP or hearing aid). private BluetoothDevice mHfpActiveDeviceCache = null; private BluetoothDevice mHearingAidActiveDeviceCache = null; private BluetoothDevice mLeAudioDeviceCache = null; private BluetoothDevice mMostRecentlyReportedActiveDevice = null; public BluetoothRouteManager(Context context, TelecomSystem.SyncRoot lock, Loading Loading @@ -552,8 +548,8 @@ public class BluetoothRouteManager extends StateMachine { sendMessage(DISCONNECT_HFP, args); } public void disconnectAudio() { mDeviceManager.disconnectAudio(); public void disconnectSco() { mDeviceManager.disconnectSco(); } public void cacheHearingAidDevice() { Loading Loading @@ -586,37 +582,19 @@ public class BluetoothRouteManager extends StateMachine { mListener.onBluetoothDeviceListChanged(); } public void onAudioOn(String address) { Session session = Log.createSubsession(); SomeArgs args = SomeArgs.obtain(); 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) { mLeAudioDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) { public void onActiveDeviceChanged(BluetoothDevice device, boolean isHearingAid) { boolean wasActiveDevicePresent = mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; if (isHearingAid) { mHearingAidActiveDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) { mHfpActiveDeviceCache = device; } else { return; mHfpActiveDeviceCache = device; } if (device != null) mMostRecentlyReportedActiveDevice = device; boolean isActiveDevicePresent = hasBtActiveDevice(); boolean isActiveDevicePresent = mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; if (wasActiveDevicePresent && !isActiveDevicePresent) { mListener.onBluetoothActiveDeviceGone(); Loading @@ -626,9 +604,7 @@ public class BluetoothRouteManager extends StateMachine { } public boolean hasBtActiveDevice() { return mLeAudioDeviceCache != null || mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; return mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; } public Collection<BluetoothDevice> getConnectedDevices() { Loading Loading @@ -706,9 +682,6 @@ public class BluetoothRouteManager extends StateMachine { if (mHearingAidActiveDeviceCache != null) { return mHearingAidActiveDeviceCache.getAddress(); } if (mLeAudioDeviceCache != null) { return mLeAudioDeviceCache.getAddress(); } return null; } Loading @@ -732,33 +705,29 @@ public class BluetoothRouteManager extends StateMachine { BluetoothAdapter bluetoothAdapter = mDeviceManager.getBluetoothAdapter(); BluetoothHeadset bluetoothHeadset = mDeviceManager.getBluetoothHeadset(); BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getBluetoothHearingAid(); BluetoothLeAudio bluetoothLeAudio = mDeviceManager.getLeAudioService(); BluetoothDevice hfpAudioOnDevice = null; BluetoothDevice hearingAidActiveDevice = null; BluetoothDevice leAudioActiveDevice = null; if (bluetoothAdapter == null) { Log.i(this, "getBluetoothAudioConnectedDevice: no adapter available."); return null; } if (bluetoothHeadset == null && bluetoothHearingAid == null && bluetoothLeAudio == null) { if (bluetoothHeadset == null && bluetoothHearingAid == null) { Log.i(this, "getBluetoothAudioConnectedDevice: no service available."); return null; } int activeDevices = 0; if (bluetoothHeadset != null) { for (BluetoothDevice device : bluetoothAdapter.getActiveDevices( BluetoothProfile.HEADSET)) { hfpAudioOnDevice = device; break; } if (bluetoothHeadset.getAudioState(hfpAudioOnDevice) == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { hfpAudioOnDevice = null; } else { activeDevices++; } } Loading @@ -767,41 +736,24 @@ public class BluetoothRouteManager extends StateMachine { BluetoothProfile.HEARING_AID)) { if (device != null) { hearingAidActiveDevice = device; activeDevices++; break; } } } if (bluetoothLeAudio != null) { for (BluetoothDevice device : bluetoothLeAudio.getActiveDevices()) { if (device != null) { leAudioActiveDevice = device; activeDevices++; 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 the active device reported by either HFP or hearing aid. If both are reporting // active devices, go with the most recent one as reported by the receiver. if (hfpAudioOnDevice != null) { if (hearingAidActiveDevice != null) { Log.i(this, "Both HFP and hearing aid are reporting active devices. Going with" + " the most recently reported active device: %s"); return mMostRecentlyReportedActiveDevice; } if (leAudioActiveDevice != null) { return leAudioActiveDevice; return hfpAudioOnDevice; } if (hearingAidActiveDevice != null) { return hearingAidActiveDevice; } return hfpAudioOnDevice; } /** * Check if in-band ringing is currently enabled. In-band ringing could be disabled during an * active connection. Loading Loading @@ -895,12 +847,10 @@ public class BluetoothRouteManager extends StateMachine { } @VisibleForTesting public void setActiveDeviceCacheForTesting(BluetoothDevice device, int deviceType) { if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO) { mLeAudioDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) { public void setActiveDeviceCacheForTesting(BluetoothDevice device, boolean isHearingAid) { if (isHearingAid) { mHearingAidActiveDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) { } else { mHfpActiveDeviceCache = device; } } Loading src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java +12 −61 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
AndroidManifest.xml +0 −3 Original line number Diff line number Diff line Loading @@ -315,9 +315,6 @@ <intent-filter> <action android:name="android.bluetooth.IBluetoothHeadsetPhone"/> </intent-filter> <intent-filter> <action android:name="android.bluetooth.IBluetoothLeCallControlCallback" /> </intent-filter> </service> <service android:name=".components.TelecomService" Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +2 −2 Original line number Diff line number Diff line Loading @@ -875,8 +875,8 @@ public class CallAudioRouteStateMachine extends StateMachine { return HANDLED; case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { // Only disconnect audio here instead of routing away from BT entirely. mBluetoothRouteManager.disconnectAudio(); // Only disconnect SCO audio here instead of routing away from BT entirely. mBluetoothRouteManager.disconnectSco(); reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } else if (msg.arg1 == RINGING_FOCUS Loading
src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +23 −149 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.telecom.Log; Loading @@ -38,11 +37,6 @@ import java.util.List; import java.util.Set; 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 = new BluetoothProfile.ServiceListener() { @Override Loading @@ -58,10 +52,6 @@ public class BluetoothDeviceManager { mBluetoothHearingAid = (BluetoothHearingAid) proxy; logString = "Got BluetoothHearingAid: " + mBluetoothHearingAid; } else if (profile == BluetoothProfile.LE_AUDIO) { mBluetoothLeAudioService = (BluetoothLeAudio) proxy; logString = "Got BluetoothLeAudio: " + mBluetoothLeAudioService; } else { logString = "Connected to non-requested bluetooth service." + " Not changing bluetooth headset."; Loading @@ -84,8 +74,7 @@ public class BluetoothDeviceManager { if (profile == BluetoothProfile.HEADSET) { mBluetoothHeadset = null; lostServiceDevices = mHfpDevicesByAddress; mBluetoothRouteManager.onActiveDeviceChanged(null, DEVICE_TYPE_HEADSET); mBluetoothRouteManager.onActiveDeviceChanged(null, false); logString = "Lost BluetoothHeadset service. " + "Removing all tracked devices"; } else if (profile == BluetoothProfile.HEARING_AID) { Loading @@ -93,15 +82,7 @@ public class BluetoothDeviceManager { logString = "Lost BluetoothHearingAid service. " + "Removing all tracked devices."; lostServiceDevices = mHearingAidDevicesByAddress; 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); mBluetoothRouteManager.onActiveDeviceChanged(null, true); } else { return; } Loading @@ -127,12 +108,6 @@ public class BluetoothDeviceManager { new LinkedHashMap<>(); private final LinkedHashMap<BluetoothDevice, Long> mHearingAidDeviceSyncIds = 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); // This lock only protects internal state -- it doesn't lock on anything going into Telecom. Loading @@ -141,7 +116,6 @@ public class BluetoothDeviceManager { private BluetoothRouteManager mBluetoothRouteManager; private BluetoothHeadset mBluetoothHeadset; private BluetoothHearingAid mBluetoothHearingAid; private BluetoothLeAudio mBluetoothLeAudioService; private BluetoothDevice mBluetoothHearingAidActiveDeviceCache; private BluetoothAdapter mBluetoothAdapter; Loading @@ -152,8 +126,6 @@ public class BluetoothDeviceManager { BluetoothProfile.HEADSET); bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener, BluetoothProfile.HEARING_AID); bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO); } } Loading @@ -161,20 +133,9 @@ public class BluetoothDeviceManager { 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() { synchronized (mLock) { return mHfpDevicesByAddress.size() + mHearingAidDevicesByAddress.size() + getLeAudioConnectedDevices().size(); return mHfpDevicesByAddress.size() + mHearingAidDevicesByAddress.size(); } } Loading @@ -182,7 +143,6 @@ public class BluetoothDeviceManager { synchronized (mLock) { ArrayList<BluetoothDevice> result = new ArrayList<>(mHfpDevicesByAddress.values()); result.addAll(mHearingAidDevicesByAddress.values()); result.addAll(getLeAudioConnectedDevices()); return Collections.unmodifiableCollection(result); } } Loading Loading @@ -217,31 +177,6 @@ public class BluetoothDeviceManager { 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); } Loading @@ -257,10 +192,6 @@ public class BluetoothDeviceManager { return mBluetoothHearingAid; } public BluetoothLeAudio getLeAudioService() { return mBluetoothLeAudioService; } public void setHeadsetServiceForTesting(BluetoothHeadset bluetoothHeadset) { mBluetoothHeadset = bluetoothHeadset; } Loading @@ -269,33 +200,12 @@ public class BluetoothDeviceManager { mBluetoothHearingAid = bluetoothHearingAid; } public void setLeAudioServiceForTesting(BluetoothLeAudio bluetoothLeAudio) { mBluetoothLeAudioService = bluetoothLeAudio; } 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) { void onDeviceConnected(BluetoothDevice device, boolean isHearingAid) { mLocalLog.log("Device connected -- address: " + device.getAddress() + " isHeadingAid: " + isHearingAid); synchronized (mLock) { LinkedHashMap<String, BluetoothDevice> targetDeviceMap; 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 (isHearingAid) { if (mBluetoothHearingAid == null) { Log.w(this, "Hearing aid service null when receiving device added broadcast"); return; Loading @@ -303,16 +213,12 @@ public class BluetoothDeviceManager { long hiSyncId = mBluetoothHearingAid.getHiSyncId(device); mHearingAidDeviceSyncIds.put(device, hiSyncId); targetDeviceMap = mHearingAidDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEADSET) { } else { if (mBluetoothHeadset == null) { Log.w(this, "Headset service null when receiving device added broadcast"); return; } targetDeviceMap = mHfpDevicesByAddress; } else { Log.w(this, "Device: " + device.getAddress() + " with invalid type: " + getDeviceTypeString(deviceType)); return; } if (!targetDeviceMap.containsKey(device.getAddress())) { targetDeviceMap.put(device.getAddress(), device); Loading @@ -321,22 +227,16 @@ public class BluetoothDeviceManager { } } void onDeviceDisconnected(BluetoothDevice device, int deviceType) { mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " deviceType: " + deviceType); void onDeviceDisconnected(BluetoothDevice device, boolean isHearingAid) { mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " isHeadingAid: " + isHearingAid); synchronized (mLock) { LinkedHashMap<String, BluetoothDevice> targetDeviceMap; if (deviceType == DEVICE_TYPE_LE_AUDIO) { targetDeviceMap = mLeAudioDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEARING_AID) { if (isHearingAid) { mHearingAidDeviceSyncIds.remove(device); targetDeviceMap = mHearingAidDevicesByAddress; } else if (deviceType == DEVICE_TYPE_HEADSET) { targetDeviceMap = mHfpDevicesByAddress; } else { Log.w(this, "Device: " + device.getAddress() + " with invalid type: " + getDeviceTypeString(deviceType)); return; targetDeviceMap = mHfpDevicesByAddress; } if (targetDeviceMap.containsKey(device.getAddress())) { targetDeviceMap.remove(device.getAddress()); Loading @@ -345,35 +245,17 @@ public class BluetoothDeviceManager { } } void onGroupNodeAdded(BluetoothDevice device, int groupId) { Log.i(this, device.getAddress() + " group added " + groupId); if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { Log.w(this, "invalid parameter"); return; } 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) { for (BluetoothDevice device: mBluetoothAdapter.getActiveDevices( BluetoothProfile.HEARING_AID)) { if (device != null) { mBluetoothAdapter.removeActiveDevice(BluetoothAdapter.ACTIVE_DEVICE_ALL); disconnectSco(); } } } disconnectSco(); } public void disconnectSco() { if (mBluetoothHeadset == null) { Loading @@ -383,18 +265,10 @@ public class BluetoothDeviceManager { } } // 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. // Connect audio to the bluetooth device at address, checking to see whether it's a hearing aid // or a HFP device, and using the proper BT API. public boolean connectAudio(String 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 (mHearingAidDevicesByAddress.containsKey(address)) { if (mBluetoothHearingAid == null) { Log.w(this, "Attempting to turn on audio when the hearing aid service is null"); return false; Loading
src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java +25 −75 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothLeAudio; import android.content.Context; import android.os.Message; import android.telecom.Log; Loading @@ -36,12 +35,10 @@ import com.android.internal.util.StateMachine; import com.android.server.telecom.TelecomSystem; import com.android.server.telecom.Timeouts; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; Loading Loading @@ -297,7 +294,7 @@ public class BluetoothRouteManager extends StateMachine { break; case BT_AUDIO_IS_ON: if (Objects.equals(mDeviceAddress, address)) { Log.i(LOG_TAG, "BT connection success for device %s.", mDeviceAddress); Log.i(LOG_TAG, "HFP connection success for device %s.", mDeviceAddress); transitionTo(mAudioConnectedStates.get(mDeviceAddress)); } else { Log.w(LOG_TAG, "In connecting state for device %s but %s" + Loading Loading @@ -454,7 +451,6 @@ public class BluetoothRouteManager extends StateMachine { // Tracks the active devices in the BT stack (HFP or hearing aid). private BluetoothDevice mHfpActiveDeviceCache = null; private BluetoothDevice mHearingAidActiveDeviceCache = null; private BluetoothDevice mLeAudioDeviceCache = null; private BluetoothDevice mMostRecentlyReportedActiveDevice = null; public BluetoothRouteManager(Context context, TelecomSystem.SyncRoot lock, Loading Loading @@ -552,8 +548,8 @@ public class BluetoothRouteManager extends StateMachine { sendMessage(DISCONNECT_HFP, args); } public void disconnectAudio() { mDeviceManager.disconnectAudio(); public void disconnectSco() { mDeviceManager.disconnectSco(); } public void cacheHearingAidDevice() { Loading Loading @@ -586,37 +582,19 @@ public class BluetoothRouteManager extends StateMachine { mListener.onBluetoothDeviceListChanged(); } public void onAudioOn(String address) { Session session = Log.createSubsession(); SomeArgs args = SomeArgs.obtain(); 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) { mLeAudioDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) { public void onActiveDeviceChanged(BluetoothDevice device, boolean isHearingAid) { boolean wasActiveDevicePresent = mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; if (isHearingAid) { mHearingAidActiveDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) { mHfpActiveDeviceCache = device; } else { return; mHfpActiveDeviceCache = device; } if (device != null) mMostRecentlyReportedActiveDevice = device; boolean isActiveDevicePresent = hasBtActiveDevice(); boolean isActiveDevicePresent = mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; if (wasActiveDevicePresent && !isActiveDevicePresent) { mListener.onBluetoothActiveDeviceGone(); Loading @@ -626,9 +604,7 @@ public class BluetoothRouteManager extends StateMachine { } public boolean hasBtActiveDevice() { return mLeAudioDeviceCache != null || mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; return mHearingAidActiveDeviceCache != null || mHfpActiveDeviceCache != null; } public Collection<BluetoothDevice> getConnectedDevices() { Loading Loading @@ -706,9 +682,6 @@ public class BluetoothRouteManager extends StateMachine { if (mHearingAidActiveDeviceCache != null) { return mHearingAidActiveDeviceCache.getAddress(); } if (mLeAudioDeviceCache != null) { return mLeAudioDeviceCache.getAddress(); } return null; } Loading @@ -732,33 +705,29 @@ public class BluetoothRouteManager extends StateMachine { BluetoothAdapter bluetoothAdapter = mDeviceManager.getBluetoothAdapter(); BluetoothHeadset bluetoothHeadset = mDeviceManager.getBluetoothHeadset(); BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getBluetoothHearingAid(); BluetoothLeAudio bluetoothLeAudio = mDeviceManager.getLeAudioService(); BluetoothDevice hfpAudioOnDevice = null; BluetoothDevice hearingAidActiveDevice = null; BluetoothDevice leAudioActiveDevice = null; if (bluetoothAdapter == null) { Log.i(this, "getBluetoothAudioConnectedDevice: no adapter available."); return null; } if (bluetoothHeadset == null && bluetoothHearingAid == null && bluetoothLeAudio == null) { if (bluetoothHeadset == null && bluetoothHearingAid == null) { Log.i(this, "getBluetoothAudioConnectedDevice: no service available."); return null; } int activeDevices = 0; if (bluetoothHeadset != null) { for (BluetoothDevice device : bluetoothAdapter.getActiveDevices( BluetoothProfile.HEADSET)) { hfpAudioOnDevice = device; break; } if (bluetoothHeadset.getAudioState(hfpAudioOnDevice) == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { hfpAudioOnDevice = null; } else { activeDevices++; } } Loading @@ -767,41 +736,24 @@ public class BluetoothRouteManager extends StateMachine { BluetoothProfile.HEARING_AID)) { if (device != null) { hearingAidActiveDevice = device; activeDevices++; break; } } } if (bluetoothLeAudio != null) { for (BluetoothDevice device : bluetoothLeAudio.getActiveDevices()) { if (device != null) { leAudioActiveDevice = device; activeDevices++; 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 the active device reported by either HFP or hearing aid. If both are reporting // active devices, go with the most recent one as reported by the receiver. if (hfpAudioOnDevice != null) { if (hearingAidActiveDevice != null) { Log.i(this, "Both HFP and hearing aid are reporting active devices. Going with" + " the most recently reported active device: %s"); return mMostRecentlyReportedActiveDevice; } if (leAudioActiveDevice != null) { return leAudioActiveDevice; return hfpAudioOnDevice; } if (hearingAidActiveDevice != null) { return hearingAidActiveDevice; } return hfpAudioOnDevice; } /** * Check if in-band ringing is currently enabled. In-band ringing could be disabled during an * active connection. Loading Loading @@ -895,12 +847,10 @@ public class BluetoothRouteManager extends StateMachine { } @VisibleForTesting public void setActiveDeviceCacheForTesting(BluetoothDevice device, int deviceType) { if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO) { mLeAudioDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID) { public void setActiveDeviceCacheForTesting(BluetoothDevice device, boolean isHearingAid) { if (isHearingAid) { mHearingAidActiveDeviceCache = device; } else if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEADSET) { } else { mHfpActiveDeviceCache = device; } } Loading
src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java +12 −61 File changed.Preview size limit exceeded, changes collapsed. Show changes