Merge "Double list in Bluetooth Settings"

This commit is contained in:
Gilles Debunne
2011-06-29 15:59:21 -07:00
committed by Android (Google) Code Review
7 changed files with 115 additions and 84 deletions

View File

@@ -936,8 +936,8 @@
<!-- Bluetooth settings: The title of the preference (list item) that initiates a scan for devices --> <!-- Bluetooth settings: The title of the preference (list item) that initiates a scan for devices -->
<string name="bluetooth_preference_scan_title">Scan for devices</string> <string name="bluetooth_preference_scan_title">Scan for devices</string>
<!-- Bluetooth settings: The title of the action button that finds nearby devices [CHAR LIMIT=20] --> <!-- Bluetooth settings: The title of the action button that initiates a scan for nearby devices [CHAR LIMIT=20] -->
<string name="bluetooth_preference_find_nearby_title">Scan</string> <string name="bluetooth_scan_nearby_devices">Scan</string>
<!-- Bluetooth settings: The sub heading for device settings. [CHAR LIMIT=30] --> <!-- Bluetooth settings: The sub heading for device settings. [CHAR LIMIT=30] -->
<string name="bluetooth_preference_device_settings">Device settings</string> <string name="bluetooth_preference_device_settings">Device settings</string>
<!-- Bluetooth settings: The sub heading for paired devices. [CHAR LIMIT=30] --> <!-- Bluetooth settings: The sub heading for paired devices. [CHAR LIMIT=30] -->

View File

@@ -23,7 +23,6 @@ import android.view.View;
public class ProgressCategory extends ProgressCategoryBase { public class ProgressCategory extends ProgressCategoryBase {
private boolean mProgress = false; private boolean mProgress = false;
private View oldView = null;
public ProgressCategory(Context context, AttributeSet attrs) { public ProgressCategory(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@@ -39,13 +38,6 @@ public class ProgressCategory extends ProgressCategoryBase {
final int visibility = mProgress ? View.VISIBLE : View.INVISIBLE; final int visibility = mProgress ? View.VISIBLE : View.INVISIBLE;
textView.setVisibility(visibility); textView.setVisibility(visibility);
progressBar.setVisibility(visibility); progressBar.setVisibility(visibility);
if (oldView != null) {
oldView.findViewById(R.id.scanning_progress).setVisibility(View.GONE);
oldView.findViewById(R.id.scanning_text).setVisibility(View.GONE);
oldView.setVisibility(View.GONE);
}
oldView = view;
} }
@Override @Override

View File

@@ -42,6 +42,9 @@ final class BluetoothDeviceFilter {
/** Bonded devices only filter (referenced directly). */ /** Bonded devices only filter (referenced directly). */
static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter(); static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter();
/** Unbonded devices only filter (referenced directly). */
static final Filter UNBONDED_DEVICE_FILTER = new UnbondedDeviceFilter();
/** Table of singleton filter objects. */ /** Table of singleton filter objects. */
private static final Filter[] FILTERS = { private static final Filter[] FILTERS = {
ALL_FILTER, // FILTER_TYPE_ALL ALL_FILTER, // FILTER_TYPE_ALL
@@ -85,6 +88,13 @@ final class BluetoothDeviceFilter {
} }
} }
/** Filter that matches only unbonded devices. */
private static final class UnbondedDeviceFilter implements Filter {
public boolean matches(BluetoothDevice device) {
return device.getBondState() != BluetoothDevice.BOND_BONDED;
}
}
/** Parent class of filters based on UUID and/or Bluetooth class. */ /** Parent class of filters based on UUID and/or Bluetooth class. */
private abstract static class ClassUuidFilter implements Filter { private abstract static class ClassUuidFilter implements Filter {
abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass); abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass);

View File

@@ -49,8 +49,6 @@ public final class BluetoothDevicePreference extends Preference implements
private final CachedBluetoothDevice mCachedDevice; private final CachedBluetoothDevice mCachedDevice;
private ImageView mDeviceSettings;
private OnClickListener mOnSettingsClickListener; private OnClickListener mOnSettingsClickListener;
private AlertDialog mDisconnectDialog; private AlertDialog mDisconnectDialog;
@@ -121,13 +119,13 @@ public final class BluetoothDevicePreference extends Preference implements
btClass.setImageResource(getBtClassDrawable()); btClass.setImageResource(getBtClassDrawable());
btClass.setAlpha(isEnabled() ? 255 : sDimAlpha); btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
btClass.setVisibility(View.VISIBLE); btClass.setVisibility(View.VISIBLE);
mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails); ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails);
if (mOnSettingsClickListener != null) { if (mOnSettingsClickListener != null) {
mDeviceSettings.setOnClickListener(this); deviceDetails.setOnClickListener(this);
mDeviceSettings.setTag(mCachedDevice); deviceDetails.setTag(mCachedDevice);
mDeviceSettings.setAlpha(isEnabled() ? 255 : sDimAlpha); deviceDetails.setAlpha(isEnabled() ? 255 : sDimAlpha);
} else { // Hide the settings icon and divider } else { // Hide the settings icon and divider
mDeviceSettings.setVisibility(View.GONE); deviceDetails.setVisibility(View.GONE);
View divider = view.findViewById(R.id.divider); View divider = view.findViewById(R.id.divider);
if (divider != null) { if (divider != null) {
divider.setVisibility(View.GONE); divider.setVisibility(View.GONE);
@@ -152,13 +150,13 @@ public final class BluetoothDevicePreference extends Preference implements
} }
public void onClick(View v) { public void onClick(View v) {
if (v == mDeviceSettings) { // Should never be null by construction
if (mOnSettingsClickListener != null) { if (mOnSettingsClickListener != null) {
mOnSettingsClickListener.onClick(v); mOnSettingsClickListener.onClick(v);
}
} }
} }
@Override
public boolean equals(Object o) { public boolean equals(Object o) {
if ((o == null) || !(o instanceof BluetoothDevicePreference)) { if ((o == null) || !(o instanceof BluetoothDevicePreference)) {
return false; return false;
@@ -167,6 +165,7 @@ public final class BluetoothDevicePreference extends Preference implements
((BluetoothDevicePreference) o).mCachedDevice); ((BluetoothDevicePreference) o).mCachedDevice);
} }
@Override
public int hashCode() { public int hashCode() {
return mCachedDevice.hashCode(); return mCachedDevice.hashCode();
} }
@@ -174,8 +173,8 @@ public final class BluetoothDevicePreference extends Preference implements
@Override @Override
public int compareTo(Preference another) { public int compareTo(Preference another) {
if (!(another instanceof BluetoothDevicePreference)) { if (!(another instanceof BluetoothDevicePreference)) {
// Put other preference types above us // Rely on default sort
return 1; return super.compareTo(another);
} }
return mCachedDevice return mCachedDevice

View File

@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.util.Log; import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
@@ -31,6 +32,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Switch; import android.widget.Switch;
import com.android.settings.ProgressCategory;
import com.android.settings.R; import com.android.settings.R;
/** /**
@@ -45,10 +47,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
private BluetoothEnabler mBluetoothEnabler; private BluetoothEnabler mBluetoothEnabler;
/** Initialize the filter to show bonded devices only. */ private PreferenceGroup mFoundDevicesCategory;
//public BluetoothSettings() { private boolean mFoundDevicesCategoryIsPresent;
// super(BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
//}
@Override @Override
void addPreferencesForActivity() { void addPreferencesForActivity() {
@@ -101,9 +101,9 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON; boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON;
menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.bluetooth_preference_find_nearby_title) menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.bluetooth_scan_nearby_devices)
//.setIcon(R.drawable.ic_menu_scan_network) //.setIcon(R.drawable.ic_menu_scan_network)
.setEnabled(bluetoothIsEnabled) .setEnabled(bluetoothIsEnabled && !mLocalAdapter.isDiscovering())
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced) menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced)
//.setIcon(android.R.drawable.ic_menu_manage) //.setIcon(android.R.drawable.ic_menu_manage)
@@ -113,13 +113,9 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
// TODO
// if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
// onAddNetworkPressed();
// }
case MENU_ID_SCAN: case MENU_ID_SCAN:
if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) { if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
mLocalAdapter.startScanning(true); startScanning();
} }
return true; return true;
case MENU_ID_ADVANCED: case MENU_ID_ADVANCED:
@@ -137,24 +133,12 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private final View.OnClickListener mListener = new View.OnClickListener() { private void startScanning() {
public void onClick(View v) { if (!mFoundDevicesCategoryIsPresent) {
// User clicked on advanced options icon for a device in the list getPreferenceScreen().addPreference(mFoundDevicesCategory);
if (v.getTag() instanceof CachedBluetoothDevice) {
CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
Preference pref = new Preference(getActivity());
pref.setTitle(device.getName());
pref.setFragment(DeviceProfilesSettings.class.getName());
pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
device.getDevice());
((PreferenceActivity) getActivity()).onPreferenceStartFragment(
BluetoothSettings.this, pref);
} else {
Log.w(TAG, "onClick() called for other View: " + v);
}
} }
}; mLocalAdapter.startScanning(true);
}
@Override @Override
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) { void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
@@ -162,12 +146,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
super.onDevicePreferenceClick(btPreference); super.onDevicePreferenceClick(btPreference);
} }
@Override
public void onBluetoothStateChanged(int bluetoothState) {
super.onBluetoothStateChanged(bluetoothState);
updateContent(bluetoothState);
}
private void updateContent(int bluetoothState) { private void updateContent(int bluetoothState) {
final PreferenceScreen preferenceScreen = getPreferenceScreen(); final PreferenceScreen preferenceScreen = getPreferenceScreen();
getActivity().invalidateOptionsMenu(); getActivity().invalidateOptionsMenu();
@@ -176,9 +154,34 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
switch (bluetoothState) { switch (bluetoothState) {
case BluetoothAdapter.STATE_ON: case BluetoothAdapter.STATE_ON:
preferenceScreen.removeAll(); preferenceScreen.removeAll();
// Repopulate (which isn't too bad since it's cached in the settings bluetooth manager)
addDevices(); // Add bonded devices from cache first
mLocalAdapter.startScanning(false); setFilter(BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
setDeviceListGroup(preferenceScreen);
preferenceScreen.setOrderingAsAdded(true);
addCachedDevices();
int numberOfPairedDevices = preferenceScreen.getPreferenceCount();
// Found devices category
mFoundDevicesCategory = new ProgressCategory(getActivity(), null);
mFoundDevicesCategory.setTitle(R.string.bluetooth_preference_found_devices);
preferenceScreen.addPreference(mFoundDevicesCategory);
mFoundDevicesCategoryIsPresent = true;
// Unbonded found devices from cache
setFilter(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER);
setDeviceListGroup(mFoundDevicesCategory);
addCachedDevices();
int numberOfUnpairedDevices = mFoundDevicesCategory.getPreferenceCount();
if (numberOfUnpairedDevices == 0) {
preferenceScreen.removePreference(mFoundDevicesCategory);
mFoundDevicesCategoryIsPresent = false;
}
if (numberOfPairedDevices == 0) startScanning();
return; return;
case BluetoothAdapter.STATE_TURNING_OFF: case BluetoothAdapter.STATE_TURNING_OFF:
@@ -197,31 +200,63 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
break; break;
} }
setDeviceListGroup(preferenceScreen);
removeAllDevices(); removeAllDevices();
// TODO: from xml, add top padding. Same as in wifi // TODO: from xml, add top padding. Same as in wifi
Preference emptyListPreference = new Preference(getActivity()); Preference emptyListPreference = new Preference(getActivity());
emptyListPreference.setTitle(messageId); emptyListPreference.setTitle(messageId);
preferenceScreen.addPreference(emptyListPreference); preferenceScreen.addPreference(emptyListPreference);
} }
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { @Override
if (bondState == BluetoothDevice.BOND_BONDED) { public void onBluetoothStateChanged(int bluetoothState) {
// add to "Paired devices" list after remote-initiated pairing super.onBluetoothStateChanged(bluetoothState);
if (mDevicePreferenceMap.get(cachedDevice) == null) { updateContent(bluetoothState);
createDevicePreference(cachedDevice);
}
} else if (bondState == BluetoothDevice.BOND_NONE) {
// remove unpaired device from paired devices list
onDeviceDeleted(cachedDevice);
}
} }
@Override
public void onScanningStateChanged(boolean started) {
super.onScanningStateChanged(started);
// Update 'Scan' option enabled state
getActivity().invalidateOptionsMenu();
}
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
setDeviceListGroup(getPreferenceScreen());
removeAllDevices();
updateContent(mLocalAdapter.getBluetoothState());
}
private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
public void onClick(View v) {
// User clicked on advanced options icon for a device in the list
if (v.getTag() instanceof CachedBluetoothDevice) {
CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
Preference pref = new Preference(getActivity());
pref.setTitle(device.getName());
pref.setFragment(DeviceProfilesSettings.class.getName());
pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
device.getDevice());
((PreferenceActivity) getActivity()).onPreferenceStartFragment(
BluetoothSettings.this, pref);
} else {
Log.w(TAG, "onClick() called for other View: " + v); // TODO remove
}
}
};
/** /**
* Add a listener, which enables the advanced settings icon. * Add a listener, which enables the advanced settings icon.
* @param preference the newly added preference * @param preference the newly added preference
*/ */
@Override @Override
void initDevicePreference(BluetoothDevicePreference preference) { void initDevicePreference(BluetoothDevicePreference preference) {
preference.setOnSettingsClickListener(mListener); CachedBluetoothDevice cachedDevice = preference.getCachedDevice();
if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
// Only paired device have an associated advanced settings screen
preference.setOnSettingsClickListener(mDeviceProfilesListener);
}
} }
} }

View File

@@ -62,7 +62,7 @@ public abstract class DeviceListPreferenceFragment extends
mFilter = BluetoothDeviceFilter.ALL_FILTER; mFilter = BluetoothDeviceFilter.ALL_FILTER;
} }
DeviceListPreferenceFragment(BluetoothDeviceFilter.Filter filter) { final void setFilter(BluetoothDeviceFilter.Filter filter) {
mFilter = filter; mFilter = filter;
} }
@@ -84,14 +84,10 @@ public abstract class DeviceListPreferenceFragment extends
addPreferencesForActivity(); addPreferencesForActivity();
mDeviceListGroup = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST); mDeviceListGroup = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
if (mDeviceListGroup == null) { }
// If null, device preferences are added directly to the root of the preference screen
mDeviceListGroup = getPreferenceScreen(); void setDeviceListGroup(PreferenceGroup preferenceGroup) {
mDeviceListGroup.setOrderingAsAdded(false); mDeviceListGroup = preferenceGroup;
}
if (mDeviceListGroup == null) {
Log.e(TAG, "Could not find device list preference object!");
}
} }
/** Add preferences from the subclass. */ /** Add preferences from the subclass. */
@@ -121,7 +117,7 @@ public abstract class DeviceListPreferenceFragment extends
mDeviceListGroup.removeAll(); mDeviceListGroup.removeAll();
} }
void addDevices() { void addCachedDevices() {
Collection<CachedBluetoothDevice> cachedDevices = Collection<CachedBluetoothDevice> cachedDevices =
mLocalManager.getCachedDeviceManager().getCachedDevicesCopy(); mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
for (CachedBluetoothDevice cachedDevice : cachedDevices) { for (CachedBluetoothDevice cachedDevice : cachedDevices) {
@@ -159,7 +155,7 @@ public abstract class DeviceListPreferenceFragment extends
return; return;
} }
// No update while list shows state message // Prevent updates while the list shows one of the state messages
if (mLocalAdapter.getBluetoothState() != BluetoothAdapter.STATE_ON) return; if (mLocalAdapter.getBluetoothState() != BluetoothAdapter.STATE_ON) return;
if (mFilter.matches(cachedDevice.getDevice())) { if (mFilter.matches(cachedDevice.getDevice())) {
@@ -199,7 +195,6 @@ public abstract class DeviceListPreferenceFragment extends
if (mDeviceListGroup instanceof ProgressCategory) { if (mDeviceListGroup instanceof ProgressCategory) {
((ProgressCategory) mDeviceListGroup).setProgress(start); ((ProgressCategory) mDeviceListGroup).setProgress(start);
} }
// else TODO Add a spinner at the end of the list to show in progress state
} }
public void onBluetoothStateChanged(int bluetoothState) { public void onBluetoothStateChanged(int bluetoothState) {

View File

@@ -55,7 +55,7 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
addDevices(); addCachedDevices();
mLocalAdapter.startScanning(true); mLocalAdapter.startScanning(true);
} }