538 lines
22 KiB
Java
538 lines
22 KiB
Java
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.settings.bluetooth;
|
|
|
|
import android.bluetooth.BluetoothCsipSetCoordinator;
|
|
import android.bluetooth.BluetoothDevice;
|
|
import android.bluetooth.BluetoothProfile;
|
|
import android.content.Context;
|
|
import android.os.SystemProperties;
|
|
import android.provider.DeviceConfig;
|
|
import android.text.TextUtils;
|
|
import android.util.Log;
|
|
|
|
import androidx.annotation.VisibleForTesting;
|
|
import androidx.preference.Preference;
|
|
import androidx.preference.PreferenceCategory;
|
|
import androidx.preference.PreferenceFragmentCompat;
|
|
import androidx.preference.PreferenceScreen;
|
|
import androidx.preference.SwitchPreference;
|
|
|
|
import com.android.settings.R;
|
|
import com.android.settings.core.SettingsUIDeviceConfig;
|
|
import com.android.settingslib.bluetooth.A2dpProfile;
|
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
|
import com.android.settingslib.bluetooth.HeadsetProfile;
|
|
import com.android.settingslib.bluetooth.LeAudioProfile;
|
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
|
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
|
|
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
|
import com.android.settingslib.bluetooth.MapProfile;
|
|
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
|
|
* supports, such as "Phone audio", "Media audio", "Contact sharing", etc.
|
|
*/
|
|
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 int ORDINAL = 99;
|
|
|
|
@VisibleForTesting
|
|
static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";
|
|
|
|
private static final String ENABLE_DUAL_MODE_AUDIO =
|
|
"persist.bluetooth.enable_dual_mode_audio";
|
|
|
|
private LocalBluetoothManager mManager;
|
|
private LocalBluetoothProfileManager mProfileManager;
|
|
private CachedBluetoothDevice mCachedDevice;
|
|
private List<CachedBluetoothDevice> mAllOfCachedDevices;
|
|
private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap =
|
|
new HashMap<String, List<CachedBluetoothDevice>>();
|
|
private boolean mIsLeContactSharingEnabled = false;
|
|
private boolean mIsLeAudioToggleEnabled = false;
|
|
|
|
@VisibleForTesting
|
|
PreferenceCategory mProfilesContainer;
|
|
|
|
public BluetoothDetailsProfilesController(Context context, PreferenceFragmentCompat fragment,
|
|
LocalBluetoothManager manager, CachedBluetoothDevice device, Lifecycle lifecycle) {
|
|
super(context, fragment, device, lifecycle);
|
|
mManager = manager;
|
|
mProfileManager = mManager.getProfileManager();
|
|
mCachedDevice = device;
|
|
mAllOfCachedDevices = getAllOfCachedBluetoothDevices();
|
|
lifecycle.addObserver(this);
|
|
}
|
|
|
|
@Override
|
|
protected void init(PreferenceScreen screen) {
|
|
mProfilesContainer = (PreferenceCategory)screen.findPreference(getPreferenceKey());
|
|
mProfilesContainer.setLayoutResource(R.layout.preference_bluetooth_profile_category);
|
|
mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
|
SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true);
|
|
mIsLeAudioToggleEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
|
SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, false);
|
|
// Call refresh here even though it will get called later in onResume, to avoid the
|
|
// list of switches appearing to "pop" into the page.
|
|
refresh();
|
|
}
|
|
|
|
/**
|
|
* Creates a switch preference for the particular profile.
|
|
*
|
|
* @param context The context to use when creating the SwitchPreference
|
|
* @param profile The profile for which the preference controls.
|
|
* @return A preference that allows the user to choose whether this profile
|
|
* will be connected to.
|
|
*/
|
|
private SwitchPreference createProfilePreference(Context context,
|
|
LocalBluetoothProfile profile) {
|
|
SwitchPreference pref = new SwitchPreference(context);
|
|
pref.setKey(profile.toString());
|
|
pref.setTitle(profile.getNameResource(mCachedDevice.getDevice()));
|
|
pref.setOnPreferenceClickListener(this);
|
|
pref.setOrder(profile.getOrdinal());
|
|
return pref;
|
|
}
|
|
|
|
/**
|
|
* Refreshes the state for an existing SwitchPreference for a profile.
|
|
*/
|
|
private void refreshProfilePreference(SwitchPreference profilePref,
|
|
LocalBluetoothProfile profile) {
|
|
BluetoothDevice device = mCachedDevice.getDevice();
|
|
boolean isLeAudioEnabled = isLeAudioEnabled();
|
|
if (profile instanceof A2dpProfile || profile instanceof HeadsetProfile
|
|
|| profile instanceof LeAudioProfile) {
|
|
List<CachedBluetoothDevice> deviceList = mProfileDeviceMap.get(
|
|
profile.toString());
|
|
boolean isBusy = deviceList != null
|
|
&& deviceList.stream().anyMatch(item -> item.isBusy());
|
|
profilePref.setEnabled(!isBusy);
|
|
} else if (profile instanceof PbapServerProfile
|
|
&& isLeAudioEnabled
|
|
&& !mIsLeContactSharingEnabled) {
|
|
profilePref.setEnabled(false);
|
|
} else {
|
|
profilePref.setEnabled(!mCachedDevice.isBusy());
|
|
}
|
|
|
|
if (profile instanceof LeAudioProfile && !mIsLeAudioToggleEnabled) {
|
|
profilePref.setVisible(false);
|
|
}
|
|
|
|
if (profile instanceof MapProfile) {
|
|
profilePref.setChecked(device.getMessageAccessPermission()
|
|
== BluetoothDevice.ACCESS_ALLOWED);
|
|
} else if (profile instanceof PbapServerProfile) {
|
|
profilePref.setChecked(device.getPhonebookAccessPermission()
|
|
== BluetoothDevice.ACCESS_ALLOWED);
|
|
} else if (profile instanceof PanProfile) {
|
|
profilePref.setChecked(profile.getConnectionStatus(device) ==
|
|
BluetoothProfile.STATE_CONNECTED);
|
|
} else {
|
|
profilePref.setChecked(profile.isEnabled(device));
|
|
}
|
|
|
|
if (profile instanceof A2dpProfile) {
|
|
A2dpProfile a2dp = (A2dpProfile) profile;
|
|
SwitchPreference highQualityPref = (SwitchPreference) mProfilesContainer.findPreference(
|
|
HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
if (highQualityPref != null) {
|
|
if (a2dp.isEnabled(device) && a2dp.supportsHighQualityAudio(device)) {
|
|
highQualityPref.setVisible(true);
|
|
highQualityPref.setTitle(a2dp.getHighQualityAudioOptionLabel(device));
|
|
highQualityPref.setChecked(a2dp.isHighQualityAudioEnabled(device));
|
|
highQualityPref.setEnabled(!mCachedDevice.isBusy());
|
|
} else {
|
|
highQualityPref.setVisible(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean isLeAudioEnabled(){
|
|
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()))) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Helper method to enable a profile for a device.
|
|
*/
|
|
private void enableProfile(LocalBluetoothProfile profile) {
|
|
final BluetoothDevice bluetoothDevice = mCachedDevice.getDevice();
|
|
if (profile instanceof PbapServerProfile) {
|
|
bluetoothDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
|
|
// We don't need to do the additional steps below for this profile.
|
|
return;
|
|
}
|
|
if (profile instanceof MapProfile) {
|
|
bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
|
|
}
|
|
|
|
if (profile instanceof LeAudioProfile) {
|
|
enableLeAudioProfile(profile);
|
|
return;
|
|
}
|
|
|
|
profile.setEnabled(bluetoothDevice, true);
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
bluetoothDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When the pref for a bluetooth profile is clicked on, we want to toggle the enabled/disabled
|
|
* state for that profile.
|
|
*/
|
|
@Override
|
|
public boolean onPreferenceClick(Preference preference) {
|
|
LocalBluetoothProfile profile = mProfileManager.getProfileByName(preference.getKey());
|
|
if (profile == null) {
|
|
// It might be the PbapServerProfile, which is not stored by name.
|
|
PbapServerProfile psp = mManager.getProfileManager().getPbapProfile();
|
|
if (TextUtils.equals(preference.getKey(), psp.toString())) {
|
|
profile = psp;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
SwitchPreference profilePref = (SwitchPreference) preference;
|
|
if (profilePref.isChecked()) {
|
|
enableProfile(profile);
|
|
} else {
|
|
disableProfile(profile);
|
|
}
|
|
refreshProfilePreference(profilePref, profile);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Helper to get the list of connectable and special profiles.
|
|
*/
|
|
private List<LocalBluetoothProfile> getProfiles() {
|
|
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);
|
|
} 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) {
|
|
final PbapServerProfile psp = mManager.getProfileManager().getPbapProfile();
|
|
result.add(psp);
|
|
}
|
|
|
|
final MapProfile mapProfile = mManager.getProfileManager().getMapProfile();
|
|
final int mapPermission = device.getMessageAccessPermission();
|
|
if (mapPermission != BluetoothDevice.ACCESS_UNKNOWN) {
|
|
result.add(mapProfile);
|
|
}
|
|
|
|
// Removes phone calls & media audio toggles for dual mode devices
|
|
boolean leAudioSupported = result.contains(
|
|
mManager.getProfileManager().getLeAudioProfile());
|
|
boolean classicAudioSupported = result.contains(
|
|
mManager.getProfileManager().getA2dpProfile()) || result.contains(
|
|
mManager.getProfileManager().getHeadsetProfile());
|
|
if (leAudioSupported && classicAudioSupported) {
|
|
result.remove(mManager.getProfileManager().getA2dpProfile());
|
|
result.remove(mManager.getProfileManager().getHeadsetProfile());
|
|
}
|
|
Log.d(TAG, "getProfiles:Map:" + mProfileDeviceMap);
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Disable the Le Audio profile, VCP, and CSIP for each of the Le Audio devices.
|
|
*
|
|
* @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;
|
|
}
|
|
LocalBluetoothProfile vcp = mProfileManager.getVolumeControlProfile();
|
|
LocalBluetoothProfile csip = mProfileManager.getCsipSetCoordinatorProfile();
|
|
|
|
for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
|
|
Log.d(TAG,
|
|
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
|
|
+ "disable LE profile");
|
|
profile.setEnabled(leAudioDevice.getDevice(), false);
|
|
if (vcp != null) {
|
|
vcp.setEnabled(leAudioDevice.getDevice(), false);
|
|
}
|
|
if (csip != null) {
|
|
csip.setEnabled(leAudioDevice.getDevice(), false);
|
|
}
|
|
}
|
|
|
|
if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
|
|
Log.i(TAG, "Enabling classic audio profiles because dual mode is disabled");
|
|
enableProfileAfterUserDisablesLeAudio(mProfileManager.getA2dpProfile());
|
|
enableProfileAfterUserDisablesLeAudio(mProfileManager.getHeadsetProfile());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enable the Le Audio profile, VCP, and CSIP 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;
|
|
}
|
|
|
|
if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
|
|
Log.i(TAG, "Disabling classic audio profiles because dual mode is disabled");
|
|
disableProfileBeforeUserEnablesLeAudio(mProfileManager.getA2dpProfile());
|
|
disableProfileBeforeUserEnablesLeAudio(mProfileManager.getHeadsetProfile());
|
|
}
|
|
|
|
LocalBluetoothProfile vcp = mProfileManager.getVolumeControlProfile();
|
|
LocalBluetoothProfile csip = mProfileManager.getCsipSetCoordinatorProfile();
|
|
for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
|
|
Log.d(TAG,
|
|
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
|
|
+ "enable LE profile");
|
|
profile.setEnabled(leAudioDevice.getDevice(), true);
|
|
if (vcp != null) {
|
|
vcp.setEnabled(leAudioDevice.getDevice(), true);
|
|
}
|
|
if (csip != null) {
|
|
csip.setEnabled(leAudioDevice.getDevice(), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void disableProfileBeforeUserEnablesLeAudio(LocalBluetoothProfile profile) {
|
|
if (profile != null && mProfileDeviceMap.get(profile.toString()) != null) {
|
|
Log.d(TAG, "Disable " + profile.toString() + " before user enables LE");
|
|
for (CachedBluetoothDevice profileDevice : mProfileDeviceMap.get(profile.toString())) {
|
|
if (profile.isEnabled(profileDevice.getDevice())) {
|
|
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
|
+ profile.toString() + " set disable");
|
|
profile.setEnabled(profileDevice.getDevice(), false);
|
|
} else {
|
|
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
|
+ profile.toString() + " profile is disabled. Do nothing.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void enableProfileAfterUserDisablesLeAudio(LocalBluetoothProfile profile) {
|
|
if (profile != null && mProfileDeviceMap.get(profile.toString()) != null) {
|
|
Log.d(TAG, "enable " + profile.toString() + "after user disables LE");
|
|
for (CachedBluetoothDevice profileDevice : mProfileDeviceMap.get(profile.toString())) {
|
|
if (!profile.isEnabled(profileDevice.getDevice())) {
|
|
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
|
+ profile.toString() + " set enable");
|
|
profile.setEnabled(profileDevice.getDevice(), true);
|
|
} else {
|
|
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
|
+ profile.toString() + " profile is enabled. Do nothing.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* separate preference for controlling whether to actually use high quality audio.
|
|
*
|
|
* @param profile the profile just added
|
|
*/
|
|
private void maybeAddHighQualityAudioPref(LocalBluetoothProfile profile) {
|
|
if (!(profile instanceof A2dpProfile)) {
|
|
return;
|
|
}
|
|
BluetoothDevice device = mCachedDevice.getDevice();
|
|
A2dpProfile a2dp = (A2dpProfile) profile;
|
|
if (a2dp.isProfileReady() && a2dp.supportsHighQualityAudio(device)) {
|
|
SwitchPreference highQualityAudioPref = new SwitchPreference(
|
|
mProfilesContainer.getContext());
|
|
highQualityAudioPref.setKey(HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
highQualityAudioPref.setVisible(false);
|
|
highQualityAudioPref.setOnPreferenceClickListener(clickedPref -> {
|
|
boolean enable = ((SwitchPreference) clickedPref).isChecked();
|
|
a2dp.setHighQualityAudioEnabled(mCachedDevice.getDevice(), enable);
|
|
return true;
|
|
});
|
|
mProfilesContainer.addPreference(highQualityAudioPref);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
|
item.unregisterCallback(this);
|
|
}
|
|
mProfileManager.removeServiceListener(this);
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
|
item.registerCallback(this);
|
|
}
|
|
mProfileManager.addServiceListener(this);
|
|
refresh();
|
|
}
|
|
|
|
@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();
|
|
}
|
|
|
|
@Override
|
|
public void onServiceDisconnected() {
|
|
refresh();
|
|
}
|
|
|
|
/**
|
|
* Refreshes the state of the switches for all profiles, possibly adding or removing switches as
|
|
* needed.
|
|
*/
|
|
@Override
|
|
protected void refresh() {
|
|
for (LocalBluetoothProfile profile : getProfiles()) {
|
|
if (profile == null || !profile.isProfileReady()) {
|
|
continue;
|
|
}
|
|
SwitchPreference pref = mProfilesContainer.findPreference(
|
|
profile.toString());
|
|
if (pref == null) {
|
|
pref = createProfilePreference(mProfilesContainer.getContext(), profile);
|
|
mProfilesContainer.addPreference(pref);
|
|
maybeAddHighQualityAudioPref(profile);
|
|
}
|
|
refreshProfilePreference(pref, profile);
|
|
}
|
|
for (LocalBluetoothProfile removedProfile : mCachedDevice.getRemovedProfiles()) {
|
|
final SwitchPreference pref = mProfilesContainer.findPreference(
|
|
removedProfile.toString());
|
|
if (pref != null) {
|
|
mProfilesContainer.removePreference(pref);
|
|
}
|
|
}
|
|
|
|
Preference preference = mProfilesContainer.findPreference(KEY_BOTTOM_PREFERENCE);
|
|
if (preference == null) {
|
|
preference = new Preference(mContext);
|
|
preference.setLayoutResource(R.layout.preference_bluetooth_profile_category);
|
|
preference.setEnabled(false);
|
|
preference.setKey(KEY_BOTTOM_PREFERENCE);
|
|
preference.setOrder(ORDINAL);
|
|
preference.setSelectable(false);
|
|
mProfilesContainer.addPreference(preference);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getPreferenceKey() {
|
|
return KEY_PROFILES_GROUP;
|
|
}
|
|
}
|