summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorDanica Chang <danicachang@google.com>2010-08-10 18:41:29 -0700
committerDanica Chang <danicachang@google.com>2010-08-17 19:07:07 -0700
commit32711b6752eb73324e1b10db975ac956888eda96 (patch)
treef72180265f4b2e72adeec5dccd2f6fe836aa037f /src/com/android
parent4216902ba3752ccaf6a3ff50f911c0f69b07e4b2 (diff)
downloadpackages_apps_Settings-32711b6752eb73324e1b10db975ac956888eda96.zip
packages_apps_Settings-32711b6752eb73324e1b10db975ac956888eda96.tar.gz
packages_apps_Settings-32711b6752eb73324e1b10db975ac956888eda96.tar.bz2
bluetooth tethering
Change-Id: I8dfb1c85bb8b963d2937b8bc4a4c9f0cf641785d
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/settings/TetherSettings.java189
-rw-r--r--src/com/android/settings/WirelessSettings.java40
-rw-r--r--src/com/android/settings/bluetooth/BluetoothDevicePreference.java7
-rw-r--r--src/com/android/settings/bluetooth/BluetoothEventRedirector.java14
-rw-r--r--src/com/android/settings/bluetooth/BluetoothSettings.java110
-rw-r--r--src/com/android/settings/bluetooth/CachedBluetoothDevice.java54
-rw-r--r--src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java3
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java95
8 files changed, 455 insertions, 57 deletions
diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
index 22377ab..67049ff 100644
--- a/src/com/android/settings/TetherSettings.java
+++ b/src/com/android/settings/TetherSettings.java
@@ -20,7 +20,13 @@ import com.android.settings.wifi.WifiApEnabler;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.IBluetooth;
import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -32,6 +38,7 @@ import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
+import android.util.Log;
import android.webkit.WebView;
import java.io.InputStream;
@@ -42,9 +49,13 @@ import java.util.Locale;
* Displays preferences for Tethering.
*/
public class TetherSettings extends PreferenceActivity {
+ private static final String TAG = "TetheringSettings";
+
private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
private static final String WIFI_AP_SETTINGS = "wifi_ap_settings";
+ private static final String ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
+ private static final String BLUETOOTH_TETHER_SETTINGS = "bluetooth_tether_settings";
private static final String TETHERING_HELP = "tethering_help";
private static final String USB_HELP_MODIFIER = "usb_";
private static final String WIFI_HELP_MODIFIER = "wifi_";
@@ -59,6 +70,10 @@ public class TetherSettings extends PreferenceActivity {
private CheckBoxPreference mEnableWifiAp;
private PreferenceScreen mWifiApSettings;
private WifiApEnabler mWifiApEnabler;
+
+ private CheckBoxPreference mBluetoothTether;
+ private PreferenceScreen mBluetoothSettings;
+
private PreferenceScreen mTetherHelp;
private BroadcastReceiver mTetherChangeReceiver;
@@ -67,36 +82,68 @@ public class TetherSettings extends PreferenceActivity {
private String[] mWifiRegexs;
+ private String[] mBluetoothRegexs;
+ private BluetoothPan mBluetoothPan;
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ mBluetoothPan = new BluetoothPan(this);
addPreferencesFromResource(R.xml.tether_prefs);
mEnableWifiAp = (CheckBoxPreference) findPreference(ENABLE_WIFI_AP);
mWifiApSettings = (PreferenceScreen) findPreference(WIFI_AP_SETTINGS);
mUsbTether = (CheckBoxPreference) findPreference(USB_TETHER_SETTINGS);
+ mBluetoothTether = (CheckBoxPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
+ mBluetoothSettings = (PreferenceScreen) findPreference(BLUETOOTH_TETHER_SETTINGS);
mTetherHelp = (PreferenceScreen) findPreference(TETHERING_HELP);
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
mUsbRegexs = cm.getTetherableUsbRegexs();
- if (mUsbRegexs.length == 0 || Utils.isMonkeyRunning()) {
- getPreferenceScreen().removePreference(mUsbTether);
+ mWifiRegexs = cm.getTetherableWifiRegexs();
+ mBluetoothRegexs = cm.getTetherableBluetoothRegexs();
- setTitle(R.string.tether_settings_title_wifi);
- }
+ boolean usbAvailable = mUsbRegexs.length != 0;
+ boolean wifiAvailable = mWifiRegexs.length != 0;
+ boolean bluetoothAvailable = mBluetoothRegexs.length != 0;
- mWifiRegexs = cm.getTetherableWifiRegexs();
- if (mWifiRegexs.length == 0) {
+
+ if (!usbAvailable || Utils.isMonkeyRunning()) {
+ getPreferenceScreen().removePreference(mUsbTether);
+ }
+ if (!wifiAvailable) {
getPreferenceScreen().removePreference(mEnableWifiAp);
getPreferenceScreen().removePreference(mWifiApSettings);
-
+ }
+ if (!bluetoothAvailable) {
+ getPreferenceScreen().removePreference(mBluetoothTether);
+ getPreferenceScreen().removePreference(mBluetoothSettings);
+ } else {
+ if (mBluetoothPan.isTetheringOn()) {
+ mBluetoothTether.setChecked(true);
+ mBluetoothSettings.setEnabled(true);
+ } else {
+ mBluetoothTether.setChecked(false);
+ mBluetoothSettings.setEnabled(false);
+ }
+ }
+ if (wifiAvailable && usbAvailable && bluetoothAvailable){
+ setTitle(R.string.tether_settings_title_all);
+ } else if (wifiAvailable && usbAvailable){
+ setTitle(R.string.tether_settings_title_all);
+ } else if (wifiAvailable && bluetoothAvailable){
+ setTitle(R.string.tether_settings_title_all);
+ } else if (wifiAvailable) {
+ setTitle(R.string.tether_settings_title_wifi);
+ } else if (usbAvailable && bluetoothAvailable) {
+ setTitle(R.string.tether_settings_title_usb_bluetooth);
+ } else if (usbAvailable) {
setTitle(R.string.tether_settings_title_usb);
- } else if (mUsbRegexs.length != 0) {
- // have both
- setTitle(R.string.tether_settings_title_both);
+ } else {
+ setTitle(R.string.tether_settings_title_bluetooth);
}
mWifiApEnabler = new WifiApEnabler(this, mEnableWifiAp);
mView = new WebView(this);
@@ -148,6 +195,7 @@ public class TetherSettings extends PreferenceActivity {
}
private class TetherChangeReceiver extends BroadcastReceiver {
+ @Override
public void onReceive(Context content, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
// TODO - this should understand the interface types
@@ -157,11 +205,14 @@ public class TetherSettings extends PreferenceActivity {
ConnectivityManager.EXTRA_ACTIVE_TETHER);
ArrayList<String> errored = intent.getStringArrayListExtra(
ConnectivityManager.EXTRA_ERRORED_TETHER);
- updateState((String[]) available.toArray(), (String[]) active.toArray(),
- (String[]) errored.toArray());
+ updateState(available.toArray(new String[available.size()]),
+ active.toArray(new String[active.size()]),
+ errored.toArray(new String[errored.size()]));
} else if (intent.getAction().equals(Intent.ACTION_MEDIA_SHARED) ||
intent.getAction().equals(Intent.ACTION_MEDIA_UNSHARED)) {
updateState();
+ } else if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+ updateState();
}
}
}
@@ -170,8 +221,8 @@ public class TetherSettings extends PreferenceActivity {
protected void onResume() {
super.onResume();
- IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
mTetherChangeReceiver = new TetherChangeReceiver();
+ IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
Intent intent = registerReceiver(mTetherChangeReceiver, filter);
filter = new IntentFilter();
@@ -180,6 +231,10 @@ public class TetherSettings extends PreferenceActivity {
filter.addDataScheme("file");
registerReceiver(mTetherChangeReceiver, filter);
+ filter = new IntentFilter();
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ registerReceiver(mTetherChangeReceiver, filter);
+
if (intent != null) mTetherChangeReceiver.onReceive(this, intent);
mWifiApEnabler.resume();
}
@@ -204,6 +259,13 @@ public class TetherSettings extends PreferenceActivity {
private void updateState(String[] available, String[] tethered,
String[] errored) {
+ updateUsbState(available, tethered, errored);
+ updateBluetoothState(available, tethered, errored);
+ }
+
+
+ private void updateUsbState(String[] available, String[] tethered,
+ String[] errored) {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
boolean usbTethered = false;
@@ -260,6 +322,66 @@ public class TetherSettings extends PreferenceActivity {
}
}
+ private void updateBluetoothState(String[] available, String[] tethered,
+ String[] errored) {
+ ConnectivityManager cm =
+ (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+ boolean bluetoothTethered = false;
+ boolean bluetoothAvailable = false;
+ int bluetoothError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
+ boolean bluetoothErrored = false;
+ for (String s : available) {
+ for (String regex : mBluetoothRegexs) {
+ if (s.matches(regex)) {
+ bluetoothAvailable = true;
+ if (bluetoothError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ bluetoothError = cm.getLastTetherError(s);
+ }
+ }
+ }
+ }
+ for (String s : tethered) {
+ for (String regex : mBluetoothRegexs) {
+ if (s.matches(regex)) bluetoothTethered = true;
+ }
+ }
+ for (String s: errored) {
+ for (String regex : mBluetoothRegexs) {
+ if (s.matches(regex)) bluetoothErrored = true;
+ }
+ }
+
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ int btState = adapter.getState();
+ if (btState == BluetoothAdapter.STATE_TURNING_OFF) {
+ mBluetoothTether.setEnabled(false);
+ mBluetoothSettings.setEnabled(false);
+ mBluetoothTether.setSummary(R.string.wifi_stopping);
+ } else if (btState == BluetoothAdapter.STATE_TURNING_ON) {
+ mBluetoothTether.setEnabled(false);
+ mBluetoothSettings.setEnabled(false);
+ mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
+ } else if (mBluetoothPan.isTetheringOn()) {
+ mBluetoothTether.setChecked(true);
+ if (btState == BluetoothAdapter.STATE_ON) {
+ mBluetoothTether.setEnabled(true);
+ mBluetoothSettings.setEnabled(true);
+ if (bluetoothTethered) {
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_connected_subtext);
+ } else if (bluetoothErrored) {
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
+ } else {
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
+ }
+ }
+ } else {
+ mBluetoothTether.setEnabled(true);
+ mBluetoothTether.setChecked(false);
+ mBluetoothSettings.setEnabled(false);
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
+ }
+ }
+
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference == mUsbTether) {
@@ -296,8 +418,47 @@ public class TetherSettings extends PreferenceActivity {
}
mUsbTether.setSummary("");
}
- } else if (preference == mTetherHelp) {
+ } else if(preference == mBluetoothTether) {
+ boolean bluetoothTetherState = mBluetoothTether.isChecked();
+
+ if (bluetoothTetherState) {
+ // turn on Bluetooth first
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
+ adapter.enable();
+ mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
+ mBluetoothTether.setEnabled(false);
+ mBluetoothSettings.setEnabled(false);
+ } else {
+ mBluetoothSettings.setEnabled(true);
+ }
+
+ mBluetoothPan.setBluetoothTethering(true,
+ BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
+ } else {
+ boolean errored = false;
+ ConnectivityManager cm =
+ (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+ String [] tethered = cm.getTetheredIfaces();
+ String bluetoothIface = findIface(tethered, mBluetoothRegexs);
+ if (bluetoothIface != null &&
+ cm.untether(bluetoothIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ errored = true;
+ }
+
+ mBluetoothPan.setBluetoothTethering(false,
+ BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
+
+ mBluetoothSettings.setEnabled(false);
+ if (errored) {
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
+ } else {
+ mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
+ }
+ }
+ } else if (preference == mTetherHelp) {
showDialog(DIALOG_TETHER_HELP);
}
return false;
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index 853fe85..60ae20d 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -133,18 +133,34 @@ public class WirelessSettings extends PreferenceActivity {
} else {
String[] usbRegexs = cm.getTetherableUsbRegexs();
String[] wifiRegexs = cm.getTetherableWifiRegexs();
+ String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();
+
+ boolean usbAvailable = usbRegexs.length != 0;
+ boolean wifiAvailable = wifiRegexs.length != 0;
+ boolean bluetoothAvailable = bluetoothRegexs.length != 0;
+
Preference p = findPreference(KEY_TETHER_SETTINGS);
- if (wifiRegexs.length == 0) {
+ if (wifiAvailable && usbAvailable && bluetoothAvailable) {
+ p.setTitle(R.string.tether_settings_title_all);
+ p.setSummary(R.string.tether_settings_summary_all);
+ } else if (wifiAvailable && usbAvailable) {
+ p.setTitle(R.string.tether_settings_title_all);
+ p.setSummary(R.string.tether_settings_summary_usb_wifi);
+ } else if (wifiAvailable && bluetoothAvailable) {
+ p.setTitle(R.string.tether_settings_title_all);
+ p.setSummary(R.string.tether_settings_summary_wifi_bluetooth);
+ } else if (wifiAvailable) {
+ p.setTitle(R.string.tether_settings_title_wifi);
+ p.setSummary(R.string.tether_settings_summary_wifi);
+ } else if (usbAvailable && bluetoothAvailable) {
+ p.setTitle(R.string.tether_settings_title_usb_bluetooth);
+ p.setSummary(R.string.tether_settings_summary_usb_bluetooth);
+ } else if (usbAvailable) {
p.setTitle(R.string.tether_settings_title_usb);
p.setSummary(R.string.tether_settings_summary_usb);
} else {
- if (usbRegexs.length == 0) {
- p.setTitle(R.string.tether_settings_title_wifi);
- p.setSummary(R.string.tether_settings_summary_wifi);
- } else {
- p.setTitle(R.string.tether_settings_title_both);
- p.setSummary(R.string.tether_settings_summary_both);
- }
+ p.setTitle(R.string.tether_settings_title_bluetooth);
+ p.setSummary(R.string.tether_settings_summary_bluetooth);
}
}
}
@@ -152,21 +168,21 @@ public class WirelessSettings extends PreferenceActivity {
@Override
protected void onResume() {
super.onResume();
-
+
mAirplaneModeEnabler.resume();
mWifiEnabler.resume();
mBtEnabler.resume();
}
-
+
@Override
protected void onPause() {
super.onPause();
-
+
mAirplaneModeEnabler.pause();
mWifiEnabler.pause();
mBtEnabler.pause();
}
-
+
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_EXIT_ECM) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 5b0218f..f0b1705 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -34,6 +34,7 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
private static int sDimAlpha = Integer.MIN_VALUE;
private CachedBluetoothDevice mCachedDevice;
+ private int mAccessibleProfile;
/**
* Cached local copy of whether the device is busy. This is only updated
@@ -41,7 +42,8 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
*/
private boolean mIsBusy;
- public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice) {
+ public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice,
+ int accessibleProfile) {
super(context);
if (sDimAlpha == Integer.MIN_VALUE) {
@@ -51,6 +53,7 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
}
mCachedDevice = cachedDevice;
+ mAccessibleProfile = accessibleProfile;
setLayoutResource(R.layout.preference_bluetooth);
@@ -83,7 +86,7 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
* related to BluetoothHeadset not bound to the actual
* BluetoothHeadsetService when we got here.
*/
- setSummary(mCachedDevice.getSummary());
+ setSummary(mCachedDevice.getSummary(mAccessibleProfile));
// Used to gray out the item
mIsBusy = mCachedDevice.isBusy();
diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
index dc8ab78..f3a404f 100644
--- a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
+++ b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
@@ -25,6 +25,7 @@ import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothInputDevice;
+import android.bluetooth.BluetoothPan;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -133,6 +134,18 @@ public class BluetoothEventRedirector {
mManager.getCachedDeviceManager().onProfileStateChanged(device,
Profile.HID, newState);
+ } else if (action.equals(BluetoothPan.ACTION_PAN_STATE_CHANGED)) {
+ final int newState = intent.getIntExtra(
+ BluetoothPan.EXTRA_PAN_STATE, 0);
+ final int oldState = intent.getIntExtra(
+ BluetoothPan.EXTRA_PREVIOUS_PAN_STATE, 0);
+ if (newState == BluetoothPan.STATE_DISCONNECTED &&
+ oldState == BluetoothPan.STATE_CONNECTING) {
+ Log.i(TAG, "Failed to connect BT PAN");
+ }
+ mManager.getCachedDeviceManager().onProfileStateChanged(device,
+ Profile.PAN, newState);
+
} else if (action.equals(BluetoothDevice.ACTION_CLASS_CHANGED)) {
mManager.getCachedDeviceManager().onBtClassChanged(device);
@@ -180,6 +193,7 @@ public class BluetoothEventRedirector {
// Fine-grained state broadcasts
filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
+ filter.addAction(BluetoothPan.ACTION_PAN_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_CLASS_CHANGED);
filter.addAction(BluetoothDevice.ACTION_UUID);
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 1e73b2d..82caa46 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,22 +18,33 @@ package com.android.settings.bluetooth;
import com.android.settings.ProgressCategory;
import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevicePicker;
+import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothUuid;
+import android.bluetooth.IBluetooth;
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.os.IBinder;
import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
+import android.server.BluetoothService;
+import android.text.TextUtils;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
@@ -60,6 +71,10 @@ public class BluetoothSettings extends PreferenceActivity
private static final int SCREEN_TYPE_SETTINGS = 0;
private static final int SCREEN_TYPE_DEVICEPICKER = 1;
+ private static final int SCREEN_TYPE_TETHERING = 2;
+
+ public static final String ACTION_LAUNCH_TETHER_PICKER =
+ "com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
private int mScreenType;
private int mFilterType;
@@ -88,16 +103,19 @@ public class BluetoothSettings extends PreferenceActivity
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
onBluetoothStateChanged(mLocalManager.getBluetoothState());
- } else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
- && mScreenType == SCREEN_TYPE_DEVICEPICKER) {
+ } else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
int bondState = intent
.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
if (bondState == BluetoothDevice.BOND_BONDED) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.equals(mSelectedDevice)) {
- sendDevicePickedIntent(device);
- finish();
+ if (mScreenType == SCREEN_TYPE_DEVICEPICKER) {
+ sendDevicePickedIntent(device);
+ finish();
+ } else if (mScreenType == SCREEN_TYPE_TETHERING) {
+ onPanDevicePicked();
+ }
}
}
}
@@ -134,6 +152,12 @@ public class BluetoothSettings extends PreferenceActivity
setTitle(getString(R.string.device_picker));
addPreferencesFromResource(R.xml.device_picker);
+ } else if (action.equals(ACTION_LAUNCH_TETHER_PICKER)){
+ mScreenType = SCREEN_TYPE_TETHERING;
+ mFilterType = BluetoothDevicePicker.FILTER_TYPE_PANU;
+
+ setTitle(getString(R.string.device_picker));
+ addPreferencesFromResource(R.xml.device_picker);
} else {
addPreferencesFromResource(R.xml.bluetooth_settings);
@@ -239,6 +263,18 @@ public class BluetoothSettings extends PreferenceActivity
} else {
btPreference.getCachedDevice().onClicked();
}
+ } else if (mScreenType == SCREEN_TYPE_TETHERING){
+ CachedBluetoothDevice device = btPreference.getCachedDevice();
+
+ mSelectedDevice = device.getDevice();
+ mLocalManager.stopScanning();
+ mLocalManager.persistSelectedDeviceInPicker(mSelectedDevice.getAddress());
+ if ((device.getBondState() == BluetoothDevice.BOND_BONDED)) {
+ onPanDevicePicked();
+ // don't call finish so that users can see it connecting
+ } else {
+ btPreference.getCachedDevice().onClicked();
+ }
}
return true;
}
@@ -321,6 +357,19 @@ public class BluetoothSettings extends PreferenceActivity
if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) return true;
}
break;
+ case BluetoothDevicePicker.FILTER_TYPE_PANU:
+ if (uuids != null) {
+ if (BluetoothUuid.containsAnyUuid(uuids,
+ LocalBluetoothProfileManager.PANU_PROFILE_UUIDS)) return true;
+
+ }
+ break;
+ case BluetoothDevicePicker.FILTER_TYPE_NAP:
+ if (uuids != null) {
+ if (BluetoothUuid.containsAnyUuid(uuids,
+ LocalBluetoothProfileManager.NAP_PROFILE_UUIDS)) return true;
+ }
+ break;
default:
return true;
}
@@ -328,7 +377,14 @@ public class BluetoothSettings extends PreferenceActivity
}
private void createDevicePreference(CachedBluetoothDevice cachedDevice) {
- BluetoothDevicePreference preference = new BluetoothDevicePreference(this, cachedDevice);
+ BluetoothDevicePreference preference;
+ if (mScreenType == SCREEN_TYPE_TETHERING) {
+ preference = new BluetoothDevicePreference(
+ this, cachedDevice, CachedBluetoothDevice.PAN_PROFILE);
+ } else {
+ preference = new BluetoothDevicePreference(
+ this, cachedDevice, CachedBluetoothDevice.OTHER_PROFILES);
+ }
mDeviceList.addPreference(preference);
mDevicePreferenceMap.put(cachedDevice, preference);
}
@@ -354,12 +410,52 @@ public class BluetoothSettings extends PreferenceActivity
}
}
+ private void onPanDevicePicked() {
+ final LocalBluetoothProfileManager profileManager =
+ LocalBluetoothProfileManager.getProfileManager(mLocalManager, Profile.PAN);
+ int status = profileManager.getConnectionStatus(mSelectedDevice);
+ if (SettingsBtStatus.isConnectionStatusConnected(status)) {
+ String name = mSelectedDevice.getName();
+ if (TextUtils.isEmpty(name)) {
+ name = getString(R.string.bluetooth_device);
+ }
+ String message = getString(R.string.bluetooth_untether_blank, name);
+ DialogInterface.OnClickListener disconnectListener =
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ profileManager.disconnect(mSelectedDevice);
+ }
+ };
+ new AlertDialog.Builder(this)
+ .setTitle(name)
+ .setMessage(message)
+ .setPositiveButton(android.R.string.ok, disconnectListener)
+ .setNegativeButton(android.R.string.cancel, null)
+ .create()
+ .show();
+ } else if (status == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
+ if (profileManager.getConnectedDevices().size() >= BluetoothPan.MAX_CONNECTIONS) {
+ new AlertDialog.Builder(this)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setTitle(R.string.bluetooth_error_title)
+ .setMessage(getString(R.string.bluetooth_tethering_overflow_error,
+ BluetoothPan.MAX_CONNECTIONS))
+ .setNegativeButton(android.R.string.ok, null)
+ .create()
+ .show();
+ return;
+ }
+ profileManager.connect(mSelectedDevice);
+ }
+ }
+
private void sendDevicePickedIntent(BluetoothDevice device) {
Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
- if (mLaunchPackage != null && mLaunchClass != null) {
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ if (mScreenType == SCREEN_TYPE_DEVICEPICKER &&
+ mLaunchPackage != null && mLaunchClass != null) {
intent.setClassName(mLaunchPackage, mLaunchClass);
}
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
sendBroadcast(intent);
}
}
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index bdaffca..5f374a5 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -56,6 +56,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
+ public static final int PAN_PROFILE = 1;
+ public static final int OTHER_PROFILES = 2;
+
private final BluetoothDevice mDevice;
private String mName;
private short mRssi;
@@ -625,9 +628,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
}
- public int getSummary() {
+ public int getSummary(int accessibleProfile) {
// TODO: clean up
- int oneOffSummary = getOneOffSummary();
+ int oneOffSummary = getOneOffSummary(accessibleProfile);
if (oneOffSummary != 0) {
return oneOffSummary;
}
@@ -653,34 +656,43 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
*
* @return A one-off summary that is applicable for the current state, or 0.
*/
- private int getOneOffSummary() {
+ private int getOneOffSummary(int accessibleProfile) {
boolean isA2dpConnected = false;
boolean isHeadsetConnected = false;
boolean isHidConnected = false;
+ boolean isPanConnected = false;
boolean isConnecting = false;
- if (mProfiles.contains(Profile.A2DP)) {
- LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
- .getProfileManager(mLocalManager, Profile.A2DP);
- isConnecting = profileManager.getConnectionStatus(mDevice) ==
- SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
- isA2dpConnected = profileManager.isConnected(mDevice);
- }
+ if (accessibleProfile == OTHER_PROFILES) {
+ if (mProfiles.contains(Profile.A2DP)) {
+ LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+ .getProfileManager(mLocalManager, Profile.A2DP);
+ isConnecting = profileManager.getConnectionStatus(mDevice) ==
+ SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+ isA2dpConnected = profileManager.isConnected(mDevice);
+ }
- if (mProfiles.contains(Profile.HEADSET)) {
- LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
- .getProfileManager(mLocalManager, Profile.HEADSET);
- isConnecting |= profileManager.getConnectionStatus(mDevice) ==
- SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
- isHeadsetConnected = profileManager.isConnected(mDevice);
- }
+ if (mProfiles.contains(Profile.HEADSET)) {
+ LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+ .getProfileManager(mLocalManager, Profile.HEADSET);
+ isConnecting |= profileManager.getConnectionStatus(mDevice) ==
+ SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+ isHeadsetConnected = profileManager.isConnected(mDevice);
+ }
- if (mProfiles.contains(Profile.HID)) {
+ if (mProfiles.contains(Profile.HID)) {
+ LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+ .getProfileManager(mLocalManager, Profile.HID);
+ isConnecting |= profileManager.getConnectionStatus(mDevice) ==
+ SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+ isHidConnected = profileManager.isConnected(mDevice);
+ }
+ } else if (accessibleProfile == PAN_PROFILE && mProfiles.contains(Profile.PAN)) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
- .getProfileManager(mLocalManager, Profile.HID);
+ .getProfileManager(mLocalManager, Profile.PAN);
isConnecting |= profileManager.getConnectionStatus(mDevice) ==
SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
- isHidConnected = profileManager.isConnected(mDevice);
+ isPanConnected = profileManager.isConnected(mDevice);
}
if (isConnecting) {
@@ -695,6 +707,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
return R.string.bluetooth_summary_connected_to_headset;
} else if (isHidConnected) {
return R.string.bluetooth_summary_connected_to_hid;
+ } else if (isPanConnected) {
+ return R.string.bluetooth_summary_connected_to_pan;
} else {
return 0;
}
diff --git a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
index 62c6f79..ab769a7 100644
--- a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
+++ b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
@@ -232,7 +232,8 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
* If the device is online, show status. Otherwise, show a summary that
* describes what the checkbox does.
*/
- mOnlineModePreference.setSummary(mOnlineMode ? mCachedDevice.getSummary()
+ mOnlineModePreference.setSummary(mOnlineMode ?
+ mCachedDevice.getSummary(CachedBluetoothDevice.OTHER_PROFILES)
: R.string.bluetooth_device_advanced_online_mode_summary);
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index b09e144..6193a4e 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothInputDevice;
+import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothUuid;
import android.os.Handler;
import android.os.ParcelUuid;
@@ -60,6 +61,14 @@ public abstract class LocalBluetoothProfileManager {
BluetoothUuid.Hid
};
+ /* package */ static final ParcelUuid[] PANU_PROFILE_UUIDS = new ParcelUuid[] {
+ BluetoothUuid.PANU
+ };
+
+ /* package */ static final ParcelUuid[] NAP_PROFILE_UUIDS = new ParcelUuid[] {
+ BluetoothUuid.NAP
+ };
+
/**
* An interface for notifying BluetoothHeadset IPC clients when they have
* been connected to the BluetoothHeadset service.
@@ -105,6 +114,9 @@ public abstract class LocalBluetoothProfileManager {
profileManager = new HidProfileManager(localManager);
sProfileMap.put(Profile.HID, profileManager);
+
+ profileManager = new PanProfileManager(localManager);
+ sProfileMap.put(Profile.PAN, profileManager);
}
}
}
@@ -173,6 +185,10 @@ public abstract class LocalBluetoothProfileManager {
if (BluetoothUuid.containsAnyUuid(uuids, HID_PROFILE_UUIDS)) {
profiles.add(Profile.HID);
}
+
+ if (BluetoothUuid.containsAnyUuid(uuids, PANU_PROFILE_UUIDS)) {
+ profiles.add(Profile.PAN);
+ }
}
protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
@@ -208,7 +224,8 @@ public abstract class LocalBluetoothProfileManager {
HEADSET(R.string.bluetooth_profile_headset),
A2DP(R.string.bluetooth_profile_a2dp),
OPP(R.string.bluetooth_profile_opp),
- HID(R.string.bluetooth_profile_hid);
+ HID(R.string.bluetooth_profile_hid),
+ PAN(R.string.bluetooth_profile_pan);
public final int localizedString;
@@ -613,4 +630,80 @@ public abstract class LocalBluetoothProfileManager {
}
}
}
+
+ private static class PanProfileManager extends LocalBluetoothProfileManager {
+ private BluetoothPan mService;
+
+ public PanProfileManager(LocalBluetoothManager localManager) {
+ super(localManager);
+ mService = new BluetoothPan(localManager.getContext());
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device) {
+ return mService.connect(device);
+ }
+
+ @Override
+ public int convertState(int panState) {
+ switch (panState) {
+ case BluetoothPan.STATE_CONNECTED:
+ return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
+ case BluetoothPan.STATE_CONNECTING:
+ return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+ case BluetoothPan.STATE_DISCONNECTED:
+ return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
+ case BluetoothPan.STATE_DISCONNECTING:
+ return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING;
+ default:
+ return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
+ }
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device) {
+ return mService.disconnect(device);
+ }
+
+ @Override
+ public int getSummary(BluetoothDevice device) {
+ final int connectionStatus = getConnectionStatus(device);
+
+ if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
+ return R.string.bluetooth_pan_profile_summary_connected;
+ } else {
+ return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
+ }
+ }
+
+ @Override
+ public boolean isProfileReady() {
+ return true;
+ }
+
+ @Override
+ public Set<BluetoothDevice> getConnectedDevices() {
+ return mService.getConnectedDevices();
+ }
+
+ @Override
+ public int getConnectionStatus(BluetoothDevice device) {
+ return convertState(mService.getPanDeviceState(device));
+ }
+
+ @Override
+ public int getPreferred(BluetoothDevice device) {
+ return -1;
+ }
+
+ @Override
+ public boolean isPreferred(BluetoothDevice device) {
+ return false;
+ }
+
+ @Override
+ public void setPreferred(BluetoothDevice device, boolean preferred) {
+ return;
+ }
+ }
}