diff --git a/res/values/strings.xml b/res/values/strings.xml index 137b1712ac4..993eb3030eb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -936,8 +936,8 @@ Scan for devices - - Scan + + Scan Device settings diff --git a/src/com/android/settings/ProgressCategory.java b/src/com/android/settings/ProgressCategory.java index c5b68b6ddeb..bedcc98c327 100644 --- a/src/com/android/settings/ProgressCategory.java +++ b/src/com/android/settings/ProgressCategory.java @@ -23,7 +23,6 @@ import android.view.View; public class ProgressCategory extends ProgressCategoryBase { private boolean mProgress = false; - private View oldView = null; public ProgressCategory(Context context, AttributeSet attrs) { super(context, attrs); @@ -39,13 +38,6 @@ public class ProgressCategory extends ProgressCategoryBase { final int visibility = mProgress ? View.VISIBLE : View.INVISIBLE; textView.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 diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java b/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java index 00e342ced62..e4f11a2a5f3 100644 --- a/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java +++ b/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java @@ -42,6 +42,9 @@ final class BluetoothDeviceFilter { /** Bonded devices only filter (referenced directly). */ 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. */ private static final Filter[] FILTERS = { 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. */ private abstract static class ClassUuidFilter implements Filter { abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass); diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index 391c94126a0..06c708bef35 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -49,8 +49,6 @@ public final class BluetoothDevicePreference extends Preference implements private final CachedBluetoothDevice mCachedDevice; - private ImageView mDeviceSettings; - private OnClickListener mOnSettingsClickListener; private AlertDialog mDisconnectDialog; @@ -121,13 +119,13 @@ public final class BluetoothDevicePreference extends Preference implements btClass.setImageResource(getBtClassDrawable()); btClass.setAlpha(isEnabled() ? 255 : sDimAlpha); btClass.setVisibility(View.VISIBLE); - mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails); + ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails); if (mOnSettingsClickListener != null) { - mDeviceSettings.setOnClickListener(this); - mDeviceSettings.setTag(mCachedDevice); - mDeviceSettings.setAlpha(isEnabled() ? 255 : sDimAlpha); + deviceDetails.setOnClickListener(this); + deviceDetails.setTag(mCachedDevice); + deviceDetails.setAlpha(isEnabled() ? 255 : sDimAlpha); } else { // Hide the settings icon and divider - mDeviceSettings.setVisibility(View.GONE); + deviceDetails.setVisibility(View.GONE); View divider = view.findViewById(R.id.divider); if (divider != null) { divider.setVisibility(View.GONE); @@ -152,13 +150,13 @@ public final class BluetoothDevicePreference extends Preference implements } public void onClick(View v) { - if (v == mDeviceSettings) { - if (mOnSettingsClickListener != null) { - mOnSettingsClickListener.onClick(v); - } + // Should never be null by construction + if (mOnSettingsClickListener != null) { + mOnSettingsClickListener.onClick(v); } } + @Override public boolean equals(Object o) { if ((o == null) || !(o instanceof BluetoothDevicePreference)) { return false; @@ -167,6 +165,7 @@ public final class BluetoothDevicePreference extends Preference implements ((BluetoothDevicePreference) o).mCachedDevice); } + @Override public int hashCode() { return mCachedDevice.hashCode(); } @@ -174,8 +173,8 @@ public final class BluetoothDevicePreference extends Preference implements @Override public int compareTo(Preference another) { if (!(another instanceof BluetoothDevicePreference)) { - // Put other preference types above us - return 1; + // Rely on default sort + return super.compareTo(another); } return mCachedDevice diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java index f20ad784fdd..76bf6232b48 100644 --- a/src/com/android/settings/bluetooth/BluetoothSettings.java +++ b/src/com/android/settings/bluetooth/BluetoothSettings.java @@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.preference.Preference; import android.preference.PreferenceActivity; +import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; import android.util.Log; import android.view.Gravity; @@ -31,6 +32,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.Switch; +import com.android.settings.ProgressCategory; import com.android.settings.R; /** @@ -45,10 +47,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { private BluetoothEnabler mBluetoothEnabler; - /** Initialize the filter to show bonded devices only. */ - //public BluetoothSettings() { - // super(BluetoothDeviceFilter.BONDED_DEVICE_FILTER); - //} + private PreferenceGroup mFoundDevicesCategory; + private boolean mFoundDevicesCategoryIsPresent; @Override void addPreferencesForActivity() { @@ -101,9 +101,9 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 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) - .setEnabled(bluetoothIsEnabled) + .setEnabled(bluetoothIsEnabled && !mLocalAdapter.isDiscovering()) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced) //.setIcon(android.R.drawable.ic_menu_manage) @@ -113,13 +113,9 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - // TODO -// if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) { -// onAddNetworkPressed(); -// } case MENU_ID_SCAN: if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) { - mLocalAdapter.startScanning(true); + startScanning(); } return true; case MENU_ID_ADVANCED: @@ -137,24 +133,12 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { return super.onOptionsItemSelected(item); } - private final View.OnClickListener mListener = 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); - } + private void startScanning() { + if (!mFoundDevicesCategoryIsPresent) { + getPreferenceScreen().addPreference(mFoundDevicesCategory); } - }; + mLocalAdapter.startScanning(true); + } @Override void onDevicePreferenceClick(BluetoothDevicePreference btPreference) { @@ -162,12 +146,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { super.onDevicePreferenceClick(btPreference); } - @Override - public void onBluetoothStateChanged(int bluetoothState) { - super.onBluetoothStateChanged(bluetoothState); - updateContent(bluetoothState); - } - private void updateContent(int bluetoothState) { final PreferenceScreen preferenceScreen = getPreferenceScreen(); getActivity().invalidateOptionsMenu(); @@ -176,9 +154,34 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { switch (bluetoothState) { case BluetoothAdapter.STATE_ON: preferenceScreen.removeAll(); - // Repopulate (which isn't too bad since it's cached in the settings bluetooth manager) - addDevices(); - mLocalAdapter.startScanning(false); + + // Add bonded devices from cache first + 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; case BluetoothAdapter.STATE_TURNING_OFF: @@ -197,31 +200,63 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { break; } + setDeviceListGroup(preferenceScreen); removeAllDevices(); + // TODO: from xml, add top padding. Same as in wifi Preference emptyListPreference = new Preference(getActivity()); emptyListPreference.setTitle(messageId); preferenceScreen.addPreference(emptyListPreference); } - public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { - if (bondState == BluetoothDevice.BOND_BONDED) { - // add to "Paired devices" list after remote-initiated pairing - if (mDevicePreferenceMap.get(cachedDevice) == null) { - createDevicePreference(cachedDevice); - } - } else if (bondState == BluetoothDevice.BOND_NONE) { - // remove unpaired device from paired devices list - onDeviceDeleted(cachedDevice); - } + @Override + public void onBluetoothStateChanged(int bluetoothState) { + super.onBluetoothStateChanged(bluetoothState); + updateContent(bluetoothState); } + @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. * @param preference the newly added preference */ @Override 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); + } } } diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java index 409edb9c08a..9783fd71d5c 100644 --- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java +++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java @@ -62,7 +62,7 @@ public abstract class DeviceListPreferenceFragment extends mFilter = BluetoothDeviceFilter.ALL_FILTER; } - DeviceListPreferenceFragment(BluetoothDeviceFilter.Filter filter) { + final void setFilter(BluetoothDeviceFilter.Filter filter) { mFilter = filter; } @@ -84,14 +84,10 @@ public abstract class DeviceListPreferenceFragment extends addPreferencesForActivity(); 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(); - mDeviceListGroup.setOrderingAsAdded(false); - } - if (mDeviceListGroup == null) { - Log.e(TAG, "Could not find device list preference object!"); - } + } + + void setDeviceListGroup(PreferenceGroup preferenceGroup) { + mDeviceListGroup = preferenceGroup; } /** Add preferences from the subclass. */ @@ -121,7 +117,7 @@ public abstract class DeviceListPreferenceFragment extends mDeviceListGroup.removeAll(); } - void addDevices() { + void addCachedDevices() { Collection cachedDevices = mLocalManager.getCachedDeviceManager().getCachedDevicesCopy(); for (CachedBluetoothDevice cachedDevice : cachedDevices) { @@ -159,7 +155,7 @@ public abstract class DeviceListPreferenceFragment extends 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 (mFilter.matches(cachedDevice.getDevice())) { @@ -199,7 +195,6 @@ public abstract class DeviceListPreferenceFragment extends if (mDeviceListGroup instanceof ProgressCategory) { ((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) { diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java index 3aeb7e2b338..8b32941d3dd 100644 --- a/src/com/android/settings/bluetooth/DevicePickerFragment.java +++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java @@ -55,7 +55,7 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment { @Override public void onResume() { super.onResume(); - addDevices(); + addCachedDevices(); mLocalAdapter.startScanning(true); }