summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/bluetooth/BluetoothSettings.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/bluetooth/BluetoothSettings.java')
-rwxr-xr-xsrc/com/android/settings/bluetooth/BluetoothSettings.java363
1 files changed, 245 insertions, 118 deletions
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index bbbeee5..dd2c9df 100755
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,58 +18,76 @@ package com.android.settings.bluetooth;
import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
-import android.app.ActionBar;
import android.app.Activity;
+import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.Preference;
-import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.util.Log;
-import android.view.Gravity;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.widget.Switch;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
import android.widget.TextView;
import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Index;
+import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
+import com.android.settings.widget.SwitchBar;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
/**
* BluetoothSettings is the Settings screen for Bluetooth configuration and
* connection management.
*/
-public final class BluetoothSettings extends DeviceListPreferenceFragment {
+public final class BluetoothSettings extends DeviceListPreferenceFragment implements Indexable {
private static final String TAG = "BluetoothSettings";
private static final int MENU_ID_SCAN = Menu.FIRST;
private static final int MENU_ID_RENAME_DEVICE = Menu.FIRST + 1;
- private static final int MENU_ID_VISIBILITY_TIMEOUT = Menu.FIRST + 2;
- private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 3;
+ private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 2;
/* Private intent to show the list of received files */
private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
"android.btopp.intent.action.OPEN_RECEIVED_FILES";
- private BluetoothEnabler mBluetoothEnabler;
+ private static View mSettingsDialogView = null;
- private BluetoothDiscoverableEnabler mDiscoverableEnabler;
+ private BluetoothEnabler mBluetoothEnabler;
private PreferenceGroup mPairedDevicesCategory;
-
private PreferenceGroup mAvailableDevicesCategory;
private boolean mAvailableDevicesCategoryIsPresent;
- private boolean mActivityStarted;
+
+ private boolean mInitialScanStarted;
+ private boolean mInitiateDiscoverable;
private TextView mEmptyView;
+ private SwitchBar mSwitchBar;
private final IntentFilter mIntentFilter;
@@ -80,15 +98,23 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
+ final String action = intent.getAction();
+ final int state =
+ intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+
if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
- updateDeviceName();
+ updateDeviceName(context);
+ }
+
+ if (state == BluetoothAdapter.STATE_ON) {
+ mInitiateDiscoverable = true;
}
}
- private void updateDeviceName() {
+ private void updateDeviceName(Context context) {
if (mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
- mMyDevicePreference.setTitle(mLocalAdapter.getName());
+ mMyDevicePreference.setSummary(context.getResources().getString(
+ R.string.bluetooth_is_visible_message, mLocalAdapter.getName()));
}
}
};
@@ -101,36 +127,29 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mActivityStarted = (savedInstanceState == null); // don't auto start scan after rotation
+ mInitialScanStarted = (savedInstanceState != null); // don't auto start scan after rotation
+ mInitiateDiscoverable = true;
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
getListView().setEmptyView(mEmptyView);
+
+ final SettingsActivity activity = (SettingsActivity) getActivity();
+ mSwitchBar = activity.getSwitchBar();
+
+ mBluetoothEnabler = new BluetoothEnabler(activity, mSwitchBar);
+ mBluetoothEnabler.setupSwitchBar();
}
@Override
- void addPreferencesForActivity() {
- addPreferencesFromResource(R.xml.bluetooth_settings);
+ public void onDestroyView() {
+ super.onDestroyView();
- Activity activity = getActivity();
-
- Switch actionBarSwitch = new Switch(activity);
-
- if (activity instanceof PreferenceActivity) {
- PreferenceActivity preferenceActivity = (PreferenceActivity) activity;
- if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {
- final int padding = activity.getResources().getDimensionPixelSize(
- R.dimen.action_bar_switch_padding);
- actionBarSwitch.setPaddingRelative(0, 0, padding, 0);
- activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
- ActionBar.DISPLAY_SHOW_CUSTOM);
- activity.getActionBar().setCustomView(actionBarSwitch, new ActionBar.LayoutParams(
- ActionBar.LayoutParams.WRAP_CONTENT,
- ActionBar.LayoutParams.WRAP_CONTENT,
- Gravity.CENTER_VERTICAL | Gravity.END));
- }
- }
+ mBluetoothEnabler.teardownSwitchBar();
+ }
- mBluetoothEnabler = new BluetoothEnabler(activity, actionBarSwitch);
+ @Override
+ void addPreferencesForActivity() {
+ addPreferencesFromResource(R.xml.bluetooth_settings);
setHasOptionsMenu(true);
}
@@ -140,16 +159,22 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
// resume BluetoothEnabler before calling super.onResume() so we don't get
// any onDeviceAdded() callbacks before setting up view in updateContent()
if (mBluetoothEnabler != null) {
- mBluetoothEnabler.resume();
+ mBluetoothEnabler.resume(getActivity());
}
super.onResume();
- if (mDiscoverableEnabler != null) {
- mDiscoverableEnabler.resume();
+ mInitiateDiscoverable = true;
+
+ if (isUiRestricted()) {
+ setDeviceListGroup(getPreferenceScreen());
+ removeAllDevices();
+ mEmptyView.setText(R.string.bluetooth_empty_list_user_restricted);
+ return;
}
+
getActivity().registerReceiver(mReceiver, mIntentFilter);
if (mLocalAdapter != null) {
- updateContent(mLocalAdapter.getBluetoothState(), mActivityStarted);
+ updateContent(mLocalAdapter.getBluetoothState());
}
}
@@ -159,17 +184,22 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
if (mBluetoothEnabler != null) {
mBluetoothEnabler.pause();
}
- getActivity().unregisterReceiver(mReceiver);
- if (mDiscoverableEnabler != null) {
- mDiscoverableEnabler.pause();
+
+ // Make the device only visible to connected devices.
+ mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+
+ if (isUiRestricted()) {
+ return;
}
+
+ getActivity().unregisterReceiver(mReceiver);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (mLocalAdapter == null) return;
// If the user is not allowed to configure bluetooth, do not show the menu.
- if (isRestrictedAndNotPinProtected()) return;
+ if (isUiRestricted()) return;
boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON;
boolean isDiscovering = mLocalAdapter.isDiscovering();
@@ -177,11 +207,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
R.string.bluetooth_search_for_devices;
menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
.setEnabled(bluetoothIsEnabled && !isDiscovering)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
- .setEnabled(bluetoothIsEnabled)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- menu.add(Menu.NONE, MENU_ID_VISIBILITY_TIMEOUT, 0, R.string.bluetooth_visibility_timeout)
+ menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
.setEnabled(bluetoothIsEnabled)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
@@ -203,11 +230,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
getFragmentManager(), "rename device");
return true;
- case MENU_ID_VISIBILITY_TIMEOUT:
- new BluetoothVisibilityTimeoutFragment().show(
- getFragmentManager(), "visibility timeout");
- return true;
-
case MENU_ID_SHOW_RECEIVED:
Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
getActivity().sendBroadcast(intent);
@@ -217,10 +239,23 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
}
private void startScanning() {
- if (isRestrictedAndNotPinProtected()) return;
+ if (isUiRestricted()) {
+ return;
+ }
+
if (!mAvailableDevicesCategoryIsPresent) {
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
+ mAvailableDevicesCategoryIsPresent = true;
}
+
+ if (mAvailableDevicesCategory != null) {
+ setDeviceListGroup(mAvailableDevicesCategory);
+ removeAllDevices();
+ }
+
+ mLocalManager.getCachedDeviceManager().clearNonBondedDevices();
+ mAvailableDevicesCategory.removeAll();
+ mInitialScanStarted = true;
mLocalAdapter.startScanning(true);
}
@@ -231,16 +266,18 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
}
private void addDeviceCategory(PreferenceGroup preferenceGroup, int titleId,
- BluetoothDeviceFilter.Filter filter) {
+ BluetoothDeviceFilter.Filter filter, boolean addCachedDevices) {
preferenceGroup.setTitle(titleId);
getPreferenceScreen().addPreference(preferenceGroup);
setFilter(filter);
setDeviceListGroup(preferenceGroup);
- addCachedDevices();
+ if (addCachedDevices) {
+ addCachedDevices();
+ }
preferenceGroup.setEnabled(true);
}
- private void updateContent(int bluetoothState, boolean scanState) {
+ private void updateContent(int bluetoothState) {
final PreferenceScreen preferenceScreen = getPreferenceScreen();
int messageId = 0;
@@ -250,28 +287,9 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
preferenceScreen.setOrderingAsAdded(true);
mDevicePreferenceMap.clear();
- // This device
- if (mMyDevicePreference == null) {
- mMyDevicePreference = new Preference(getActivity());
- }
- mMyDevicePreference.setTitle(mLocalAdapter.getName());
- if (getResources().getBoolean(com.android.internal.R.bool.config_voice_capable)) {
- mMyDevicePreference.setIcon(R.drawable.ic_bt_cellphone); // for phones
- } else {
- mMyDevicePreference.setIcon(R.drawable.ic_bt_laptop); // for tablets, etc.
- }
- mMyDevicePreference.setPersistent(false);
- mMyDevicePreference.setEnabled(true);
- preferenceScreen.addPreference(mMyDevicePreference);
-
- if (!isRestrictedAndNotPinProtected()) {
- if (mDiscoverableEnabler == null) {
- mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
- mLocalAdapter, mMyDevicePreference);
- mDiscoverableEnabler.resume();
- LocalBluetoothManager.getInstance(getActivity()).setDiscoverableEnabler(
- mDiscoverableEnabler);
- }
+ if (isUiRestricted()) {
+ messageId = R.string.bluetooth_empty_list_user_restricted;
+ break;
}
// Paired devices category
@@ -282,44 +300,47 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
}
addDeviceCategory(mPairedDevicesCategory,
R.string.bluetooth_preference_paired_devices,
- BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
+ BluetoothDeviceFilter.BONDED_DEVICE_FILTER, true);
int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
- if (mDiscoverableEnabler != null) {
- mDiscoverableEnabler.setNumberOfPairedDevices(numberOfPairedDevices);
+ if (isUiRestricted() || numberOfPairedDevices <= 0) {
+ preferenceScreen.removePreference(mPairedDevicesCategory);
}
// Available devices category
if (mAvailableDevicesCategory == null) {
- mAvailableDevicesCategory = new BluetoothProgressCategory(getActivity(), null);
+ mAvailableDevicesCategory = new BluetoothProgressCategory(getActivity());
+ mAvailableDevicesCategory.setSelectable(false);
} else {
mAvailableDevicesCategory.removeAll();
}
- if (!isRestrictedAndNotPinProtected()) {
- addDeviceCategory(mAvailableDevicesCategory,
- R.string.bluetooth_preference_found_devices,
- BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER);
- }
+ addDeviceCategory(mAvailableDevicesCategory,
+ R.string.bluetooth_preference_found_devices,
+ BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, mInitialScanStarted);
int numberOfAvailableDevices = mAvailableDevicesCategory.getPreferenceCount();
- mAvailableDevicesCategoryIsPresent = true;
- if (numberOfAvailableDevices == 0) {
- preferenceScreen.removePreference(mAvailableDevicesCategory);
- mAvailableDevicesCategoryIsPresent = false;
+ if (!mInitialScanStarted) {
+ startScanning();
}
- if (numberOfPairedDevices == 0) {
- preferenceScreen.removePreference(mPairedDevicesCategory);
- if (scanState == true) {
- mActivityStarted = false;
- startScanning();
- } else {
- if (!mAvailableDevicesCategoryIsPresent) {
- getPreferenceScreen().addPreference(mAvailableDevicesCategory);
- }
- }
+ if (mMyDevicePreference == null) {
+ mMyDevicePreference = new Preference(getActivity());
}
+
+ mMyDevicePreference.setSummary(getResources().getString(
+ R.string.bluetooth_is_visible_message, mLocalAdapter.getName()));
+ mMyDevicePreference.setSelectable(false);
+ preferenceScreen.addPreference(mMyDevicePreference);
+
getActivity().invalidateOptionsMenu();
+
+ // mLocalAdapter.setScanMode is internally synchronized so it is okay for multiple
+ // threads to execute.
+ if (mInitiateDiscoverable) {
+ // Make the device visible to other devices.
+ mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ mInitiateDiscoverable = false;
+ }
return; // not break
case BluetoothAdapter.STATE_TURNING_OFF:
@@ -328,55 +349,126 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
case BluetoothAdapter.STATE_OFF:
messageId = R.string.bluetooth_empty_list_bluetooth_off;
+ if (isUiRestricted()) {
+ messageId = R.string.bluetooth_empty_list_user_restricted;
+ }
break;
case BluetoothAdapter.STATE_TURNING_ON:
messageId = R.string.bluetooth_turning_on;
+ mInitialScanStarted = false;
break;
}
setDeviceListGroup(preferenceScreen);
removeAllDevices();
mEmptyView.setText(messageId);
- getActivity().invalidateOptionsMenu();
+ if (!isUiRestricted()) {
+ getActivity().invalidateOptionsMenu();
+ }
}
@Override
public void onBluetoothStateChanged(int bluetoothState) {
super.onBluetoothStateChanged(bluetoothState);
- updateContent(bluetoothState, true);
+ updateContent(bluetoothState);
}
@Override
public void onScanningStateChanged(boolean started) {
super.onScanningStateChanged(started);
// Update options' enabled state
- getActivity().invalidateOptionsMenu();
+ if (getActivity() != null) {
+ getActivity().invalidateOptionsMenu();
+ }
}
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
setDeviceListGroup(getPreferenceScreen());
removeAllDevices();
- updateContent(mLocalAdapter.getBluetoothState(), false);
+ updateContent(mLocalAdapter.getBluetoothState());
}
- private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
+ 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) {
- if (isRestrictedAndNotPinProtected()) return;
+ if (!(v.getTag() instanceof CachedBluetoothDevice)) {
+ Log.w(TAG, "onClick() called for other View: " + v);
+ return;
+ }
- CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
+ final CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
+ final Activity activity = getActivity();
+ DeviceProfilesSettings profileFragment = (DeviceProfilesSettings)activity.
+ getFragmentManager().findFragmentById(R.id.bluetooth_fragment_settings);
- Bundle args = new Bundle(1);
- args.putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, device.getDevice());
+ if (mSettingsDialogView != null){
+ ViewGroup parent = (ViewGroup) mSettingsDialogView.getParent();
+ if (parent != null) {
+ parent.removeView(mSettingsDialogView);
+ }
+ }
+
+ if (profileFragment == null) {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ mSettingsDialogView = inflater.inflate(R.layout.bluetooth_device_settings, null);
+ profileFragment = (DeviceProfilesSettings)activity.getFragmentManager()
+ .findFragmentById(R.id.bluetooth_fragment_settings);
- ((PreferenceActivity) getActivity()).startPreferencePanel(
- DeviceProfilesSettings.class.getName(), args,
- R.string.bluetooth_device_advanced_title, null, null, 0);
- } else {
- Log.w(TAG, "onClick() called for other View: " + v); // TODO remove
+ // To enable scrolling we store the name field in a seperate header and add to
+ // the ListView of the profileFragment.
+ View header = inflater.inflate(R.layout.bluetooth_device_settings_header, null);
+ profileFragment.getListView().addHeaderView(header);
}
+
+ final View dialogLayout = mSettingsDialogView;
+ AlertDialog.Builder settingsDialog = new AlertDialog.Builder(activity);
+ profileFragment.setDevice(device);
+ final EditText deviceName = (EditText)dialogLayout.findViewById(R.id.name);
+ deviceName.setText(device.getName(), TextView.BufferType.EDITABLE);
+
+ final DeviceProfilesSettings dpsFragment = profileFragment;
+ final Context context = v.getContext();
+ settingsDialog.setView(dialogLayout);
+ settingsDialog.setTitle(R.string.bluetooth_preference_paired_devices);
+ settingsDialog.setPositiveButton(R.string.okay,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ EditText deviceName = (EditText)dialogLayout.findViewById(R.id.name);
+ device.setName(deviceName.getText().toString());
+ }
+ });
+
+ settingsDialog.setNegativeButton(R.string.forget,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ device.unpair();
+ com.android.settings.bluetooth.Utils.updateSearchIndex(activity,
+ BluetoothSettings.class.getName(), device.getName(),
+ context.getResources().getString(R.string.bluetooth_settings),
+ R.drawable.ic_settings_bluetooth2, false);
+ }
+ });
+
+ // We must ensure that the fragment gets destroyed to avoid duplicate fragments.
+ settingsDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ public void onDismiss(final DialogInterface dialog) {
+ if (!activity.isDestroyed()) {
+ activity.getFragmentManager().beginTransaction().remove(dpsFragment)
+ .commitAllowingStateLoss();
+ }
+ }
+ });
+
+ AlertDialog dialog = settingsDialog.create();
+ dialog.create();
+ dialog.show();
+
+ // We must ensure that clicking on the EditText will bring up the keyboard.
+ dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
};
@@ -397,4 +489,39 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
protected int getHelpResource() {
return R.string.help_url_bluetooth;
}
+
+ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+
+ final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
+
+ final Resources res = context.getResources();
+
+ // Add fragment title
+ SearchIndexableRaw data = new SearchIndexableRaw(context);
+ data.title = res.getString(R.string.bluetooth_settings);
+ data.screenTitle = res.getString(R.string.bluetooth_settings);
+ result.add(data);
+
+ // Add cached paired BT devices
+ LocalBluetoothManager lbtm = LocalBluetoothManager.getInstance(context);
+ // LocalBluetoothManager.getInstance can return null if the device does not
+ // support bluetooth (e.g. the emulator).
+ if (lbtm != null) {
+ Set<BluetoothDevice> bondedDevices =
+ lbtm.getBluetoothAdapter().getBondedDevices();
+
+ for (BluetoothDevice device : bondedDevices) {
+ data = new SearchIndexableRaw(context);
+ data.title = device.getName();
+ data.screenTitle = res.getString(R.string.bluetooth_settings);
+ data.enabled = enabled;
+ result.add(data);
+ }
+ }
+ return result;
+ }
+ };
}