summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/bluetooth')
-rw-r--r--src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java96
-rw-r--r--src/com/android/settings/bluetooth/BluetoothDevicePreference.java7
-rw-r--r--src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java147
-rw-r--r--src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java161
-rw-r--r--src/com/android/settings/bluetooth/BluetoothNamePreference.java143
-rw-r--r--src/com/android/settings/bluetooth/BluetoothPairingDialog.java94
-rw-r--r--src/com/android/settings/bluetooth/BluetoothSettings.java97
-rw-r--r--src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java68
-rw-r--r--src/com/android/settings/bluetooth/CachedBluetoothDevice.java8
9 files changed, 485 insertions, 336 deletions
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java b/src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java
deleted file mode 100644
index 83371cd..0000000
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2011 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.content.Intent;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-public class AdvancedBluetoothSettings extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
- private static final String KEY_BT_DISCOVERABLE_TIMEOUT = "bt_discoverable_timeout";
- private static final String KEY_BT_NAME = "bt_name";
- private static final String KEY_BT_SHOW_RECEIVED = "bt_show_received_files";
-
- /* 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 BluetoothDiscoverableEnabler mDiscoverableEnabler;
- private BluetoothNamePreference mNamePreference;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.bluetooth_advanced_settings);
-
- LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(getActivity());
- if (localManager != null) {
- LocalBluetoothAdapter localAdapter = localManager.getBluetoothAdapter();
- mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
- localAdapter,
- (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE),
- (ListPreference) findPreference(KEY_BT_DISCOVERABLE_TIMEOUT));
- }
-
- mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mDiscoverableEnabler.resume();
- mNamePreference.resume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- mNamePreference.pause();
- mDiscoverableEnabler.pause();
- }
-
- @Override
- public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
- if (KEY_BT_SHOW_RECEIVED.equals(preference.getKey())) {
- Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
- getActivity().sendBroadcast(intent);
- return true;
- }
-
- return super.onPreferenceTreeClick(preferenceScreen, preference);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- return true;
- }
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 06c708b..68180c6 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
+import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
@@ -200,7 +201,8 @@ public final class BluetoothDevicePreference extends Preference implements
if (TextUtils.isEmpty(name)) {
name = context.getString(R.string.bluetooth_device);
}
- String message = context.getString(R.string.bluetooth_disconnect_blank, name);
+ String message = context.getString(R.string.bluetooth_disconnect_all_profiles, name);
+ String title = context.getString(R.string.bluetooth_disconnect_title);
DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@@ -209,7 +211,7 @@ public final class BluetoothDevicePreference extends Preference implements
};
mDisconnectDialog = Utils.showDisconnectDialog(context,
- mDisconnectDialog, disconnectListener, name, message);
+ mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
}
private void pair() {
@@ -221,7 +223,6 @@ public final class BluetoothDevicePreference extends Preference implements
private int getConnectionSummary() {
final CachedBluetoothDevice cachedDevice = mCachedDevice;
- final BluetoothDevice device = cachedDevice.getDevice();
// if any profiles are connected or busy, return that status
for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index 40bf5bc..0ad8948 100644
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -21,11 +21,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.os.Handler;
import android.os.SystemProperties;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
import android.preference.Preference;
+import android.text.format.DateUtils;
import com.android.settings.R;
@@ -34,7 +34,7 @@ import com.android.settings.R;
* checkbox. It sets/unsets discoverability and keeps track of how much time
* until the the discoverability is automatically turned off.
*/
-final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
+final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClickListener {
private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT =
"debug.bt.discoverable_time";
@@ -44,6 +44,10 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
private static final int DISCOVERABLE_TIMEOUT_ONE_HOUR = 3600;
static final int DISCOVERABLE_TIMEOUT_NEVER = 0;
+ // Bluetooth advanced settings screen was replaced with action bar items.
+ // Use the same preference key for discoverable timeout as the old ListPreference.
+ private static final String KEY_DISCOVERABLE_TIMEOUT = "bt_discoverable_timeout";
+
private static final String VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES = "twomin";
private static final String VALUE_DISCOVERABLE_TIMEOUT_FIVE_MINUTES = "fivemin";
private static final String VALUE_DISCOVERABLE_TIMEOUT_ONE_HOUR = "onehour";
@@ -53,11 +57,17 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
private final Context mContext;
private final Handler mUiHandler;
- private final CheckBoxPreference mCheckBoxPreference;
- private final ListPreference mTimeoutListPreference;
+ private final Preference mDiscoveryPreference;
private final LocalBluetoothAdapter mLocalAdapter;
+ private final SharedPreferences mSharedPreferences;
+
+ private boolean mDiscoverable;
+ private int mNumberOfPairedDevices;
+
+ private int mTimeoutSecs = -1;
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -78,21 +88,13 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
};
BluetoothDiscoverableEnabler(Context context, LocalBluetoothAdapter adapter,
- CheckBoxPreference checkBoxPreference, ListPreference timeoutListPreference) {
+ Preference discoveryPreference) {
mContext = context;
mUiHandler = new Handler();
- mCheckBoxPreference = checkBoxPreference;
- mTimeoutListPreference = timeoutListPreference;
-
- checkBoxPreference.setPersistent(false);
- // we actually want to persist this since can't infer from BT device state
- mTimeoutListPreference.setPersistent(true);
-
mLocalAdapter = adapter;
- if (adapter == null) {
- // Bluetooth not supported
- checkBoxPreference.setEnabled(false);
- }
+ mDiscoveryPreference = discoveryPreference;
+ mSharedPreferences = discoveryPreference.getSharedPreferences();
+ discoveryPreference.setPersistent(false);
}
public void resume() {
@@ -102,8 +104,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
mContext.registerReceiver(mReceiver, filter);
- mCheckBoxPreference.setOnPreferenceChangeListener(this);
- mTimeoutListPreference.setOnPreferenceChangeListener(this);
+ mDiscoveryPreference.setOnPreferenceClickListener(this);
handleModeChanged(mLocalAdapter.getScanMode());
}
@@ -113,20 +114,14 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
}
mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
- mCheckBoxPreference.setOnPreferenceChangeListener(null);
- mTimeoutListPreference.setOnPreferenceChangeListener(null);
mContext.unregisterReceiver(mReceiver);
+ mDiscoveryPreference.setOnPreferenceClickListener(null);
}
- public boolean onPreferenceChange(Preference preference, Object value) {
- if (preference == mCheckBoxPreference) {
- // Turn on/off BT discoverability
- setEnabled((Boolean) value);
- } else if (preference == mTimeoutListPreference) {
- mTimeoutListPreference.setValue((String) value);
- setEnabled(true);
- }
-
+ public boolean onPreferenceClick(Preference preference) {
+ // toggle discoverability
+ mDiscoverable = !mDiscoverable;
+ setEnabled(mDiscoverable);
return true;
}
@@ -138,9 +133,8 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
long endTimestamp = System.currentTimeMillis() + timeout * 1000L;
LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);
- updateCountdownSummary();
-
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
+ updateCountdownSummary();
} else {
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
}
@@ -148,22 +142,51 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
private void updateTimerDisplay(int timeout) {
if (getDiscoverableTimeout() == DISCOVERABLE_TIMEOUT_NEVER) {
- mCheckBoxPreference.setSummaryOn(
- mContext.getString(R.string.bluetooth_is_discoverable_always));
+ mDiscoveryPreference.setSummary(R.string.bluetooth_is_discoverable_always);
} else {
- mCheckBoxPreference.setSummaryOn(
- mContext.getString(R.string.bluetooth_is_discoverable, timeout));
+ String textTimeout = DateUtils.formatElapsedTime(timeout);
+ mDiscoveryPreference.setSummary(mContext.getString(R.string.bluetooth_is_discoverable,
+ textTimeout));
}
}
+ void setDiscoverableTimeout(int index) {
+ String timeoutValue;
+ switch (index) {
+ case 0:
+ default:
+ mTimeoutSecs = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
+ timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES;
+ break;
+
+ case 1:
+ mTimeoutSecs = DISCOVERABLE_TIMEOUT_FIVE_MINUTES;
+ timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_FIVE_MINUTES;
+ break;
+
+ case 2:
+ mTimeoutSecs = DISCOVERABLE_TIMEOUT_ONE_HOUR;
+ timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_ONE_HOUR;
+ break;
+
+ case 3:
+ mTimeoutSecs = DISCOVERABLE_TIMEOUT_NEVER;
+ timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_NEVER;
+ break;
+ }
+ mSharedPreferences.edit().putString(KEY_DISCOVERABLE_TIMEOUT, timeoutValue).apply();
+ setEnabled(true); // enable discovery and reset timer
+ }
+
private int getDiscoverableTimeout() {
+ if (mTimeoutSecs != -1) {
+ return mTimeoutSecs;
+ }
+
int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1);
if (timeout < 0) {
- String timeoutValue = mTimeoutListPreference.getValue();
- if (timeoutValue == null) {
- mTimeoutListPreference.setValue(VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
- return DISCOVERABLE_TIMEOUT_TWO_MINUTES;
- }
+ String timeoutValue = mSharedPreferences.getString(KEY_DISCOVERABLE_TIMEOUT,
+ VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
if (timeoutValue.equals(VALUE_DISCOVERABLE_TIMEOUT_NEVER)) {
timeout = DISCOVERABLE_TIMEOUT_NEVER;
@@ -175,16 +198,48 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
timeout = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
}
}
-
+ mTimeoutSecs = timeout;
return timeout;
}
- private void handleModeChanged(int mode) {
+ int getDiscoverableTimeoutIndex() {
+ int timeout = getDiscoverableTimeout();
+ switch (timeout) {
+ case DISCOVERABLE_TIMEOUT_TWO_MINUTES:
+ default:
+ return 0;
+
+ case DISCOVERABLE_TIMEOUT_FIVE_MINUTES:
+ return 1;
+
+ case DISCOVERABLE_TIMEOUT_ONE_HOUR:
+ return 2;
+
+ case DISCOVERABLE_TIMEOUT_NEVER:
+ return 3;
+ }
+ }
+
+ void setNumberOfPairedDevices(int pairedDevices) {
+ mNumberOfPairedDevices = pairedDevices;
+ setSummaryNotDiscoverable();
+ }
+
+ void handleModeChanged(int mode) {
if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- mCheckBoxPreference.setChecked(true);
+ mDiscoverable = true;
updateCountdownSummary();
} else {
- mCheckBoxPreference.setChecked(false);
+ mDiscoverable = false;
+ setSummaryNotDiscoverable();
+ }
+ }
+
+ private void setSummaryNotDiscoverable() {
+ if (mNumberOfPairedDevices != 0) {
+ mDiscoveryPreference.setSummary(R.string.bluetooth_only_visible_to_paired_devices);
+ } else {
+ mDiscoveryPreference.setSummary(R.string.bluetooth_not_visible_to_other_devices);
}
}
@@ -199,7 +254,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
if (currentTimestamp > endTimestamp) {
// We're still in discoverable mode, but maybe there isn't a timeout.
- mCheckBoxPreference.setSummaryOn(null);
+ updateTimerDisplay(0);
return;
}
diff --git a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
new file mode 100644
index 0000000..c00aff3
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 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.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.android.settings.R;
+
+/**
+ * Dialog fragment for renaming the local Bluetooth device.
+ */
+final class BluetoothNameDialogFragment extends DialogFragment implements TextWatcher {
+ private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
+
+ private AlertDialog mAlertDialog;
+ private Button mOkButton;
+
+ // accessed from inner class (not private to avoid thunks)
+ static final String TAG = "BluetoothNameDialogFragment";
+ final LocalBluetoothAdapter mLocalAdapter;
+ EditText mDeviceNameView;
+
+ // This flag is set when the name is updated by code, to distinguish from user changes
+ private boolean mDeviceNameUpdated;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
+ updateDeviceName();
+ } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
+ (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
+ BluetoothAdapter.STATE_ON)) {
+ updateDeviceName();
+ }
+ }
+ };
+
+ public BluetoothNameDialogFragment(LocalBluetoothAdapter adapter) {
+ mLocalAdapter = adapter;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ mAlertDialog = new AlertDialog.Builder(getActivity())
+ .setIcon(android.R.drawable.ic_dialog_info)
+ .setTitle(R.string.bluetooth_rename_device)
+ .setView(createDialogView())
+ .setPositiveButton(R.string.bluetooth_rename_button,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (mLocalAdapter != null) {
+ String deviceName = mDeviceNameView.getText().toString();
+ Log.d(TAG, "Setting device name to " + deviceName);
+ mLocalAdapter.setName(deviceName);
+ }
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, null)
+ .create();
+
+ return mAlertDialog;
+ }
+
+ private View createDialogView() {
+ final LayoutInflater layoutInflater = (LayoutInflater)getActivity()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view = layoutInflater.inflate(R.layout.dialog_edittext, null);
+ mDeviceNameView = (EditText) view.findViewById(R.id.edittext);
+ mDeviceNameView.setFilters(new InputFilter[] {
+ new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
+ });
+ mDeviceNameView.addTextChangedListener(this);
+ return view;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mAlertDialog = null;
+ mDeviceNameView = null;
+ mOkButton = null;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (mOkButton == null) {
+ mOkButton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ mOkButton.setEnabled(false); // Ok button is enabled when the user edits the name
+ }
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+ getActivity().registerReceiver(mReceiver, filter);
+ updateDeviceName();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ getActivity().unregisterReceiver(mReceiver);
+ }
+
+ void updateDeviceName() {
+ if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
+ mDeviceNameUpdated = true;
+ mDeviceNameView.setText(mLocalAdapter.getName());
+ }
+ }
+
+ public void afterTextChanged(Editable s) {
+ if (mDeviceNameUpdated) {
+ // Device name changed by code; disable Ok button until edited by user
+ mDeviceNameUpdated = false;
+ mOkButton.setEnabled(false);
+ } else {
+ mOkButton.setEnabled(s.length() != 0);
+ }
+ }
+
+ /* Not used */
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ /* Not used */
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
deleted file mode 100644
index f41689e..0000000
--- a/src/com/android/settings/bluetooth/BluetoothNamePreference.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 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.app.AlertDialog;
-import android.app.Dialog;
-
-import android.bluetooth.BluetoothAdapter;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.preference.EditTextPreference;
-import android.text.Editable;
-import android.text.InputFilter;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.widget.Button;
-import android.widget.EditText;
-
-/**
- * BluetoothNamePreference is the preference type for editing the device's
- * Bluetooth name. It asks the user for a name, and persists it via the
- * Bluetooth API.
- */
-public final class BluetoothNamePreference extends EditTextPreference implements TextWatcher {
-// private static final String TAG = "BluetoothNamePreference";
- private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
-
- private final LocalBluetoothAdapter mLocalAdapter;
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
- setSummaryToName();
- } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
- (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
- BluetoothAdapter.STATE_ON)) {
- setSummaryToName();
- }
- }
- };
-
- public BluetoothNamePreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mLocalAdapter = LocalBluetoothManager.getInstance(context).getBluetoothAdapter();
-
- setSummaryToName();
- }
-
- public void resume() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
- getContext().registerReceiver(mReceiver, filter);
-
- // Make sure the OK button is disabled (if necessary) after rotation
- EditText et = getEditText();
- if (et != null) {
- et.setFilters(new InputFilter[] {
- new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
- });
-
- et.addTextChangedListener(this);
- Dialog d = getDialog();
- if (d instanceof AlertDialog) {
- Button b = ((AlertDialog) d).getButton(AlertDialog.BUTTON_POSITIVE);
- b.setEnabled(et.getText().length() > 0);
- }
- }
- }
-
- public void pause() {
- EditText et = getEditText();
- if (et != null) {
- et.removeTextChangedListener(this);
- }
- getContext().unregisterReceiver(mReceiver);
- }
-
- private void setSummaryToName() {
- if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
- setSummary(mLocalAdapter.getName());
- }
- }
-
- @Override
- protected boolean persistString(String value) {
- // Persist with Bluez instead of shared preferences
- if (mLocalAdapter != null) {
- mLocalAdapter.setName(value);
- }
- return true;
- }
-
- @Override
- protected void onClick() {
- super.onClick();
-
- // The dialog should be created by now
- EditText et = getEditText();
- if (et != null && mLocalAdapter != null) {
- et.setText(mLocalAdapter.getName());
- }
- }
-
- // TextWatcher interface
- public void afterTextChanged(Editable s) {
- Dialog d = getDialog();
- if (d instanceof AlertDialog) {
- ((AlertDialog) d).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(s.length() > 0);
- }
- }
-
- // TextWatcher interface
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // not used
- }
-
- // TextWatcher interface
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // not used
- }
-
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
index 1b443c4..1ec8ff2 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
@@ -24,13 +24,17 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Editable;
+import android.text.Html;
import android.text.InputFilter;
import android.text.InputType;
+import android.text.Spanned;
import android.text.TextWatcher;
import android.text.InputFilter.LengthFilter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
@@ -42,8 +46,8 @@ import com.android.settings.R;
* BluetoothPairingDialog asks the user to enter a PIN / Passkey / simple confirmation
* for pairing with a remote Bluetooth device. It is an activity that appears as a dialog.
*/
-public final class BluetoothPairingDialog extends AlertActivity implements DialogInterface.OnClickListener,
- TextWatcher {
+public final class BluetoothPairingDialog extends AlertActivity implements
+ CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener, TextWatcher {
private static final String TAG = "BluetoothPairingDialog";
private static final int BLUETOOTH_PIN_MAX_LENGTH = 16;
@@ -156,7 +160,7 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
final AlertController.AlertParams p = mAlertParams;
p.mIconId = android.R.drawable.ic_dialog_info;
p.mTitle = getString(R.string.bluetooth_pairing_request);
- p.mView = createView(deviceManager);
+ p.mView = createPinEntryView(deviceManager.getName(mDevice));
p.mPositiveButtonText = getString(android.R.string.ok);
p.mPositiveButtonListener = this;
p.mNegativeButtonText = getString(android.R.string.cancel);
@@ -167,56 +171,78 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
mOkButton.setEnabled(false);
}
- private View createView(CachedBluetoothDeviceManager deviceManager) {
+ private View createPinEntryView(String deviceName) {
View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
- String name = deviceManager.getName(mDevice);
TextView messageView = (TextView) view.findViewById(R.id.message);
+ TextView messageView2 = (TextView) view.findViewById(R.id.message_below_pin);
+ CheckBox alphanumericPin = (CheckBox) view.findViewById(R.id.alphanumeric_pin);
mPairingView = (EditText) view.findViewById(R.id.text);
mPairingView.addTextChangedListener(this);
+ alphanumericPin.setOnCheckedChangeListener(this);
+ int messageId1;
+ int messageId2;
+ int maxLength;
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN:
- messageView.setText(getString(R.string.bluetooth_enter_pin_msg, name));
- // Maximum of 16 characters in a PIN adb sync
- mPairingView.setFilters(new InputFilter[] {
- new LengthFilter(BLUETOOTH_PIN_MAX_LENGTH) });
+ messageId1 = R.string.bluetooth_enter_pin_msg;
+ messageId2 = R.string.bluetooth_enter_pin_other_device;
+ // Maximum of 16 characters in a PIN
+ maxLength = BLUETOOTH_PIN_MAX_LENGTH;
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
- messageView.setText(getString(R.string.bluetooth_enter_passkey_msg, name));
+ messageId1 = R.string.bluetooth_enter_passkey_msg;
+ messageId2 = R.string.bluetooth_enter_passkey_other_device;
// Maximum of 6 digits for passkey
- mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER |
- InputType.TYPE_NUMBER_FLAG_SIGNED);
- mPairingView.setFilters(new InputFilter[] {
- new LengthFilter(BLUETOOTH_PASSKEY_MAX_LENGTH)});
+ maxLength = BLUETOOTH_PASSKEY_MAX_LENGTH;
+ alphanumericPin.setVisibility(View.GONE);
break;
+ default:
+ Log.e(TAG, "Incorrect pairing type for createPinEntryView: " + mType);
+ return null;
+ }
+
+ // Format the message string, then parse HTML style tags
+ String messageText = getString(messageId1, deviceName);
+ messageView.setText(Html.fromHtml(messageText));
+ messageView2.setText(messageId2);
+ mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
+ mPairingView.setFilters(new InputFilter[] {
+ new LengthFilter(maxLength) });
+
+ return view;
+ }
+
+ private View createView(CachedBluetoothDeviceManager deviceManager) {
+ View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_confirm, null);
+ String name = deviceManager.getName(mDevice);
+ TextView messageView = (TextView) view.findViewById(R.id.message);
+
+ String messageText; // formatted string containing HTML style tags
+ switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
- mPairingView.setVisibility(View.GONE);
- messageView.setText(getString(R.string.bluetooth_confirm_passkey_msg, name,
- mPairingKey));
+ messageText = getString(R.string.bluetooth_confirm_passkey_msg,
+ name, mPairingKey);
break;
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
- mPairingView.setVisibility(View.GONE);
- messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
+ case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
+ messageText = getString(R.string.bluetooth_incoming_pairing_msg, name);
break;
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
- mPairingView.setVisibility(View.GONE);
- messageView.setText(getString(R.string.bluetooth_display_passkey_pin_msg, name,
- mPairingKey));
- break;
-
- case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
- mPairingView.setVisibility(View.GONE);
- messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
+ messageText = getString(R.string.bluetooth_display_passkey_pin_msg, name,
+ mPairingKey);
break;
default:
Log.e(TAG, "Incorrect pairing type received, not creating view");
+ return null;
}
+ messageView.setText(Html.fromHtml(messageText));
return view;
}
@@ -317,7 +343,11 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case BUTTON_POSITIVE:
- onPair(mPairingView.getText().toString());
+ if (mPairingView != null) {
+ onPair(mPairingView.getText().toString());
+ } else {
+ onPair(null);
+ }
break;
case BUTTON_NEGATIVE:
@@ -335,4 +365,12 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ // change input type for soft keyboard to numeric or alphanumeric
+ if (isChecked) {
+ mPairingView.setInputType(InputType.TYPE_CLASS_TEXT);
+ } else {
+ mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
+ }
+ }
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 2208223..ede218d 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -20,6 +20,10 @@ import android.app.ActionBar;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
@@ -48,16 +52,48 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
private static final String TAG = "BluetoothSettings";
private static final int MENU_ID_SCAN = Menu.FIRST;
- private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
+ 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 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 BluetoothDiscoverableEnabler mDiscoverableEnabler;
+
+ private PreferenceGroup mPairedDevicesCategory;
+
private PreferenceGroup mAvailableDevicesCategory;
private boolean mAvailableDevicesCategoryIsPresent;
private View mView;
private TextView mEmptyView;
+ // accessed from inner class (not private to avoid thunks)
+ Preference mMyDevicePreference;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED) ||
+ (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
+ (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+ BluetoothAdapter.ERROR) == BluetoothAdapter.STATE_ON))) {
+ updateDeviceName();
+ }
+ }
+
+ private void updateDeviceName() {
+ if (mLocalAdapter != null && mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
+ mMyDevicePreference.setTitle(mLocalAdapter.getName());
+ }
+ }
+ };
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -106,15 +142,26 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
super.onResume();
mBluetoothEnabler.resume();
-
updateContent(mLocalAdapter.getBluetoothState());
+
+ if (mDiscoverableEnabler != null) {
+ mDiscoverableEnabler.resume();
+ }
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+ getActivity().registerReceiver(mReceiver, filter);
}
@Override
public void onPause() {
super.onPause();
-
mBluetoothEnabler.pause();
+ getActivity().unregisterReceiver(mReceiver);
+ if (mDiscoverableEnabler != null) {
+ mDiscoverableEnabler.pause();
+ }
}
@Override
@@ -124,12 +171,14 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
int textId = isDiscovering ? R.string.bluetooth_searching_for_devices :
R.string.bluetooth_search_for_devices;
menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
- //.setIcon(R.drawable.ic_menu_scan_network)
.setEnabled(bluetoothIsEnabled && !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)
+ menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ menu.add(Menu.NONE, MENU_ID_VISIBILITY_TIMEOUT, 0, R.string.bluetooth_visibility_timeout)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
@Override
@@ -140,16 +189,20 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
startScanning();
}
return true;
- case MENU_ID_ADVANCED:
- if (getActivity() instanceof PreferenceActivity) {
- ((PreferenceActivity) getActivity()).startPreferencePanel(
- AdvancedBluetoothSettings.class.getCanonicalName(),
- null,
- R.string.bluetooth_advanced_titlebar, null,
- this, 0);
- } else {
- startFragment(this, AdvancedBluetoothSettings.class.getCanonicalName(), -1, null);
- }
+
+ case MENU_ID_RENAME_DEVICE:
+ new BluetoothNameDialogFragment(mLocalAdapter).show(
+ getFragmentManager(), "rename device");
+ return true;
+
+ case MENU_ID_VISIBILITY_TIMEOUT:
+ new BluetoothVisibilityTimeoutFragment(mDiscoverableEnabler).show(
+ getFragmentManager(), "visibility timeout");
+ return true;
+
+ case MENU_ID_SHOW_RECEIVED:
+ Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
+ getActivity().sendBroadcast(intent);
return true;
}
return super.onOptionsItemSelected(item);
@@ -195,9 +248,15 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
if (mLocalAdapter != null) {
mMyDevicePreference.setTitle(mLocalAdapter.getName());
}
+ mMyDevicePreference.setPersistent(false);
mMyDevicePreference.setEnabled(true);
preferenceScreen.addPreference(mMyDevicePreference);
+ if (mDiscoverableEnabler == null) {
+ mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
+ mLocalAdapter, mMyDevicePreference);
+ }
+
// Paired devices category
if (mPairedDevicesCategory == null) {
mPairedDevicesCategory = new PreferenceCategory(getActivity());
@@ -209,6 +268,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
+ mDiscoverableEnabler.setNumberOfPairedDevices(numberOfPairedDevices);
+
// Available devices category
if (mAvailableDevicesCategory == null) {
mAvailableDevicesCategory = new ProgressCategory(getActivity(), null);
@@ -291,10 +352,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
}
};
- private Preference mMyDevicePreference;
-
- private PreferenceGroup mPairedDevicesCategory;
-
/**
* Add a listener, which enables the advanced settings icon.
* @param preference the newly added preference
diff --git a/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java b/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
new file mode 100644
index 0000000..dbdb052
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 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.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.android.internal.app.AlertController;
+import com.android.settings.R;
+
+/**
+ * Dialog fragment for setting the discoverability timeout.
+ */
+final class BluetoothVisibilityTimeoutFragment extends DialogFragment
+ implements DialogInterface.OnClickListener {
+
+ private final BluetoothDiscoverableEnabler mDiscoverableEnabler;
+
+ public BluetoothVisibilityTimeoutFragment(BluetoothDiscoverableEnabler enabler) {
+ mDiscoverableEnabler = enabler;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setIcon(android.R.drawable.ic_dialog_info)
+ .setTitle(R.string.bluetooth_visibility_timeout)
+ .setSingleChoiceItems(R.array.bluetooth_visibility_timeout_entries,
+ mDiscoverableEnabler.getDiscoverableTimeoutIndex(), this)
+ .setNegativeButton(android.R.string.cancel, null)
+ .create();
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ mDiscoverableEnabler.setDiscoverableTimeout(which);
+ dismiss();
+ }
+}
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 71a5c01..846c379 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -257,6 +257,14 @@ final class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
return true;
}
+ /**
+ * Return true if user initiated pairing on this device. The message text is
+ * slightly different for local vs. remote initiated pairing dialogs.
+ */
+ boolean isUserInitiatedPairing() {
+ return mConnectAfterPairing;
+ }
+
void unpair() {
disconnect();