android:entryValues="@array/usb_configuration_values" />
<SwitchPreference
+ android:key="bluetooth_show_devices_without_names"
+ android:title="@string/bluetooth_show_devices_without_names"
+ android:summary="@string/bluetooth_show_devices_without_names_summary"/>
+
+ <SwitchPreference
android:key="bluetooth_disable_absolute_volume"
android:title="@string/bluetooth_disable_absolute_volume"
android:summary="@string/bluetooth_disable_absolute_volume_summary"/>
private final UserManager mUserManager;
private AlertDialog mDisconnectDialog;
-
private String contentDescription = null;
-
+ private DeviceListPreferenceFragment mDeviceListPreferenceFragment;
/* Talk-back descriptions for various BT icons */
Resources mResources;
- public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice) {
+ public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice,
+ DeviceListPreferenceFragment deviceListPreferenceFragment) {
super(context, null);
mResources = getContext().getResources();
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mDeviceListPreferenceFragment = deviceListPreferenceFragment;
if (sDimAlpha == Integer.MIN_VALUE) {
TypedValue outValue = new TypedValue();
// Used to gray out the item
setEnabled(!mCachedDevice.isBusy());
+ // Device is only visible in the UI if it has a valid name besides MAC address or when user
+ // allows showing devices without user-friendly name in developer settings
+ setVisible(mDeviceListPreferenceFragment.shouldShowDevicesWithoutNames()
+ || mCachedDevice.hasHumanReadableName());
+
// This could affect ordering, so notify that
notifyHierarchyChanged();
}
mBluetoothEnabler.resume(getActivity());
}
super.onStart();
+ // Always show paired devices regardless whether user-friendly name exists
+ mShowDevicesWithoutNames = true;
if (isUiRestricted()) {
getPreferenceScreen().removeAll();
if (!isUiRestrictedByOnlyAdmin()) {
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
+import android.os.SystemProperties;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
private static final String KEY_BT_SCAN = "bt_scan";
+ // Copied from DevelopmentSettings.java
+ private static final String BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY =
+ "persist.bluetooth.showdeviceswithoutnames";
+
private BluetoothDeviceFilter.Filter mFilter;
@VisibleForTesting
final WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
+ boolean mShowDevicesWithoutNames;
+
DeviceListPreferenceFragment(String restrictedKey) {
super(restrictedKey);
mFilter = BluetoothDeviceFilter.ALL_FILTER;
@Override
public void onStart() {
super.onStart();
+ mShowDevicesWithoutNames = SystemProperties.getBoolean(
+ BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY, false);
if (mLocalManager == null || isUiRestricted()) return;
mLocalManager.setForegroundActivity(getActivity());
BluetoothDevicePreference preference = (BluetoothDevicePreference) getCachedPreference(key);
if (preference == null) {
- preference = new BluetoothDevicePreference(getPrefContext(), cachedDevice);
+ preference = new BluetoothDevicePreference(getPrefContext(), cachedDevice, this);
preference.setKey(key);
mDeviceListGroup.addPreference(preference);
} else {
* Return the key of the {@link PreferenceGroup} that contains the bluetooth devices
*/
public abstract String getDeviceListKey();
+
+ public boolean shouldShowDevicesWithoutNames() {
+ return mShowDevicesWithoutNames;
+ }
}
private static final String FORCE_RESIZABLE_KEY = "force_resizable_activities";
private static final String COLOR_TEMPERATURE_KEY = "color_temperature";
+ private static final String BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_KEY =
+ "bluetooth_show_devices_without_names";
+ private static final String BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY =
+ "persist.bluetooth.showdeviceswithoutnames";
private static final String BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY =
"bluetooth_disable_absolute_volume";
private static final String BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY =
private SwitchPreference mWifiAggressiveHandover;
private SwitchPreference mMobileDataAlwaysOn;
private SwitchPreference mTetheringHardwareOffload;
+ private SwitchPreference mBluetoothShowDevicesWithoutNames;
private SwitchPreference mBluetoothDisableAbsVolume;
private SwitchPreference mBluetoothEnableInbandRinging;
mLogpersist = null;
}
mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
+ mBluetoothShowDevicesWithoutNames =
+ findAndInitSwitchPref(BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_KEY);
mBluetoothDisableAbsVolume = findAndInitSwitchPref(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY);
mBluetoothEnableInbandRinging = findAndInitSwitchPref(BLUETOOTH_ENABLE_INBAND_RINGING_KEY);
if (!BluetoothHeadset.isInbandRingingSupported(getContext())) {
if (mColorTemperaturePreference != null) {
updateColorTemperature();
}
+ updateBluetoothShowDevicesWithoutUserFriendlyNameOptions();
updateBluetoothDisableAbsVolumeOptions();
updateBluetoothEnableInbandRingingOptions();
updateBluetoothA2dpConfigurationValues();
mWifiManager.setAllowScansWithTraffic(mWifiAllowScansWithTraffic.isChecked() ? 1 : 0);
}
+ private void updateBluetoothShowDevicesWithoutUserFriendlyNameOptions() {
+ updateSwitchPreference(mBluetoothShowDevicesWithoutNames,
+ SystemProperties.getBoolean(
+ BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY, false));
+ }
+
+ private void writeBluetoothShowDevicesWithoutUserFriendlyNameOptions() {
+ SystemProperties.set(BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY,
+ mBluetoothShowDevicesWithoutNames.isChecked() ? "true" : "false");
+ }
+
private void updateBluetoothDisableAbsVolumeOptions() {
updateSwitchPreference(mBluetoothDisableAbsVolume,
SystemProperties.getBoolean(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY, false));
writeUSBAudioOptions();
} else if (preference == mForceResizable) {
writeForceResizableOptions();
+ } else if (preference == mBluetoothShowDevicesWithoutNames) {
+ writeBluetoothShowDevicesWithoutUserFriendlyNameOptions();
} else if (preference == mBluetoothDisableAbsVolume) {
writeBluetoothDisableAbsVolumeOptions();
} else if (preference == mBluetoothEnableInbandRinging) {
import org.robolectric.util.ReflectionHelpers;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
private Context mContext;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private DeviceListPreferenceFragment mDeviceListPreferenceFragment;
private FakeFeatureFactory mFakeFeatureFactory;
private MetricsFeatureProvider mMetricsFeatureProvider;
FakeFeatureFactory.setupForTest(mContext);
mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
- mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice);
+ mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+ mDeviceListPreferenceFragment);
}
@Test
assertThat(mPreference.getIcon()).isEqualTo(
mContext.getDrawable(R.drawable.ic_settings_print));
}
+
+ @Test
+ public void testVisible_notVisibleThenVisible() {
+ when(mDeviceListPreferenceFragment.shouldShowDevicesWithoutNames()).thenReturn(false);
+ final boolean[] humanReadableName = {false};
+ doAnswer(invocation -> humanReadableName[0]).when(mCachedBluetoothDevice)
+ .hasHumanReadableName();
+ BluetoothDevicePreference preference =
+ new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+ mDeviceListPreferenceFragment);
+ assertThat(preference.isVisible()).isFalse();
+ humanReadableName[0] = true;
+ preference.onDeviceAttributesChanged();
+ assertThat(preference.isVisible()).isTrue();
+ }
+
+ @Test
+ public void testVisible_visibleThenNotVisible() {
+ when(mDeviceListPreferenceFragment.shouldShowDevicesWithoutNames()).thenReturn(false);
+ final boolean[] humanReadableName = {true};
+ doAnswer(invocation -> humanReadableName[0]).when(mCachedBluetoothDevice)
+ .hasHumanReadableName();
+ BluetoothDevicePreference preference =
+ new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+ mDeviceListPreferenceFragment);
+ assertThat(preference.isVisible()).isTrue();
+ humanReadableName[0] = false;
+ preference.onDeviceAttributesChanged();
+ assertThat(preference.isVisible()).isFalse();
+ }
+
+ @Test
+ public void testVisible_alwaysVisibleWhenEnabled() {
+ when(mDeviceListPreferenceFragment.shouldShowDevicesWithoutNames()).thenReturn(true);
+ final boolean[] humanReadableName = {true};
+ doAnswer(invocation -> humanReadableName[0]).when(mCachedBluetoothDevice)
+ .hasHumanReadableName();
+ BluetoothDevicePreference preference =
+ new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+ mDeviceListPreferenceFragment);
+ assertThat(preference.isVisible()).isTrue();
+ humanReadableName[0] = false;
+ preference.onDeviceAttributesChanged();
+ assertThat(preference.isVisible()).isTrue();
+ }
}