Loading src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java +207 −8 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package com.android.settings.bluetooth; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; Loading @@ -31,6 +33,7 @@ import androidx.preference.SwitchPreference; import com.android.settings.R; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; Loading @@ -39,7 +42,10 @@ import com.android.settingslib.bluetooth.PanProfile; import com.android.settingslib.bluetooth.PbapServerProfile; import com.android.settingslib.core.lifecycle.Lifecycle; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This class adds switches for toggling the individual profiles that a Bluetooth device Loading @@ -48,8 +54,11 @@ import java.util.List; public class BluetoothDetailsProfilesController extends BluetoothDetailsController implements Preference.OnPreferenceClickListener, LocalBluetoothProfileManager.ServiceListener { private static final String TAG = "BtDetailsProfilesCtrl"; private static final String KEY_PROFILES_GROUP = "bluetooth_profiles"; private static final String KEY_BOTTOM_PREFERENCE = "bottom_preference"; private static final String HEADSET_CLIENT = "HEADSET_CLIENT"; private static final int ORDINAL = 99; @VisibleForTesting Loading @@ -58,6 +67,9 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll private LocalBluetoothManager mManager; private LocalBluetoothProfileManager mProfileManager; private CachedBluetoothDevice mCachedDevice; private List<CachedBluetoothDevice> mAllOfCachedDevices; private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap = new HashMap<String, List<CachedBluetoothDevice>>(); @VisibleForTesting PreferenceCategory mProfilesContainer; Loading @@ -68,6 +80,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll mManager = manager; mProfileManager = mManager.getProfileManager(); mCachedDevice = device; mAllOfCachedDevices = getAllOfCachedBluetoothDevices(); lifecycle.addObserver(this); } Loading Loading @@ -100,11 +113,66 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll /** * Refreshes the state for an existing SwitchPreference for a profile. * If the LeAudio profile is enabled on the LeAudio devices, then the SwitchPreferences of * A2dp profile and Hfp profile are graied out. */ private void refreshProfilePreference(SwitchPreference profilePref, LocalBluetoothProfile profile) { BluetoothDevice device = mCachedDevice.getDevice(); boolean isLeAudioEnabled = false; if (profile instanceof A2dpProfile || HEADSET_CLIENT.equals(profile.toString())) { LocalBluetoothProfile leAudio = mProfileManager.getLeAudioProfile(); if (leAudio != null) { List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get( leAudio.toString()); if (leAudioDeviceList != null && leAudioDeviceList.stream() .anyMatch(item -> leAudio.isEnabled(item.getDevice()))) { isLeAudioEnabled = true; } } if (isLeAudioEnabled) { // If the LeAudio profile is enabled on the LeAudio devices, then the // SwitchPreferences of A2dp profile and Hfp profile are graied out. profilePref.setEnabled(false); } else { List<CachedBluetoothDevice> deviceList = mProfileDeviceMap.get( profile.toString()); boolean isBusy = deviceList != null && deviceList.stream().anyMatch(item -> item.isBusy()); profilePref.setEnabled(!isBusy); } } else if (profile instanceof LeAudioProfile) { List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get( profile.toString()); boolean isLeAudioProfileEnable = leAudioDeviceList != null && leAudioDeviceList.stream().anyMatch( item -> profile.isEnabled(item.getDevice())); boolean isBusy = leAudioDeviceList != null && leAudioDeviceList.stream().anyMatch(item -> item.isBusy()); if (isLeAudioProfileEnable && !isBusy) { LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile(); LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile(); // If the LeAudio profile is enabled on the LeAudio devices, then the // SwitchPreferences of A2dp profile and Hfp profile are graied out. if (a2dp != null) { SwitchPreference pref = mProfilesContainer.findPreference(a2dp.toString()); if (pref != null) { pref.setEnabled(false); } } if (hfp != null) { SwitchPreference pref = mProfilesContainer.findPreference(hfp.toString()); if (pref != null) { pref.setEnabled(false); } } } profilePref.setEnabled(!isBusy); } else { profilePref.setEnabled(!mCachedDevice.isBusy()); } if (profile instanceof MapProfile) { profilePref.setChecked(device.getMessageAccessPermission() == BluetoothDevice.ACCESS_ALLOWED); Loading @@ -127,7 +195,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll highQualityPref.setVisible(true); highQualityPref.setTitle(a2dp.getHighQualityAudioOptionLabel(device)); highQualityPref.setChecked(a2dp.isHighQualityAudioEnabled(device)); highQualityPref.setEnabled(!mCachedDevice.isBusy()); highQualityPref.setEnabled(!mCachedDevice.isBusy() && !isLeAudioEnabled); } else { highQualityPref.setVisible(false); } Loading @@ -148,6 +216,12 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll if (profile instanceof MapProfile) { bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED); } if (profile instanceof LeAudioProfile) { enableLeAudioProfile(profile); return; } profile.setEnabled(bluetoothDevice, true); } Loading @@ -155,8 +229,14 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll * Helper method to disable a profile for a device */ private void disableProfile(LocalBluetoothProfile profile) { if (profile instanceof LeAudioProfile) { disableLeAudioProfile(profile); return; } final BluetoothDevice bluetoothDevice = mCachedDevice.getDevice(); profile.setEnabled(bluetoothDevice, false); if (profile instanceof MapProfile) { bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_REJECTED); } else if (profile instanceof PbapServerProfile) { Loading Loading @@ -190,14 +270,33 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll return true; } /** * Helper to get the list of connectable and special profiles. */ private List<LocalBluetoothProfile> getProfiles() { List<LocalBluetoothProfile> result = mCachedDevice.getConnectableProfiles(); final BluetoothDevice device = mCachedDevice.getDevice(); List<LocalBluetoothProfile> result = new ArrayList<LocalBluetoothProfile>(); mProfileDeviceMap.clear(); if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) { return result; } for (CachedBluetoothDevice cachedItem : mAllOfCachedDevices) { List<LocalBluetoothProfile> tmpResult = cachedItem.getConnectableProfiles(); for (LocalBluetoothProfile profile : tmpResult) { if (mProfileDeviceMap.containsKey(profile.toString())) { mProfileDeviceMap.get(profile.toString()).add(cachedItem); Log.d(TAG, "getProfiles: " + profile.toString() + " add device " + cachedItem.getDevice().getAnonymizedAddress()); } else { List<CachedBluetoothDevice> tmpCachedDeviceList = new ArrayList<CachedBluetoothDevice>(); tmpCachedDeviceList.add(cachedItem); mProfileDeviceMap.put(profile.toString(), tmpCachedDeviceList); result.add(profile); } } } final BluetoothDevice device = mCachedDevice.getDevice(); final int pbapPermission = device.getPhonebookAccessPermission(); // Only provide PBAP cabability if the client device has requested PBAP. if (pbapPermission != BluetoothDevice.ACCESS_UNKNOWN) { Loading @@ -210,10 +309,93 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll if (mapPermission != BluetoothDevice.ACCESS_UNKNOWN) { result.add(mapProfile); } Log.d(TAG, "getProfiles:result:" + result); return result; } private List<CachedBluetoothDevice> getAllOfCachedBluetoothDevices() { List<CachedBluetoothDevice> cachedBluetoothDevices = new ArrayList<>(); if (mCachedDevice == null) { return cachedBluetoothDevices; } cachedBluetoothDevices.add(mCachedDevice); if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { for (CachedBluetoothDevice member : mCachedDevice.getMemberDevice()) { cachedBluetoothDevices.add(member); } } return cachedBluetoothDevices; } /** * When user disable the Le Audio profile, the system needs to do two things. * 1) Disable the Le Audio profile for each of the Le Audio devices. * 2) Enable the A2dp profile and Hfp profile for the associated device. The system can't * enable the A2dp profile and Hfp profile if the Le Audio profile is enabled. * * @param profile the LeAudio profile */ private void disableLeAudioProfile(LocalBluetoothProfile profile) { if (profile == null || mProfileDeviceMap.get(profile.toString()) == null) { Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing."); return; } for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) { profile.setEnabled(leAudioDevice.getDevice(), false); } LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile(); LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile(); if (a2dp != null && mProfileDeviceMap.get(a2dp.toString()) != null) { for (CachedBluetoothDevice a2dpDevice : mProfileDeviceMap.get(a2dp.toString())) { if (!a2dp.isEnabled(a2dpDevice.getDevice())) { a2dp.setEnabled(a2dpDevice.getDevice(), true); } } } if (hfp != null && mProfileDeviceMap.get(hfp.toString()) != null) { for (CachedBluetoothDevice hfpDevice : mProfileDeviceMap.get(hfp.toString())) { if (!hfp.isEnabled(hfpDevice.getDevice())) { hfp.setEnabled(hfpDevice.getDevice(), true); } } } } /** * When user enable the Le Audio profile, the system needs to do two things. * 1) Disable the A2dp profile and Hfp profile for the associated device. The system can't * enable the Le Audio if the A2dp profile and Hfp profile are enabled. * 2) Enable the Le Audio profile for each of the Le Audio devices. * * @param profile the LeAudio profile */ private void enableLeAudioProfile(LocalBluetoothProfile profile) { if (profile == null || mProfileDeviceMap.get(profile.toString()) == null) { Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing."); return; } LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile(); LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile(); if (a2dp != null && mProfileDeviceMap.get(a2dp.toString()) != null) { for (CachedBluetoothDevice a2dpDevice : mProfileDeviceMap.get(a2dp.toString())) { if (a2dp.isEnabled(a2dpDevice.getDevice())) { a2dp.setEnabled(a2dpDevice.getDevice(), false); } } } if (hfp != null && mProfileDeviceMap.get(hfp.toString()) != null) { for (CachedBluetoothDevice hfpDevice : mProfileDeviceMap.get(hfp.toString())) { if (hfp.isEnabled(hfpDevice.getDevice())) { hfp.setEnabled(hfpDevice.getDevice(), false); } } } for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) { profile.setEnabled(leAudioDevice.getDevice(), true); } } /** * This is a helper method to be called after adding a Preference for a profile. If that * profile happened to be A2dp and the device supports high quality audio, it will add a Loading Loading @@ -243,16 +425,33 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll @Override public void onPause() { super.onPause(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.unregisterCallback(this); } mProfileManager.removeServiceListener(this); } @Override public void onResume() { super.onResume(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.registerCallback(this); } mProfileManager.addServiceListener(this); } @Override public void onDeviceAttributesChanged() { for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.unregisterCallback(this); } mAllOfCachedDevices = getAllOfCachedBluetoothDevices(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.registerCallback(this); } super.onDeviceAttributesChanged(); } @Override public void onServiceConnected() { refresh(); Loading Loading
src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java +207 −8 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package com.android.settings.bluetooth; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; Loading @@ -31,6 +33,7 @@ import androidx.preference.SwitchPreference; import com.android.settings.R; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; Loading @@ -39,7 +42,10 @@ import com.android.settingslib.bluetooth.PanProfile; import com.android.settingslib.bluetooth.PbapServerProfile; import com.android.settingslib.core.lifecycle.Lifecycle; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This class adds switches for toggling the individual profiles that a Bluetooth device Loading @@ -48,8 +54,11 @@ import java.util.List; public class BluetoothDetailsProfilesController extends BluetoothDetailsController implements Preference.OnPreferenceClickListener, LocalBluetoothProfileManager.ServiceListener { private static final String TAG = "BtDetailsProfilesCtrl"; private static final String KEY_PROFILES_GROUP = "bluetooth_profiles"; private static final String KEY_BOTTOM_PREFERENCE = "bottom_preference"; private static final String HEADSET_CLIENT = "HEADSET_CLIENT"; private static final int ORDINAL = 99; @VisibleForTesting Loading @@ -58,6 +67,9 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll private LocalBluetoothManager mManager; private LocalBluetoothProfileManager mProfileManager; private CachedBluetoothDevice mCachedDevice; private List<CachedBluetoothDevice> mAllOfCachedDevices; private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap = new HashMap<String, List<CachedBluetoothDevice>>(); @VisibleForTesting PreferenceCategory mProfilesContainer; Loading @@ -68,6 +80,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll mManager = manager; mProfileManager = mManager.getProfileManager(); mCachedDevice = device; mAllOfCachedDevices = getAllOfCachedBluetoothDevices(); lifecycle.addObserver(this); } Loading Loading @@ -100,11 +113,66 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll /** * Refreshes the state for an existing SwitchPreference for a profile. * If the LeAudio profile is enabled on the LeAudio devices, then the SwitchPreferences of * A2dp profile and Hfp profile are graied out. */ private void refreshProfilePreference(SwitchPreference profilePref, LocalBluetoothProfile profile) { BluetoothDevice device = mCachedDevice.getDevice(); boolean isLeAudioEnabled = false; if (profile instanceof A2dpProfile || HEADSET_CLIENT.equals(profile.toString())) { LocalBluetoothProfile leAudio = mProfileManager.getLeAudioProfile(); if (leAudio != null) { List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get( leAudio.toString()); if (leAudioDeviceList != null && leAudioDeviceList.stream() .anyMatch(item -> leAudio.isEnabled(item.getDevice()))) { isLeAudioEnabled = true; } } if (isLeAudioEnabled) { // If the LeAudio profile is enabled on the LeAudio devices, then the // SwitchPreferences of A2dp profile and Hfp profile are graied out. profilePref.setEnabled(false); } else { List<CachedBluetoothDevice> deviceList = mProfileDeviceMap.get( profile.toString()); boolean isBusy = deviceList != null && deviceList.stream().anyMatch(item -> item.isBusy()); profilePref.setEnabled(!isBusy); } } else if (profile instanceof LeAudioProfile) { List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get( profile.toString()); boolean isLeAudioProfileEnable = leAudioDeviceList != null && leAudioDeviceList.stream().anyMatch( item -> profile.isEnabled(item.getDevice())); boolean isBusy = leAudioDeviceList != null && leAudioDeviceList.stream().anyMatch(item -> item.isBusy()); if (isLeAudioProfileEnable && !isBusy) { LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile(); LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile(); // If the LeAudio profile is enabled on the LeAudio devices, then the // SwitchPreferences of A2dp profile and Hfp profile are graied out. if (a2dp != null) { SwitchPreference pref = mProfilesContainer.findPreference(a2dp.toString()); if (pref != null) { pref.setEnabled(false); } } if (hfp != null) { SwitchPreference pref = mProfilesContainer.findPreference(hfp.toString()); if (pref != null) { pref.setEnabled(false); } } } profilePref.setEnabled(!isBusy); } else { profilePref.setEnabled(!mCachedDevice.isBusy()); } if (profile instanceof MapProfile) { profilePref.setChecked(device.getMessageAccessPermission() == BluetoothDevice.ACCESS_ALLOWED); Loading @@ -127,7 +195,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll highQualityPref.setVisible(true); highQualityPref.setTitle(a2dp.getHighQualityAudioOptionLabel(device)); highQualityPref.setChecked(a2dp.isHighQualityAudioEnabled(device)); highQualityPref.setEnabled(!mCachedDevice.isBusy()); highQualityPref.setEnabled(!mCachedDevice.isBusy() && !isLeAudioEnabled); } else { highQualityPref.setVisible(false); } Loading @@ -148,6 +216,12 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll if (profile instanceof MapProfile) { bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED); } if (profile instanceof LeAudioProfile) { enableLeAudioProfile(profile); return; } profile.setEnabled(bluetoothDevice, true); } Loading @@ -155,8 +229,14 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll * Helper method to disable a profile for a device */ private void disableProfile(LocalBluetoothProfile profile) { if (profile instanceof LeAudioProfile) { disableLeAudioProfile(profile); return; } final BluetoothDevice bluetoothDevice = mCachedDevice.getDevice(); profile.setEnabled(bluetoothDevice, false); if (profile instanceof MapProfile) { bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_REJECTED); } else if (profile instanceof PbapServerProfile) { Loading Loading @@ -190,14 +270,33 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll return true; } /** * Helper to get the list of connectable and special profiles. */ private List<LocalBluetoothProfile> getProfiles() { List<LocalBluetoothProfile> result = mCachedDevice.getConnectableProfiles(); final BluetoothDevice device = mCachedDevice.getDevice(); List<LocalBluetoothProfile> result = new ArrayList<LocalBluetoothProfile>(); mProfileDeviceMap.clear(); if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) { return result; } for (CachedBluetoothDevice cachedItem : mAllOfCachedDevices) { List<LocalBluetoothProfile> tmpResult = cachedItem.getConnectableProfiles(); for (LocalBluetoothProfile profile : tmpResult) { if (mProfileDeviceMap.containsKey(profile.toString())) { mProfileDeviceMap.get(profile.toString()).add(cachedItem); Log.d(TAG, "getProfiles: " + profile.toString() + " add device " + cachedItem.getDevice().getAnonymizedAddress()); } else { List<CachedBluetoothDevice> tmpCachedDeviceList = new ArrayList<CachedBluetoothDevice>(); tmpCachedDeviceList.add(cachedItem); mProfileDeviceMap.put(profile.toString(), tmpCachedDeviceList); result.add(profile); } } } final BluetoothDevice device = mCachedDevice.getDevice(); final int pbapPermission = device.getPhonebookAccessPermission(); // Only provide PBAP cabability if the client device has requested PBAP. if (pbapPermission != BluetoothDevice.ACCESS_UNKNOWN) { Loading @@ -210,10 +309,93 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll if (mapPermission != BluetoothDevice.ACCESS_UNKNOWN) { result.add(mapProfile); } Log.d(TAG, "getProfiles:result:" + result); return result; } private List<CachedBluetoothDevice> getAllOfCachedBluetoothDevices() { List<CachedBluetoothDevice> cachedBluetoothDevices = new ArrayList<>(); if (mCachedDevice == null) { return cachedBluetoothDevices; } cachedBluetoothDevices.add(mCachedDevice); if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { for (CachedBluetoothDevice member : mCachedDevice.getMemberDevice()) { cachedBluetoothDevices.add(member); } } return cachedBluetoothDevices; } /** * When user disable the Le Audio profile, the system needs to do two things. * 1) Disable the Le Audio profile for each of the Le Audio devices. * 2) Enable the A2dp profile and Hfp profile for the associated device. The system can't * enable the A2dp profile and Hfp profile if the Le Audio profile is enabled. * * @param profile the LeAudio profile */ private void disableLeAudioProfile(LocalBluetoothProfile profile) { if (profile == null || mProfileDeviceMap.get(profile.toString()) == null) { Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing."); return; } for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) { profile.setEnabled(leAudioDevice.getDevice(), false); } LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile(); LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile(); if (a2dp != null && mProfileDeviceMap.get(a2dp.toString()) != null) { for (CachedBluetoothDevice a2dpDevice : mProfileDeviceMap.get(a2dp.toString())) { if (!a2dp.isEnabled(a2dpDevice.getDevice())) { a2dp.setEnabled(a2dpDevice.getDevice(), true); } } } if (hfp != null && mProfileDeviceMap.get(hfp.toString()) != null) { for (CachedBluetoothDevice hfpDevice : mProfileDeviceMap.get(hfp.toString())) { if (!hfp.isEnabled(hfpDevice.getDevice())) { hfp.setEnabled(hfpDevice.getDevice(), true); } } } } /** * When user enable the Le Audio profile, the system needs to do two things. * 1) Disable the A2dp profile and Hfp profile for the associated device. The system can't * enable the Le Audio if the A2dp profile and Hfp profile are enabled. * 2) Enable the Le Audio profile for each of the Le Audio devices. * * @param profile the LeAudio profile */ private void enableLeAudioProfile(LocalBluetoothProfile profile) { if (profile == null || mProfileDeviceMap.get(profile.toString()) == null) { Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing."); return; } LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile(); LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile(); if (a2dp != null && mProfileDeviceMap.get(a2dp.toString()) != null) { for (CachedBluetoothDevice a2dpDevice : mProfileDeviceMap.get(a2dp.toString())) { if (a2dp.isEnabled(a2dpDevice.getDevice())) { a2dp.setEnabled(a2dpDevice.getDevice(), false); } } } if (hfp != null && mProfileDeviceMap.get(hfp.toString()) != null) { for (CachedBluetoothDevice hfpDevice : mProfileDeviceMap.get(hfp.toString())) { if (hfp.isEnabled(hfpDevice.getDevice())) { hfp.setEnabled(hfpDevice.getDevice(), false); } } } for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) { profile.setEnabled(leAudioDevice.getDevice(), true); } } /** * This is a helper method to be called after adding a Preference for a profile. If that * profile happened to be A2dp and the device supports high quality audio, it will add a Loading Loading @@ -243,16 +425,33 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll @Override public void onPause() { super.onPause(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.unregisterCallback(this); } mProfileManager.removeServiceListener(this); } @Override public void onResume() { super.onResume(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.registerCallback(this); } mProfileManager.addServiceListener(this); } @Override public void onDeviceAttributesChanged() { for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.unregisterCallback(this); } mAllOfCachedDevices = getAllOfCachedBluetoothDevices(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.registerCallback(this); } super.onDeviceAttributesChanged(); } @Override public void onServiceConnected() { refresh(); Loading