diff options
author | Danica Chang <danicachang@google.com> | 2010-08-18 16:58:52 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-08-18 16:58:52 -0700 |
commit | 3a9cf0363618bfadeaa5df2460fa615922bd8c75 (patch) | |
tree | f72180265f4b2e72adeec5dccd2f6fe836aa037f /src | |
parent | b08adb00329e352f5f60050abe7a0f4f0fdc214b (diff) | |
parent | 32711b6752eb73324e1b10db975ac956888eda96 (diff) | |
download | packages_apps_settings-3a9cf0363618bfadeaa5df2460fa615922bd8c75.zip packages_apps_settings-3a9cf0363618bfadeaa5df2460fa615922bd8c75.tar.gz packages_apps_settings-3a9cf0363618bfadeaa5df2460fa615922bd8c75.tar.bz2 |
Merge "bluetooth tethering"
Diffstat (limited to 'src')
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; + } + } } |