diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6a773a4bcf7..5b9af25dd6c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -659,9 +659,6 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/preference_bluetooth_profile.xml b/res/layout/preference_bluetooth_profile.xml
new file mode 100644
index 00000000000..5ec0a479f99
--- /dev/null
+++ b/res/layout/preference_bluetooth_profile.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/profile_icon_small.xml b/res/layout/profile_icon_small.xml
new file mode 100644
index 00000000000..b0a9f4bdd26
--- /dev/null
+++ b/res/layout/profile_icon_small.xml
@@ -0,0 +1,23 @@
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d6221fe0480..da54e9d3523 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -782,7 +782,14 @@
Scan for devices
-
+
+ Find nearby devices
+
+ Device settings
+
+ Paired devices
+
+ Found devices
Connect
@@ -823,12 +830,18 @@
%1$s options
+
+ Device actions
Connect
Connect to Bluetooth device
Profiles
+
+ Rename device
+
+ Allow incoming file transfers
Connected to media audio
diff --git a/res/xml/bluetooth_device_advanced.xml b/res/xml/bluetooth_device_advanced.xml
index 561159529b7..b4a097860cf 100644
--- a/res/xml/bluetooth_device_advanced.xml
+++ b/res/xml/bluetooth_device_advanced.xml
@@ -18,15 +18,32 @@
xmlns:android="http://schemas.android.com/apk/res/android">
-
-
+
+
-
+
+
+
+
+
diff --git a/res/xml/bluetooth_settings.xml b/res/xml/bluetooth_settings.xml
index 131f7a01ee5..b7a0edcd77b 100644
--- a/res/xml/bluetooth_settings.xml
+++ b/res/xml/bluetooth_settings.xml
@@ -18,6 +18,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/bluetooth_settings" >
+
+
-
-
-
+
+
diff --git a/res/xml/device_picker.xml b/res/xml/device_picker.xml
index 7dd5b6887f1..43b58296cd3 100644
--- a/res/xml/device_picker.xml
+++ b/res/xml/device_picker.xml
@@ -23,7 +23,7 @@
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index f0b1705b3a0..1f9408d12e4 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -19,16 +19,22 @@ package com.android.settings.bluetooth;
import com.android.settings.R;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.util.TypedValue;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
import android.widget.ImageView;
+import android.widget.LinearLayout;
/**
* BluetoothDevicePreference is the preference type used to display each remote
* Bluetooth device in the Bluetooth Settings screen.
*/
-public class BluetoothDevicePreference extends Preference implements CachedBluetoothDevice.Callback {
+public class BluetoothDevicePreference extends Preference implements
+ CachedBluetoothDevice.Callback, OnClickListener {
private static final String TAG = "BluetoothDevicePreference";
private static int sDimAlpha = Integer.MIN_VALUE;
@@ -36,6 +42,9 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
private CachedBluetoothDevice mCachedDevice;
private int mAccessibleProfile;
+ private ImageView mDeviceSettings;
+ private OnClickListener mOnSettingsClickListener;
+
/**
* Cached local copy of whether the device is busy. This is only updated
* from {@link #onDeviceAttributesChanged(CachedBluetoothDevice)}.
@@ -66,6 +75,10 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
return mCachedDevice;
}
+ public void setOnSettingsClickListener(OnClickListener listener) {
+ mOnSettingsClickListener = listener;
+ }
+
@Override
protected void onPrepareForRemoval() {
super.onPrepareForRemoval();
@@ -117,6 +130,34 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
ImageView btClass = (ImageView) view.findViewById(R.id.btClass);
btClass.setImageResource(mCachedDevice.getBtClassDrawable());
btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
+
+ mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails);
+ if (mOnSettingsClickListener != null) {
+ mDeviceSettings.setOnClickListener(this);
+ mDeviceSettings.setTag(mCachedDevice);
+ } else { // Hide the settings icon and divider
+ mDeviceSettings.setVisibility(View.GONE);
+ ImageView divider = (ImageView) view.findViewById(R.id.divider);
+ if (divider != null) {
+ divider.setVisibility(View.GONE);
+ }
+ }
+
+ LayoutInflater inflater = (LayoutInflater)
+ getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ ViewGroup profilesGroup = (ViewGroup) view.findViewById(R.id.profileIcons);
+ for (Drawable icon : mCachedDevice.getProfileIcons()) {
+ inflater.inflate(R.layout.profile_icon_small, profilesGroup, true);
+ ImageView imageView =
+ (ImageView) profilesGroup.getChildAt(profilesGroup.getChildCount() - 1);
+ imageView.setImageDrawable(icon);
+ }
+ }
+
+ public void onClick(View v) {
+ if (v == mDeviceSettings) {
+ if (mOnSettingsClickListener != null) mOnSettingsClickListener.onClick(v);
+ }
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
new file mode 100644
index 00000000000..c0df8a74140
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 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 com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+import com.android.settings.R;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.preference.Preference;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+
+/**
+ * BluetoothProfilePreference is the preference type used to display each profile for a
+ * particular bluetooth device.
+ */
+public class BluetoothProfilePreference extends Preference implements OnClickListener {
+
+ private static final String TAG = "BluetoothProfilePreference";
+
+ private Drawable mProfileDrawable;
+ private boolean mExpanded;
+ private ImageView mProfileExpandView;
+ private Profile mProfile;
+
+ private OnClickListener mOnExpandClickListener;
+
+ public BluetoothProfilePreference(Context context, Profile profile) {
+ super(context);
+
+ mProfile = profile;
+
+ setLayoutResource(R.layout.preference_bluetooth_profile);
+ setExpanded(false);
+ }
+
+ public void setOnExpandClickListener(OnClickListener listener) {
+ mOnExpandClickListener = listener;
+ }
+
+ public void setExpanded(boolean expanded) {
+ mExpanded = expanded;
+ notifyChanged();
+ }
+
+ public boolean isExpanded() {
+ return mExpanded;
+ }
+
+ public void setProfileDrawable(Drawable drawable) {
+ mProfileDrawable = drawable;
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ ImageView btProfile = (ImageView) view.findViewById(R.id.profileIcon);
+ btProfile.setImageDrawable(mProfileDrawable);
+
+ mProfileExpandView = (ImageView) view.findViewById(R.id.profileExpand);
+ mProfileExpandView.setOnClickListener(this);
+ mProfileExpandView.setTag(mProfile);
+
+ mProfileExpandView.setImageResource(mExpanded ? R.drawable.ic_preferences_expanded
+ : R.drawable.ic_preferences_collapsed);
+ }
+
+ public void onClick(View v) {
+ if (v == mProfileExpandView) {
+ if (mOnExpandClickListener != null) {
+ setExpanded(!mExpanded);
+ mOnExpandClickListener.onClick(v);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 0de3bfa96ad..841c9abc4c9 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -16,11 +16,11 @@
package com.android.settings.bluetooth;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import com.android.settings.ProgressCategory;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.UserLeaveHintListener;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import android.app.Activity;
import android.app.AlertDialog;
@@ -39,6 +39,7 @@ import android.os.Bundle;
import android.os.ParcelUuid;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
+import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.text.TextUtils;
import android.view.ContextMenu;
@@ -55,7 +56,7 @@ import java.util.WeakHashMap;
* connection management.
*/
public class BluetoothSettings extends SettingsPreferenceFragment
- implements LocalBluetoothManager.Callback, UserLeaveHintListener {
+ implements LocalBluetoothManager.Callback, UserLeaveHintListener, View.OnClickListener {
private static final String TAG = "BluetoothSettings";
@@ -64,14 +65,18 @@ public class BluetoothSettings extends SettingsPreferenceFragment
private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
private static final String KEY_BT_NAME = "bt_name";
private static final String KEY_BT_SCAN = "bt_scan";
+ private static final String KEY_BT_FIND_NEARBY = "bt_find_nearby";
private static final int SCREEN_TYPE_SETTINGS = 0;
private static final int SCREEN_TYPE_DEVICEPICKER = 1;
private static final int SCREEN_TYPE_TETHERING = 2;
+ private static final int SCREEN_TYPE_SCAN = 3;
public static final String ACTION = "bluetooth_action";
public static final String ACTION_LAUNCH_TETHER_PICKER =
- "com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
+ "com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
+ public static final String ACTION_LAUNCH_SCAN_MODE =
+ "com.android.settings.bluetooth.action.LAUNCH_SCAN_MODE";
private int mScreenType;
private int mFilterType;
@@ -88,7 +93,7 @@ public class BluetoothSettings extends SettingsPreferenceFragment
private BluetoothNamePreference mNamePreference;
- private ProgressCategory mDeviceList;
+ private PreferenceCategory mDeviceList;
private WeakHashMap mDevicePreferenceMap =
new WeakHashMap();
@@ -96,11 +101,11 @@ public class BluetoothSettings extends SettingsPreferenceFragment
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- // TODO: put this in callback instead of receiving
-
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
onBluetoothStateChanged(mLocalManager.getBluetoothState());
} else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+ // TODO: If this is a scanning screen, maybe return on successful pairing
+
int bondState = intent
.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
if (bondState == BluetoothDevice.BOND_BONDED) {
@@ -153,6 +158,8 @@ public class BluetoothSettings extends SettingsPreferenceFragment
action = intent.getAction();
}
+ if (getPreferenceScreen() != null) getPreferenceScreen().removeAll();
+
if (action.equals(BluetoothDevicePicker.ACTION_LAUNCH)) {
mScreenType = SCREEN_TYPE_DEVICEPICKER;
mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
@@ -168,6 +175,10 @@ public class BluetoothSettings extends SettingsPreferenceFragment
mFilterType = BluetoothDevicePicker.FILTER_TYPE_PANU;
activity.setTitle(activity.getString(R.string.device_picker));
+ addPreferencesFromResource(R.xml.device_picker);
+ } else if (action.equals(ACTION_LAUNCH_SCAN_MODE)) {
+ mScreenType = SCREEN_TYPE_SCAN;
+
addPreferencesFromResource(R.xml.device_picker);
} else {
addPreferencesFromResource(R.xml.bluetooth_settings);
@@ -182,10 +193,9 @@ public class BluetoothSettings extends SettingsPreferenceFragment
mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
- mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
}
- mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
+ mDeviceList = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
registerForContextMenu(getListView());
@@ -200,7 +210,9 @@ public class BluetoothSettings extends SettingsPreferenceFragment
// bluetooth manager
mDevicePreferenceMap.clear();
mDeviceList.removeAll();
- addDevices();
+ if (mScreenType != SCREEN_TYPE_SCAN) {
+ addDevices();
+ }
if (mScreenType == SCREEN_TYPE_SETTINGS) {
mEnabler.resume();
@@ -210,8 +222,11 @@ public class BluetoothSettings extends SettingsPreferenceFragment
mLocalManager.registerCallback(this);
- mDeviceList.setProgress(mLocalManager.getBluetoothAdapter().isDiscovering());
- mLocalManager.startScanning(false);
+ updateProgressUi(mLocalManager.getBluetoothAdapter().isDiscovering());
+
+ if (mScreenType != SCREEN_TYPE_SETTINGS) {
+ mLocalManager.startScanning(true);
+ }
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
@@ -249,6 +264,13 @@ public class BluetoothSettings extends SettingsPreferenceFragment
}
}
+ public void onClick(View v) {
+ if (v.getTag() instanceof CachedBluetoothDevice) {
+ CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
+ device.onClickedAdvancedOptions(this);
+ }
+ }
+
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
@@ -260,7 +282,7 @@ public class BluetoothSettings extends SettingsPreferenceFragment
if (preference instanceof BluetoothDevicePreference) {
BluetoothDevicePreference btPreference = (BluetoothDevicePreference)preference;
- if (mScreenType == SCREEN_TYPE_SETTINGS) {
+ if (mScreenType == SCREEN_TYPE_SETTINGS || mScreenType == SCREEN_TYPE_SCAN) {
btPreference.getCachedDevice().onClicked();
} else if (mScreenType == SCREEN_TYPE_DEVICEPICKER) {
CachedBluetoothDevice device = btPreference.getCachedDevice();
@@ -312,7 +334,7 @@ public class BluetoothSettings extends SettingsPreferenceFragment
CachedBluetoothDevice cachedDevice = getDeviceFromMenuInfo(item.getMenuInfo());
if (cachedDevice == null) return false;
- cachedDevice.onContextItemSelected(item);
+ cachedDevice.onContextItemSelected(item, this);
return true;
}
@@ -337,8 +359,11 @@ public class BluetoothSettings extends SettingsPreferenceFragment
throw new IllegalStateException("Got onDeviceAdded, but cachedDevice already exists");
}
- if (addDevicePreference(cachedDevice)) {
- createDevicePreference(cachedDevice);
+ if (mScreenType != SCREEN_TYPE_SETTINGS
+ || cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
+ if (addDevicePreference(cachedDevice)) {
+ createDevicePreference(cachedDevice);
+ }
}
}
@@ -406,6 +431,9 @@ public class BluetoothSettings extends SettingsPreferenceFragment
preference = new BluetoothDevicePreference(
getActivity(), cachedDevice, CachedBluetoothDevice.OTHER_PROFILES);
}
+ if (mScreenType == SCREEN_TYPE_SETTINGS) {
+ preference.setOnSettingsClickListener(this);
+ }
mDeviceList.addPreference(preference);
mDevicePreferenceMap.put(cachedDevice, preference);
}
@@ -418,16 +446,23 @@ public class BluetoothSettings extends SettingsPreferenceFragment
}
public void onScanningStateChanged(boolean started) {
- mDeviceList.setProgress(started);
+ updateProgressUi(started);
}
+ private void updateProgressUi(boolean start) {
+ if (mDeviceList instanceof ProgressCategory) {
+ ((ProgressCategory) mDeviceList).setProgress(start);
+ }
+ }
private void onBluetoothStateChanged(int bluetoothState) {
// When bluetooth is enabled (and we are in the activity, which we are),
// we should start a scan
if (bluetoothState == BluetoothAdapter.STATE_ON) {
- mLocalManager.startScanning(false);
+ if (mScreenType != SCREEN_TYPE_SETTINGS) {
+ mLocalManager.startScanning(false);
+ }
} else if (bluetoothState == BluetoothAdapter.STATE_OFF) {
- mDeviceList.setProgress(false);
+ updateProgressUi(false);
}
}
@@ -480,4 +515,22 @@ public class BluetoothSettings extends SettingsPreferenceFragment
}
getActivity().sendBroadcast(intent);
}
+
+ public static class FindNearby extends BluetoothSettings {
+
+ public FindNearby() {
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ Bundle args = super.getArguments();
+ if (args == null) {
+ args = new Bundle();
+ setArguments(args);
+ }
+ args.putString(ACTION, ACTION_LAUNCH_SCAN_MODE);
+ super.onActivityCreated(savedInstanceState);
+ }
+ }
}
+
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index c0fa105d82d..22fa0055ede 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -16,28 +16,31 @@
package com.android.settings.bluetooth;
+import com.android.settings.R;
+
+import com.android.settings.SettingsPreferenceFragment;
+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.content.Context;
import android.content.DialogInterface;
-import android.content.Intent;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
import android.os.ParcelUuid;
import android.os.SystemClock;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
-import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
-
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
/**
* CachedBluetoothDevice represents a remote Bluetooth device. It contains
@@ -63,6 +66,7 @@ public class CachedBluetoothDevice implements Comparable
private String mName;
private short mRssi;
private BluetoothClass mBtClass;
+ private Context mContext;
private List mProfiles = new ArrayList();
@@ -138,6 +142,7 @@ public class CachedBluetoothDevice implements Comparable
}
mDevice = device;
+ mContext = context;
fillData();
}
@@ -655,6 +660,20 @@ public class CachedBluetoothDevice implements Comparable
return SettingsBtStatus.getPairingStatusSummary(getBondState());
}
+ public List getProfileIcons() {
+ ArrayList drawables = new ArrayList();
+
+ for (Profile profile : mProfiles) {
+ LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+ .getProfileManager(mLocalManager, profile);
+ int iconResource = profileManager.getDrawableResource();
+ if (iconResource != 0) {
+ drawables.add(mContext.getResources().getDrawable(iconResource));
+ }
+ }
+
+ return drawables;
+ }
/**
* We have special summaries when particular profiles are connected. This
* checks for those states and returns an applicable summary.
@@ -781,7 +800,7 @@ public class CachedBluetoothDevice implements Comparable
*
* @param item The item that was clicked.
*/
- public void onContextItemSelected(MenuItem item) {
+ public void onContextItemSelected(MenuItem item, SettingsPreferenceFragment fragment) {
switch (item.getItemId()) {
case CONTEXT_ITEM_DISCONNECT:
disconnect();
@@ -796,21 +815,34 @@ public class CachedBluetoothDevice implements Comparable
break;
case CONTEXT_ITEM_CONNECT_ADVANCED:
- Intent intent = new Intent();
- // Need an activity context to open this in our task
- Context context = mLocalManager.getForegroundActivity();
- if (context == null) {
- // Fallback on application context, and open in a new task
- context = mLocalManager.getContext();
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
- intent.setClass(context, ConnectSpecificProfilesActivity.class);
- intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE, mDevice);
- context.startActivity(intent);
+ onClickedAdvancedOptions(fragment);
break;
}
}
+ public void onClickedAdvancedOptions(SettingsPreferenceFragment fragment) {
+ // TODO: Verify if there really is a case when there's no foreground
+ // activity
+
+ // Intent intent = new Intent();
+ // // Need an activity context to open this in our task
+ // Context context = mLocalManager.getForegroundActivity();
+ // if (context == null) {
+ // // Fallback on application context, and open in a new task
+ // context = mLocalManager.getContext();
+ // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // }
+ // intent.setClass(context, ConnectSpecificProfilesActivity.class);
+ // intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE,
+ // mDevice);
+ // context.startActivity(intent);
+ Preference pref = new Preference(fragment.getActivity());
+ pref.setTitle(getName());
+ pref.setFragment(DeviceProfilesSettings.class.getName());
+ pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, mDevice);
+ ((PreferenceActivity) fragment.getActivity()).onPreferenceStartFragment(fragment, pref);
+ }
+
public void registerCallback(Callback callback) {
synchronized (mCallbacks) {
mCallbacks.add(callback);
diff --git a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
similarity index 54%
rename from src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
rename to src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index ac2b4d81ab8..f8a66f68063 100644
--- a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -16,31 +16,41 @@
package com.android.settings.bluetooth;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+
import android.bluetooth.BluetoothDevice;
-import android.content.Intent;
+import android.content.Context;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
import android.preference.Preference;
-import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
+import android.view.View;
-import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+import java.util.HashMap;
/**
* ConnectSpecificProfilesActivity presents the user with all of the profiles
* for a particular device, and allows him to choose which should be connected
* (or disconnected).
*/
-public class ConnectSpecificProfilesActivity extends PreferenceActivity
- implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
- private static final String TAG = "ConnectSpecificProfilesActivity";
+public class DeviceProfilesSettings extends SettingsPreferenceFragment
+ implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener,
+ View.OnClickListener {
+ private static final String TAG = "DeviceProfilesSettings";
- private static final String KEY_ONLINE_MODE = "online_mode";
private static final String KEY_TITLE = "title";
+ private static final String KEY_RENAME_DEVICE = "rename_device";
private static final String KEY_PROFILE_CONTAINER = "profile_container";
+ private static final String KEY_UNPAIR = "unpair";
+ private static final String KEY_ALLOW_INCOMING = "allow_incoming";
+
+ private static final String AUTO_CONNECT_KEY_SUFFIX = "X";
public static final String EXTRA_DEVICE = "device";
@@ -48,27 +58,21 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
private CachedBluetoothDevice mCachedDevice;
private PreferenceGroup mProfileContainer;
- private CheckBoxPreference mOnlineModePreference;
-
- /**
- * The current mode of this activity and its checkboxes (either online mode
- * or offline mode). In online mode, user interactions with the profile
- * checkboxes will also toggle the profile's connectivity. In offline mode,
- * they will not, and only the preferred state will be saved for the
- * profile.
- */
- private boolean mOnlineMode;
+ private CheckBoxPreference mAllowIncomingPref;
+ private EditTextPreference mDeviceNamePref;
+ private HashMap mAutoConnectPrefs
+ = new HashMap();
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BluetoothDevice device;
if (savedInstanceState != null) {
device = savedInstanceState.getParcelable(EXTRA_DEVICE);
} else {
- Intent intent = getIntent();
- device = intent.getParcelableExtra(EXTRA_DEVICE);
+ Bundle args = getArguments();
+ device = args.getParcelable(EXTRA_DEVICE);
}
if (device == null) {
@@ -76,7 +80,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
finish();
}
- mManager = LocalBluetoothManager.getInstance(this);
+ mManager = LocalBluetoothManager.getInstance(getActivity());
mCachedDevice = mManager.getCachedDeviceManager().findDevice(device);
if (mCachedDevice == null) {
Log.w(TAG, "Device not found, cannot connect to it");
@@ -84,39 +88,43 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
}
addPreferencesFromResource(R.xml.bluetooth_device_advanced);
+ getPreferenceScreen().setOrderingAsAdded(false);
+
mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
+ mAllowIncomingPref = (CheckBoxPreference) findPreference(KEY_ALLOW_INCOMING);
+ mAllowIncomingPref.setChecked(isIncomingFileTransfersAllowed());
+
+ mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
+ mDeviceNamePref.setSummary(mCachedDevice.getName());
+ mDeviceNamePref.setText(mCachedDevice.getName());
// Set the title of the screen
- findPreference(KEY_TITLE).setTitle(
- getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
-
- // Listen for check/uncheck of the online mode checkbox
- mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
- mOnlineModePreference.setOnPreferenceChangeListener(this);
+ findPreference(KEY_TITLE).setTitle(getResources()
+ .getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
// Add a preference for each profile
addPreferencesForProfiles();
}
@Override
- protected void onSaveInstanceState(Bundle outState) {
+ public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(EXTRA_DEVICE, mCachedDevice.getDevice());
}
@Override
- protected void onResume() {
+ public void onResume() {
super.onResume();
- mManager.setForegroundActivity(this);
+ mManager.setForegroundActivity(getActivity());
mCachedDevice.registerCallback(this);
refresh();
}
@Override
- protected void onPause() {
+ public void onPause() {
super.onPause();
mCachedDevice.unregisterCallback(this);
@@ -138,18 +146,20 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
* @return A preference that allows the user to choose whether this profile
* will be connected to.
*/
- private CheckBoxPreference createProfilePreference(Profile profile) {
- CheckBoxPreference pref = new CheckBoxPreference(this);
+ private Preference createProfilePreference(Profile profile) {
+ BluetoothProfilePreference pref = new BluetoothProfilePreference(getActivity(), profile);
pref.setKey(profile.toString());
pref.setTitle(profile.localizedString);
+ pref.setExpanded(false);
pref.setPersistent(false);
- pref.setOnPreferenceChangeListener(this);
+ pref.setOrder(getProfilePreferenceIndex(profile));
+ pref.setOnExpandClickListener(this);
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile);
/**
- * Gray out checkbox while connecting and disconnecting
+ * Gray out profile while connecting and disconnecting
*/
pref.setEnabled(!mCachedDevice.isBusy());
@@ -158,37 +168,46 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
return pref;
}
- public boolean onPreferenceChange(Preference preference, Object newValue) {
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
String key = preference.getKey();
- if (TextUtils.isEmpty(key) || newValue == null) return true;
+ if (preference instanceof BluetoothProfilePreference) {
+ onProfileClicked(preference, Profile.valueOf(key));
+ return true;
+ } else if (key.equals(KEY_UNPAIR)) {
+ unpairDevice();
+ finish();
+ return true;
+ }
- if (key.equals(KEY_ONLINE_MODE)) {
- onOnlineModeCheckedStateChanged((Boolean) newValue);
+ return false;
+ }
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mAllowIncomingPref) {
+ setIncomingFileTransfersAllowed(mAllowIncomingPref.isChecked());
+ } else if (preference == mDeviceNamePref) {
+ // TODO: Verify and check for error conditions
+ mCachedDevice.setName(mDeviceNamePref.getText());
} else {
- Profile profile = getProfileOf(preference);
- if (profile == null) return false;
- onProfileCheckedStateChanged(profile, (Boolean) newValue);
+ return false;
}
return true;
}
- private void onOnlineModeCheckedStateChanged(boolean checked) {
- setOnlineMode(checked, true);
- }
-
- private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
+ private void onProfileClicked(Preference preference, Profile profile) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile);
- profileManager.setPreferred(mCachedDevice.getDevice(), checked);
- if (mOnlineMode) {
- if (checked) {
- mCachedDevice.connect(profile);
- } else {
- mCachedDevice.disconnect(profile);
- }
- }
+ // TODO: Get the current state and flip it, updating the summary for the preference
+
+// profileManager.setPreferred(mCachedDevice.getDevice(), checked);
+//
+// if (checked) {
+// mCachedDevice.connect(profile);
+// } else {
+// mCachedDevice.disconnect(profile);
+// }
}
public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {
@@ -196,51 +215,12 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
}
private void refresh() {
- // We are in 'online mode' if we are connected, connecting, or disconnecting
- setOnlineMode(mCachedDevice.isConnected() || mCachedDevice.isBusy(), false);
refreshProfiles();
}
- /**
- * Switches between online/offline mode.
- *
- * @param onlineMode Whether to be in online mode, or offline mode.
- * @param takeAction Whether to take action (i.e., connect or disconnect)
- * based on the new online mode.
- */
- private void setOnlineMode(boolean onlineMode, boolean takeAction) {
- mOnlineMode = onlineMode;
-
- if (takeAction) {
- if (onlineMode) {
- mCachedDevice.connect();
- } else {
- mCachedDevice.disconnect();
- }
- }
-
- refreshOnlineModePreference();
- }
-
- private void refreshOnlineModePreference() {
- mOnlineModePreference.setChecked(mOnlineMode);
-
- /* Gray out checkbox while connecting and disconnecting */
- mOnlineModePreference.setEnabled(!mCachedDevice.isBusy());
-
- /**
- * If the device is online, show status. Otherwise, show a summary that
- * describes what the checkbox does.
- */
- mOnlineModePreference.setSummary(mOnlineMode ?
- mCachedDevice.getSummary(CachedBluetoothDevice.OTHER_PROFILES)
- : R.string.bluetooth_device_advanced_online_mode_summary);
- }
-
private void refreshProfiles() {
for (Profile profile : mCachedDevice.getConnectableProfiles()) {
- CheckBoxPreference profilePref =
- (CheckBoxPreference) findPreference(profile.toString());
+ Preference profilePref = findPreference(profile.toString());
if (profilePref == null) {
profilePref = createProfilePreference(profile);
mProfileContainer.addPreference(profilePref);
@@ -250,7 +230,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
}
}
- private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
+ private void refreshProfilePreference(Preference profilePref, Profile profile) {
BluetoothDevice device = mCachedDevice.getDevice();
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile);
@@ -262,9 +242,9 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
*/
profilePref.setEnabled(!mCachedDevice.isBusy());
profilePref.setSummary(getProfileSummary(profileManager, profile, device,
- connectionStatus, mOnlineMode));
-
- profilePref.setChecked(profileManager.isPreferred(device));
+ connectionStatus, isDeviceOnline()));
+ // TODO:
+ //profilePref.setChecked(profileManager.isPreferred(device));
}
private Profile getProfileOf(Preference pref) {
@@ -307,4 +287,60 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
}
}
+ public void onClick(View v) {
+ if (v.getTag() instanceof Profile) {
+ Profile prof = (Profile) v.getTag();
+ CheckBoxPreference autoConnectPref = mAutoConnectPrefs.get(prof.toString());
+ if (autoConnectPref == null) {
+ autoConnectPref = new CheckBoxPreference(getActivity());
+ autoConnectPref.setKey(prof.toString() + AUTO_CONNECT_KEY_SUFFIX);
+ autoConnectPref.setTitle(getCheckBoxTitle(prof));
+ autoConnectPref.setOrder(getProfilePreferenceIndex(prof) + 1);
+ autoConnectPref.setChecked(getAutoConnect(prof));
+ mAutoConnectPrefs.put(prof.name(), autoConnectPref);
+ }
+ BluetoothProfilePreference profilePref =
+ (BluetoothProfilePreference) findPreference(prof.toString());
+ if (profilePref != null) {
+ if (profilePref.isExpanded()) {
+ mProfileContainer.addPreference(autoConnectPref);
+ } else {
+ mProfileContainer.removePreference(autoConnectPref);
+ }
+ }
+ }
+ }
+
+ private int getProfilePreferenceIndex(Profile prof) {
+ return mProfileContainer.getOrder() + prof.ordinal() * 10;
+ }
+
+ private void unpairDevice() {
+ mCachedDevice.unpair();
+ }
+
+ private boolean isDeviceOnline() {
+ // TODO: Verify
+ return mCachedDevice.isConnected() || mCachedDevice.isBusy();
+ }
+
+ private void setIncomingFileTransfersAllowed(boolean allow) {
+ // TODO:
+ Log.d(TAG, "Set allow incoming = " + allow);
+ }
+
+ private boolean isIncomingFileTransfersAllowed() {
+ // TODO:
+ return true;
+ }
+
+ private String getCheckBoxTitle(Profile prof) {
+ // TODO: Use resources and base it on profile if necessary
+ return "Auto connect";
+ }
+
+ private boolean getAutoConnect(Profile prof) {
+ // TODO: Get the auto connect toggle state for the profile
+ return true;
+ }
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index 613ee258676..b46cc96d2f1 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -47,7 +47,7 @@ public class LocalBluetoothManager {
private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
/** Singleton instance. */
- private static LocalBluetoothManager INSTANCE;
+ private static LocalBluetoothManager sInstance;
private boolean mInitialized;
private Context mContext;
@@ -87,17 +87,17 @@ public class LocalBluetoothManager {
public static LocalBluetoothManager getInstance(Context context) {
synchronized (LocalBluetoothManager.class) {
- if (INSTANCE == null) {
- INSTANCE = new LocalBluetoothManager();
+ if (sInstance == null) {
+ sInstance = new LocalBluetoothManager();
}
- if (!INSTANCE.init(context)) {
+ if (!sInstance.init(context)) {
return null;
}
- LocalBluetoothProfileManager.init(INSTANCE);
+ LocalBluetoothProfileManager.init(sInstance);
- return INSTANCE;
+ return sInstance;
}
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index 1480b163e4f..f7ad3d3c4b5 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -31,12 +31,10 @@ import android.os.ParcelUuid;
import android.util.Log;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* LocalBluetoothProfileManager is an abstract class defining the basic
@@ -123,7 +121,8 @@ public abstract class LocalBluetoothProfileManager {
}
}
- private static LinkedList mServiceListeners = new LinkedList();
+ private static LinkedList mServiceListeners =
+ new LinkedList();
public static void addServiceListener(ServiceListener l) {
mServiceListeners.add(l);
@@ -221,6 +220,10 @@ public abstract class LocalBluetoothProfileManager {
public abstract boolean isProfileReady();
+ public int getDrawableResource() {
+ return R.drawable.ic_bt_headphones_a2dp;
+ }
+
// TODO: int instead of enum
public enum Profile {
HEADSET(R.string.bluetooth_profile_headset),
@@ -347,6 +350,11 @@ public abstract class LocalBluetoothProfileManager {
public boolean isProfileReady() {
return true;
}
+
+ @Override
+ public int getDrawableResource() {
+ return R.drawable.ic_bt_headphones_a2dp;
+ }
}
/**
@@ -489,6 +497,11 @@ public abstract class LocalBluetoothProfileManager {
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
}
}
+
+ @Override
+ public int getDrawableResource() {
+ return R.drawable.ic_bt_headset_hfp;
+ }
}
/**
@@ -563,6 +576,12 @@ public abstract class LocalBluetoothProfileManager {
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
}
}
+
+ @Override
+ public int getDrawableResource() {
+ // TODO:
+ return 0;
+ }
}
private static class HidProfileManager extends LocalBluetoothProfileManager {
@@ -645,6 +664,12 @@ public abstract class LocalBluetoothProfileManager {
mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_OFF);
}
}
+
+ @Override
+ public int getDrawableResource() {
+ // TODO:
+ return 0;
+ }
}
private static class PanProfileManager extends LocalBluetoothProfileManager {
@@ -721,5 +746,11 @@ public abstract class LocalBluetoothProfileManager {
public void setPreferred(BluetoothDevice device, boolean preferred) {
return;
}
+
+ @Override
+ public int getDrawableResource() {
+ // TODO:
+ return 0;
+ }
}
}