summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml4
-rw-r--r--res/values/strings.xml10
-rw-r--r--res/xml/device_picker.xml30
-rw-r--r--src/com/android/settings/bluetooth/BluetoothDevicePreference.java4
-rw-r--r--src/com/android/settings/bluetooth/BluetoothSettings.java144
-rw-r--r--src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java41
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java77
7 files changed, 276 insertions, 34 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2565914..9f6ac0e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -125,6 +125,10 @@
<category android:name="com.android.settings.SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
+ <intent-filter>
+ <action android:name="android.bluetooth.intent.action.DEVICE_PICKER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
</activity>
<activity android:name=".vpn.VpnSettings"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2382fe9..97015cb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -215,6 +215,8 @@
<!-- Notification message when a Bluetooth device wants to pair with us -->
<string name="bluetooth_notif_message">Select to pair with\u0020</string>
+ <!-- Strings for BluetoothDevicePicker -->
+ <string name="device_picker">Bluetooth device picker</string>
<!-- Do not translate. Used for diagnostic screens, precise translation is not necessary -->
<string name="bluetooth_scan_text">Empty button\u2026</string>
@@ -568,6 +570,8 @@
<string name="bluetooth_profile_a2dp">Media</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the headset or handsfree profile. -->
<string name="bluetooth_profile_headset">Phone</string>
+ <!-- Bluetooth settings. The user-visible string that is used whenever referring to the OPP profile. -->
+ <string name="bluetooth_profile_opp">Transfer</string>
<!-- Bluetooth settings. The summary string when a device is connected to the A2DP profile. -->
<string name="bluetooth_summary_connected_to_a2dp">Connected to media audio</string>
@@ -588,11 +592,17 @@
<string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
<!-- Bluetooth settings. Connection options screen. The summary for the headset checkbox preference when headset is connected. -->
<string name="bluetooth_headset_profile_summary_connected">Connected to phone audio</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the OPP checkbox preference when OPP is connected. -->
+ <string name="bluetooth_opp_profile_summary_connected">Connected to file transfer server</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the OPP checkbox preference when OPP is not connected. -->
+ <string name="bluetooth_opp_profile_summary_not_connected">Not connected to file transfer server</string>
<!-- Bluetooth settings. Connection options screen. The summary for the A2DP checkbox preference that describes how checking it will set the A2DP profile as preferred. -->
<string name="bluetooth_a2dp_profile_summary_use_for">Use for media audio</string>
<!-- Bluetooth settings. Connection options screen. The summary for the headset checkbox preference that describes how checking it will set the headset profile as preferred. -->
<string name="bluetooth_headset_profile_summary_use_for">Use for phone audio</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the OPP checkbox preference that describes how checking it will set the OPP profile as preferred. -->
+ <string name="bluetooth_opp_profile_summary_use_for">Use for file transfer</string>
<!-- Wi-Fi settings -->
<!-- Used in the 2nd-level settings screen to turn on Wi-Fi -->
diff --git a/res/xml/device_picker.xml b/res/xml/device_picker.xml
new file mode 100644
index 0000000..7dd5b68
--- /dev/null
+++ b/res/xml/device_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <Preference
+ android:key="bt_scan"
+ android:title="@string/bluetooth_preference_scan_title" />
+
+ <com.android.settings.ProgressCategory
+ android:key="bt_device_list"
+ android:title="@string/bluetooth_devices"
+ android:orderingFromXml="false" />
+
+</PreferenceScreen>
+
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index b4daa88..237e4ab 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -105,7 +105,9 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
@Override
protected void onBindView(View view) {
// Disable this view if the bluetooth enable/disable preference view is off
- setDependency("bt_checkbox");
+ if (null != findPreferenceInHierarchy("bt_checkbox")){
+ setDependency("bt_checkbox");
+ }
super.onBindView(view);
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 29b6f9e..0525ec7 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,12 +18,15 @@ package com.android.settings.bluetooth;
import com.android.settings.ProgressCategory;
import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import java.util.List;
import java.util.WeakHashMap;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothIntent;
+import android.bluetooth.BluetoothError;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -39,6 +42,7 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.util.Log;
/**
* BluetoothSettings is the Settings screen for Bluetooth configuration and
@@ -57,6 +61,15 @@ public class BluetoothSettings extends PreferenceActivity
private static final String KEY_BT_NAME = "bt_name";
private static final String KEY_BT_SCAN = "bt_scan";
+ private static final int SCREEN_TYPE_SETTINGS = 0;
+ private static final int SCREEN_TYPE_DEVICEPICKER = 1;
+
+ private int mScreenType;
+ private int mFilterType;
+ private boolean mNeedAuth;
+ private String mLaunchPackage;
+ private String mLaunchClass;
+
private LocalBluetoothManager mLocalManager;
private BluetoothEnabler mEnabler;
@@ -73,7 +86,19 @@ public class BluetoothSettings extends PreferenceActivity
@Override
public void onReceive(Context context, Intent intent) {
// TODO: put this in callback instead of receiving
- onBluetoothStateChanged(mLocalManager.getBluetoothState());
+
+ if (intent.getAction().equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
+ onBluetoothStateChanged(mLocalManager.getBluetoothState());
+ } else if (intent.getAction().equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)
+ && mScreenType == SCREEN_TYPE_DEVICEPICKER) {
+ int bondState = intent
+ .getIntExtra(BluetoothIntent.BOND_STATE, BluetoothError.ERROR);
+ if (bondState == BluetoothDevice.BOND_BONDED) {
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothIntent.DEVICE);
+ sendDevicePickedIntent(device);
+ finish();
+ }
+ }
}
};
@@ -84,17 +109,44 @@ public class BluetoothSettings extends PreferenceActivity
mLocalManager = LocalBluetoothManager.getInstance(this);
if (mLocalManager == null) finish();
- addPreferencesFromResource(R.xml.bluetooth_settings);
-
- mEnabler = new BluetoothEnabler(
- this,
- (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX));
-
- mDiscoverableEnabler = new BluetoothDiscoverableEnabler(
- this,
- (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE));
-
- mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
+ // Note:
+ // If an application wish to show the BT device list, it can send an
+ // intent to Settings application with below extra data:
+ // -DEVICE_PICKER_FILTER_TYPE: the type of BT devices that want to show.
+ // -DEVICE_PICKER_LAUNCH_PACKAGE: the package which the application belongs to.
+ // -DEVICE_PICKER_LAUNCH_CLASS: the class which will receive user's selected
+ // result from the BT list.
+ // -DEVICE_PICKER_NEED_AUTH: to show if bonding procedure needed.
+
+ mFilterType = BluetoothDevice.DEVICE_PICKER_FILTER_TYPE_ALL;
+ Intent intent = getIntent();
+ String action = intent.getAction();
+
+ if (action.equals(BluetoothIntent.DEVICE_PICKER_DEVICE_PICKER)) {
+ mScreenType = SCREEN_TYPE_DEVICEPICKER;
+ mNeedAuth = intent.getBooleanExtra(BluetoothIntent.DEVICE_PICKER_NEED_AUTH, false);
+ mFilterType = intent.getIntExtra(BluetoothIntent.DEVICE_PICKER_FILTER_TYPE,
+ BluetoothDevice.DEVICE_PICKER_FILTER_TYPE_ALL);
+ mLaunchPackage = intent.getStringExtra(BluetoothIntent.DEVICE_PICKER_LAUNCH_PACKAGE);
+ mLaunchClass = intent.getStringExtra(BluetoothIntent.DEVICE_PICKER_LAUNCH_CLASS);
+
+ setTitle(getString(R.string.device_picker));
+ addPreferencesFromResource(R.xml.device_picker);
+ } else {
+ addPreferencesFromResource(R.xml.bluetooth_settings);
+
+ mEnabler = new BluetoothEnabler(
+ this,
+ (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX));
+
+ mDiscoverableEnabler = new BluetoothDiscoverableEnabler(
+ this,
+ (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE));
+
+ mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
+
+ mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
+ }
mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
@@ -111,17 +163,21 @@ public class BluetoothSettings extends PreferenceActivity
mDeviceList.removeAll();
addDevices();
- mEnabler.resume();
- mDiscoverableEnabler.resume();
- mNamePreference.resume();
+ if (mScreenType == SCREEN_TYPE_SETTINGS) {
+ mEnabler.resume();
+ mDiscoverableEnabler.resume();
+ mNamePreference.resume();
+ }
+
mLocalManager.registerCallback(this);
mDeviceList.setProgress(mLocalManager.getBluetoothAdapter().isDiscovering());
mLocalManager.startScanning(false);
- registerReceiver(mReceiver,
- new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION));
-
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
+ intentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
+ registerReceiver(mReceiver, intentFilter);
mLocalManager.setForegroundActivity(this);
}
@@ -134,9 +190,11 @@ public class BluetoothSettings extends PreferenceActivity
unregisterReceiver(mReceiver);
mLocalManager.unregisterCallback(this);
- mNamePreference.pause();
- mDiscoverableEnabler.pause();
- mEnabler.pause();
+ if (mScreenType == SCREEN_TYPE_SETTINGS) {
+ mNamePreference.pause();
+ mDiscoverableEnabler.pause();
+ mEnabler.pause();
+ }
}
private void addDevices() {
@@ -184,8 +242,20 @@ public class BluetoothSettings extends PreferenceActivity
}
if (preference instanceof BluetoothDevicePreference) {
- BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
- btPreference.getCachedDevice().onClicked();
+ BluetoothDevicePreference btPreference = (BluetoothDevicePreference)preference;
+ if (mScreenType == SCREEN_TYPE_SETTINGS) {
+ btPreference.getCachedDevice().onClicked();
+ } else if (mScreenType == SCREEN_TYPE_DEVICEPICKER) {
+ CachedBluetoothDevice device = btPreference.getCachedDevice();
+
+ if ((device.getBondState() == BluetoothDevice.BOND_BONDED) || (mNeedAuth == false)) {
+ BluetoothDevice btAddress = btPreference.getCachedDevice().getDevice();
+ sendDevicePickedIntent(btAddress);
+ finish();
+ } else {
+ btPreference.getCachedDevice().onClicked();
+ }
+ }
return true;
}
@@ -195,6 +265,10 @@ public class BluetoothSettings extends PreferenceActivity
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
+ //For device picker, disable Context Menu
+ if (mScreenType != SCREEN_TYPE_SETTINGS) {
+ return;
+ }
CachedBluetoothDevice cachedDevice = getDeviceFromMenuInfo(menuInfo);
if (cachedDevice == null) return;
@@ -231,8 +305,19 @@ public class BluetoothSettings extends PreferenceActivity
throw new IllegalStateException("Got onDeviceAdded, but cachedDevice already exists");
}
- createDevicePreference(cachedDevice);
- }
+ List<Profile> profiles = cachedDevice.getProfiles();
+ if (mFilterType == BluetoothDevice.DEVICE_PICKER_FILTER_TYPE_TRANSFER){
+ if(profiles.contains(Profile.OPP)){
+ createDevicePreference(cachedDevice);
+ }
+ } else if (mFilterType == BluetoothDevice.DEVICE_PICKER_FILTER_TYPE_AUDIO) {
+ if((profiles.contains(Profile.A2DP)) || (profiles.contains(Profile.HEADSET))){
+ createDevicePreference(cachedDevice);
+ }
+ } else {
+ createDevicePreference(cachedDevice);
+ }
+ }
private void createDevicePreference(CachedBluetoothDevice cachedDevice) {
BluetoothDevicePreference preference = new BluetoothDevicePreference(this, cachedDevice);
@@ -260,4 +345,13 @@ public class BluetoothSettings extends PreferenceActivity
mDeviceList.setProgress(false);
}
}
+
+ private void sendDevicePickedIntent(BluetoothDevice device) {
+ Intent intent = new Intent(BluetoothIntent.DEVICE_PICKER_DEVICE_SELECTED);
+ if (mLaunchPackage != null && mLaunchClass != null) {
+ intent.setClassName(mLaunchPackage, mLaunchClass);
+ }
+ intent.putExtra(BluetoothIntent.DEVICE, device);
+ sendBroadcast(intent);
+ }
}
diff --git a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
index bfc3caf..4f14390 100644
--- a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
+++ b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
@@ -29,6 +29,8 @@ import android.preference.PreferenceGroup;
import android.text.TextUtils;
import android.util.Log;
+import java.util.List;
+
/**
* ConnectSpecificProfilesActivity presents the user with all of the profiles
* for a particular device, and allows him to choose which should be connected
@@ -43,7 +45,10 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
private static final String KEY_PROFILE_CONTAINER = "profile_container";
public static final String EXTRA_DEVICE = "device";
-
+
+ public static final String CLASS_NAME_OPP_PROFILE_MANAGER =
+ "com.android.settings.bluetooth.LocalBluetoothProfileManager$OppProfileManager";
+
private LocalBluetoothManager mManager;
private CachedBluetoothDevice mCachedDevice;
@@ -145,6 +150,19 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
pref.setPersistent(false);
pref.setOnPreferenceChangeListener(this);
+ LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+ .getProfileManager(mManager, profile);
+
+ /**
+ * Gray out checkbox while connecting and disconnecting or this is OPP
+ * profile
+ */
+ if (profileManager.getClass().getName().equals(CLASS_NAME_OPP_PROFILE_MANAGER)) {
+ pref.setEnabled(false);
+ } else {
+ pref.setEnabled(!mCachedDevice.isBusy());
+ }
+
refreshProfilePreference(pref, profile);
return pref;
@@ -221,6 +239,12 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
/* Gray out checkbox while connecting and disconnecting */
mOnlineModePreference.setEnabled(!mCachedDevice.isBusy());
+ List<Profile> profiles = mCachedDevice.getProfiles();
+ if ((profiles.size() == 1) && (profiles.get(0).name().equals("OPP"))) {
+ Log.w(TAG, "there is only one profile: Opp, disable the connect button.");
+ mOnlineModePreference.setEnabled(false);
+ }
+
/**
* If the device is online, show status. Otherwise, show a summary that
* describes what the checkbox does.
@@ -249,9 +273,16 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
int connectionStatus = profileManager.getConnectionStatus(device);
- /* Gray out checkbox while connecting and disconnecting */
- profilePref.setEnabled(!mCachedDevice.isBusy());
-
+ /*
+ * Gray out checkbox while connecting and disconnecting or this is OPP
+ * profile
+ */
+ if (profileManager.getClass().getName().equals(CLASS_NAME_OPP_PROFILE_MANAGER)) {
+ Log.w(TAG, "this is Opp profile");
+ profilePref.setEnabled(false);
+ } else {
+ profilePref.setEnabled(!mCachedDevice.isBusy());
+ }
profilePref.setSummary(getProfileSummary(profileManager, profile, device,
connectionStatus, mOnlineMode));
@@ -291,6 +322,8 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
return R.string.bluetooth_a2dp_profile_summary_use_for;
case HEADSET:
return R.string.bluetooth_headset_profile_summary_use_for;
+ case OPP:
+ return R.string.bluetooth_opp_profile_summary_use_for;
default:
return 0;
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index 49c2eea..2a52a8b 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -18,6 +18,7 @@ package com.android.settings.bluetooth;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothHeadset;
import android.os.Handler;
@@ -59,6 +60,10 @@ public abstract class LocalBluetoothProfileManager {
case HEADSET:
profileManager = new HeadsetProfileManager(localManager);
break;
+
+ case OPP:
+ profileManager = new OppProfileManager(localManager);
+ break;
}
sProfileMap.put(profile, profileManager);
@@ -80,13 +85,17 @@ public abstract class LocalBluetoothProfileManager {
public static void fill(int btClass, List<Profile> profiles) {
profiles.clear();
- if (BluetoothHeadset.doesClassMatch(btClass)) {
+ if (BluetoothClass.doesClassMatch(btClass, BluetoothClass.PROFILE_HEADSET)) {
profiles.add(Profile.HEADSET);
}
-
- if (BluetoothA2dp.doesClassMatchSink(btClass)) {
+
+ if (BluetoothClass.doesClassMatch(btClass, BluetoothClass.PROFILE_A2DP)) {
profiles.add(Profile.A2DP);
}
+
+ if (BluetoothClass.doesClassMatch(btClass, BluetoothClass.PROFILE_OPP)) {
+ profiles.add(Profile.OPP);
+ }
}
protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
@@ -114,7 +123,8 @@ public abstract class LocalBluetoothProfileManager {
// TODO: int instead of enum
public enum Profile {
HEADSET(R.string.bluetooth_profile_headset),
- A2DP(R.string.bluetooth_profile_a2dp);
+ A2DP(R.string.bluetooth_profile_a2dp),
+ OPP(R.string.bluetooth_profile_opp);
public final int localizedString;
@@ -291,4 +301,63 @@ public abstract class LocalBluetoothProfileManager {
}
}
}
+
+ /**
+ * OppProfileManager
+ */
+ private static class OppProfileManager extends LocalBluetoothProfileManager {
+
+ public OppProfileManager(LocalBluetoothManager localManager) {
+ super(localManager);
+ }
+
+ @Override
+ public int connect(BluetoothDevice device) {
+ return -1;
+ }
+
+ @Override
+ public int disconnect(BluetoothDevice device) {
+ return -1;
+ }
+
+ @Override
+ public int getConnectionStatus(BluetoothDevice device) {
+ return -1;
+ }
+
+ @Override
+ public int getSummary(BluetoothDevice device) {
+ int connectionStatus = getConnectionStatus(device);
+
+ if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
+ return R.string.bluetooth_opp_profile_summary_connected;
+ } else {
+ return R.string.bluetooth_opp_profile_summary_not_connected;
+ }
+ }
+
+ @Override
+ public boolean isPreferred(BluetoothDevice device) {
+ return false;
+ }
+
+ @Override
+ public void setPreferred(BluetoothDevice device, boolean preferred) {
+ }
+
+ @Override
+ public int convertState(int oppState) {
+ switch (oppState) {
+ case 0:
+ return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
+ case 1:
+ return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+ case 2:
+ return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
+ default:
+ return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
+ }
+ }
+ }
}