Fix multiple BT settings bugs.

- Change Bluetooth profiles screen to match ICS wireframes
- Remove BluetoothProfilePreference.java (no longer used)
- Remove "Pair with this device" summary below every unpaired device
- Remove "Paired but not connected" summary below unconnected paired devices
- Fix auto connection after pairing (reuse existing CachedBluetoothDevice)
- Add "Connected (no phone/media)" summaries based on ICS wireframes
- Fix visibility timeout strings.
- Fix crash when starting Bluetooth from Settings shortcut widget.

Bug: 5064139
Bug: 5064324
Bug: 5080404
Bug: 5093513
Bug: 5104485
Change-Id: Ie87103e183ce414c86cb1831a38ef0178b1b1292
This commit is contained in:
Jake Hamby
2011-08-01 16:36:35 -07:00
parent 0c8ff2b3ce
commit 79be0b3e6b
18 changed files with 157 additions and 314 deletions

View File

@@ -19,13 +19,6 @@
android:layout_height="wrap_content"
android:gravity="center_vertical">
<LinearLayout android:id="@+id/profileIcons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
/>
<!-- Divider -->
<ImageView
android:id="@+id/divider"

View File

@@ -350,10 +350,10 @@
<!-- Discoverable mode timeout options -->
<string-array name="bluetooth_visibility_timeout_entries">
<item>2 Minutes</item>
<item>5 Minutes</item>
<item>1 Hour</item>
<item>Never</item>
<item>2 minutes</item>
<item>5 minutes</item>
<item>1 hour</item>
<item>Never time out</item>
</string-array>
<!-- Match this with drawable.wifi_signal. --> <skip />

View File

@@ -230,10 +230,20 @@
<string name="bluetooth_disconnect_title">Disconnect?</string>
<!-- Bluetooth settings. Message for disconnecting from all profiles of a bluetooth device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_disconnect_all_profiles">This will end your connection with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b></string>
<!-- Bluetooth settings. Message for disconnecting from all profiles of a bluetooth device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_disconnect_blank">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> will be disconnected."</string>
<!-- Bluetooth settings. Message when connected to a device -->
<!-- Bluetooth settings. Dialog title to disable a single profile of a device. [CHAR LIMIT=40] -->
<string name="bluetooth_disable_profile_title">Disable profile?</string>
<!-- Bluetooth settings. Message for disabling a profile of a bluetooth device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_disable_profile_message">This will disable:&lt;br>&lt;b><xliff:g id="profile_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>From:&lt;br>&lt;b><xliff:g id="device_name">%2$s</xliff:g>&lt;/b></string>
<!-- Bluetooth settings. Message when connected to a device. [CHAR LIMIT=40] -->
<string name="bluetooth_connected">Connected</string>
<!-- Bluetooth settings. Message when connected to a device, except for phone audio. [CHAR LIMIT=40] -->
<string name="bluetooth_connected_no_headset">Connected (no phone)</string>
<!-- Bluetooth settings. Message when connected to a device, except for media audio. [CHAR LIMIT=40] -->
<string name="bluetooth_connected_no_a2dp">Connected (no media)</string>
<!-- Bluetooth settings. Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] -->
<string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)</string>
<!-- Bluetooth settings. Message when a device is disconnected -->
<string name="bluetooth_disconnected">Disconnected</string>
<!-- Bluetooth settings. Message when disconnecting from a device -->
@@ -242,12 +252,8 @@
<string name="bluetooth_connecting">Connecting\u2026</string>
<!-- Bluetooth settings. Message when the device state is unknown -->
<string name="bluetooth_unknown" />
<!--Bluetooth settings screen, summary text under individual Bluetooth devices when not paired yet -->
<string name="bluetooth_not_connected">Pair with this device</string>
<!--Bluetooth settings screen, summary text under individual Bluetooth devices when pairing -->
<string name="bluetooth_pairing">Pairing\u2026</string>
<!--Bluetooth settings screen, summary text under individual Bluetooth devices when paired with one -->
<string name="bluetooth_paired">Paired but not connected</string>
<!--Bluetooth settings screen, summary text for Bluetooth device with no name -->
<string name="bluetooth_device">Unnamed Bluetooth device</string>
<!--Bluetooth settings screen, text that appears in heading bar when scanning for devices -->
@@ -1011,15 +1017,17 @@
<string name="bluetooth_connect_specific_profiles_title">Connect to\u2026</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the A2DP profile. -->
<string name="bluetooth_profile_a2dp">Media</string>
<string name="bluetooth_profile_a2dp">Media audio</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the headset or handsfree profile. -->
<string name="bluetooth_profile_headset">Handsfree</string>
<string name="bluetooth_profile_headset">Phone audio</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the OPP profile. -->
<string name="bluetooth_profile_opp">Transfer</string>
<string name="bluetooth_profile_opp">File transfer</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the HID profile. -->
<string name="bluetooth_profile_hid">Input Device</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile. [CHAR LIMIT=25]-->
<string name="bluetooth_profile_hid">Input device</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile (accessing Internet through remote device). [CHAR LIMIT=40]-->
<string name="bluetooth_profile_pan">Internet access</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile (sharing this device's Internet connection). [CHAR LIMIT=40]-->
<string name="bluetooth_profile_pan_nap">Internet connection sharing</string>
<!-- Bluetooth settings. Message for disconnecting from the A2DP profile. [CHAR LIMIT=80] -->
<string name="bluetooth_disconnect_a2dp_profile"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from media audio.</string>
@@ -1034,10 +1042,8 @@
<!-- Bluetooth settings. Message for disconnecting from the PAN profile (NAP role). [CHAR LIMIT=80] -->
<string name="bluetooth_disconnect_pan_nap_profile" product="default"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from sharing this phone\'s Internet connection.</string>
<!-- Bluetooth settings. Connection options screen. The title of the screen. -->
<string name="bluetooth_device_advanced_title"><xliff:g id="device_name">%1$s</xliff:g> options</string>
<!-- Bluetooth settings. Connection options screen. Title of device actions section. [CHAR LIMIT=30] -->
<string name="bluetooth_device_advanced_device_actions_title">Device actions</string>
<!-- Bluetooth settings. Connection options screen. The title of the screen. [CHAR LIMIT=40] -->
<string name="bluetooth_device_advanced_title">Paired Bluetooth device</string>
<!-- Bluetooth settings. Connection options screen. The title of the checkbox that controls whether the device is in "online" mode or "offline" mode. This essentially is the checkbox that controls whether any checks / unchecks on a profile should be applied immediately, or next time the device is connected. -->
<string name="bluetooth_device_advanced_online_mode_title">Connect</string>
<!-- Bluetooth settings. Connection options screen. The summary of the online mode checkbox. This describes what the setting does in the context of the screen. -->
@@ -1045,7 +1051,7 @@
<!-- Bluetooth settings. Connection options screen. The title of the header that is above all of the profiles. -->
<string name="bluetooth_device_advanced_profile_header_title">Profiles</string>
<!-- Bluetooth settings. Connection options screen. Title for option to rename the device. [CHAR LIMIT=30] -->
<string name="bluetooth_device_advanced_rename_device">Rename device</string>
<string name="bluetooth_device_advanced_rename_device">Rename</string>
<!-- Bluetooth settings. Connection options screen. Title for checkbox to enable incoming file transfers [CHAR LIMIT=30] -->
<string name="bluetooth_device_advanced_enable_opp_title">Allow incoming file transfers</string>
<!-- Bluetooth settings. Connection options screen. The summary for the A2DP checkbox preference when A2DP is connected. -->

View File

@@ -15,12 +15,8 @@
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="title"
android:order="10"
android:title="@string/bluetooth_device_advanced_device_actions_title" />
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/bluetooth_device_advanced_title">
<EditTextPreference
android:key="rename_device"

View File

@@ -138,14 +138,10 @@ final class A2dpProfile implements LocalBluetoothProfile {
return ORDINAL;
}
public int getNameResource() {
public int getNameResource(BluetoothDevice device) {
return R.string.bluetooth_profile_a2dp;
}
public int getDisconnectResource(BluetoothDevice device) {
return R.string.bluetooth_disconnect_a2dp_profile;
}
public int getSummaryResourceForDevice(BluetoothDevice device) {
int state = mService.getConnectionState(device);
switch (state) {

View File

@@ -65,7 +65,9 @@ public final class BluetoothDevicePreference extends Preference implements
mCachedDevice = cachedDevice;
setWidgetLayoutResource(R.layout.preference_bluetooth);
if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
setWidgetLayoutResource(R.layout.preference_bluetooth);
}
mCachedDevice.registerCallback(this);
@@ -98,7 +100,17 @@ public final class BluetoothDevicePreference extends Preference implements
*/
setTitle(mCachedDevice.getName());
setSummary(getConnectionSummary());
int summaryResId = getConnectionSummary();
if (summaryResId != 0) {
setSummary(summaryResId);
} else {
setSummary(null); // empty summary for unpaired devices
}
int iconResId = getBtClassDrawable();
if (iconResId != 0) {
setIcon(iconResId);
}
// Used to gray out the item
setEnabled(!mCachedDevice.isBusy());
@@ -114,40 +126,16 @@ public final class BluetoothDevicePreference extends Preference implements
setDependency("bt_checkbox");
}
if (mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails);
if (deviceDetails != null) {
deviceDetails.setOnClickListener(this);
deviceDetails.setTag(mCachedDevice);
deviceDetails.setAlpha(isEnabled() ? 255 : sDimAlpha);
}
}
super.onBindView(view);
ImageView btClass = (ImageView) view.findViewById(android.R.id.icon);
btClass.setImageResource(getBtClassDrawable());
btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
btClass.setVisibility(View.VISIBLE);
ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails);
if (mOnSettingsClickListener != null) {
deviceDetails.setOnClickListener(this);
deviceDetails.setTag(mCachedDevice);
deviceDetails.setAlpha(isEnabled() ? 255 : sDimAlpha);
} else { // Hide the settings icon and divider
deviceDetails.setVisibility(View.GONE);
View divider = 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 (LocalBluetoothProfile profile : mCachedDevice.getProfiles()) {
int iconResource = profile.getDrawableResource(mCachedDevice.getBtClass());
if (iconResource != 0) {
Drawable icon = getContext().getResources().getDrawable(iconResource);
inflater.inflate(R.layout.profile_icon_small, profilesGroup, true);
ImageView imageView =
(ImageView) profilesGroup.getChildAt(profilesGroup.getChildCount() - 1);
imageView.setImageDrawable(icon);
boolean profileEnabled = mCachedDevice.isConnectedProfile(profile);
imageView.setAlpha(profileEnabled ? 255 : sDimAlpha);
}
}
}
public void onClick(View v) {
@@ -224,22 +212,52 @@ public final class BluetoothDevicePreference extends Preference implements
private int getConnectionSummary() {
final CachedBluetoothDevice cachedDevice = mCachedDevice;
// if any profiles are connected or busy, return that status
boolean profileConnected = false; // at least one profile is connected
boolean a2dpNotConnected = false; // A2DP is preferred but not connected
boolean headsetNotConnected = false; // Headset is preferred but not connected
for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
int connectionStatus = cachedDevice.getProfileConnectionState(profile);
if (connectionStatus != BluetoothProfile.STATE_DISCONNECTED) {
return Utils.getConnectionStateSummary(connectionStatus);
switch (connectionStatus) {
case BluetoothProfile.STATE_CONNECTING:
case BluetoothProfile.STATE_DISCONNECTING:
return Utils.getConnectionStateSummary(connectionStatus);
case BluetoothProfile.STATE_CONNECTED:
profileConnected = true;
break;
case BluetoothProfile.STATE_DISCONNECTED:
if (profile.isProfileReady() && profile.isPreferred(cachedDevice.getDevice())) {
if (profile instanceof A2dpProfile) {
a2dpNotConnected = true;
} else if (profile instanceof HeadsetProfile) {
headsetNotConnected = true;
}
}
break;
}
}
if (profileConnected) {
if (a2dpNotConnected && headsetNotConnected) {
return R.string.bluetooth_connected_no_headset_no_a2dp;
} else if (a2dpNotConnected) {
return R.string.bluetooth_connected_no_a2dp;
} else if (headsetNotConnected) {
return R.string.bluetooth_connected_no_headset;
} else {
return R.string.bluetooth_connected;
}
}
switch (cachedDevice.getBondState()) {
case BluetoothDevice.BOND_BONDED:
return R.string.bluetooth_paired;
case BluetoothDevice.BOND_BONDING:
return R.string.bluetooth_pairing;
case BluetoothDevice.BOND_BONDED:
case BluetoothDevice.BOND_NONE:
return R.string.bluetooth_not_connected;
default:
return 0;
}

View File

@@ -225,7 +225,7 @@ final class BluetoothEventManager {
Log.w(TAG, "received ACTION_DISAPPEARED for an unknown device: " + device);
return;
}
if (mDeviceManager.onDeviceDisappeared(cachedDevice)) {
if (CachedBluetoothDeviceManager.onDeviceDisappeared(cachedDevice)) {
synchronized (mCallbacks) {
for (BluetoothCallback callback : mCallbacks) {
callback.onDeviceDeleted(cachedDevice);
@@ -283,7 +283,7 @@ final class BluetoothEventManager {
// if the device is undocked, remove it from the list as well
if (!device.getAddress().equals(getDockedDeviceAddress(context))) {
mDeviceManager.onDeviceDisappeared(cachedDevice);
cachedDevice.setVisible(false);
}
}
int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
@@ -361,7 +361,7 @@ final class BluetoothEventManager {
if (device != null && device.getBondState() == BluetoothDevice.BOND_NONE) {
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice != null) {
mDeviceManager.onDeviceDisappeared(cachedDevice);
cachedDevice.setVisible(false);
}
}
}

View File

@@ -1,96 +0,0 @@
/*
* 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 android.content.Context;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import com.android.settings.R;
/**
* BluetoothProfilePreference is the preference type used to display each profile for a
* particular bluetooth device.
*/
final class BluetoothProfilePreference extends Preference implements OnClickListener {
// private static final String TAG = "BluetoothProfilePreference";
private Drawable mProfileDrawable;
private boolean mExpanded;
private ImageView mProfileExpandView;
private final LocalBluetoothProfile mProfile;
private OnClickListener mOnExpandClickListener;
BluetoothProfilePreference(Context context, LocalBluetoothProfile profile) {
super(context);
mProfile = profile;
setWidgetLayoutResource(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(android.R.id.icon);
btProfile.setImageDrawable(mProfileDrawable);
mProfileExpandView = (ImageView) view.findViewById(R.id.profileExpand);
if (mProfile.isAutoConnectable()) {
mProfileExpandView.setOnClickListener(this);
mProfileExpandView.setTag(mProfile);
mProfileExpandView.setImageResource(mExpanded
? com.android.internal.R.drawable.expander_close_holo_dark
: com.android.internal.R.drawable.expander_open_holo_dark);
} else {
mProfileExpandView.setVisibility(View.GONE);
}
}
public void onClick(View v) {
if (v == mProfileExpandView) {
if (mOnExpandClickListener != null) {
setExpanded(!mExpanded);
mOnExpandClickListener.onClick(v);
}
}
}
}

View File

@@ -142,9 +142,11 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
@Override
public void onResume() {
// resume BluetoothEnabler before calling super.onResume() so we don't get
// any onDeviceAdded() callbacks before setting up view in updateContent()
mBluetoothEnabler.resume();
super.onResume();
mBluetoothEnabler.resume();
if (mDiscoverableEnabler != null) {
mDiscoverableEnabler.resume();
}
@@ -246,6 +248,11 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
mMyDevicePreference = new Preference(getActivity());
}
mMyDevicePreference.setTitle(mLocalAdapter.getName());
if (getResources().getBoolean(com.android.internal.R.bool.config_voice_capable)) {
mMyDevicePreference.setIcon(R.drawable.ic_bt_cellphone); // for phones
} else {
mMyDevicePreference.setIcon(R.drawable.ic_bt_laptop); // for tablets, etc.
}
mMyDevicePreference.setPersistent(false);
mMyDevicePreference.setEnabled(true);
preferenceScreen.addPreference(mMyDevicePreference);
@@ -337,13 +344,12 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
if (v.getTag() instanceof CachedBluetoothDevice) {
CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
Preference pref = new Preference(getActivity());
pref.setTitle(device.getName());
pref.setFragment(DeviceProfilesSettings.class.getName());
pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
device.getDevice());
((PreferenceActivity) getActivity()).onPreferenceStartFragment(
BluetoothSettings.this, pref);
Bundle args = new Bundle(1);
args.putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, device.getDevice());
((PreferenceActivity) getActivity()).startPreferencePanel(
DeviceProfilesSettings.class.getName(), args,
R.string.bluetooth_device_advanced_title, null, null, 0);
} else {
Log.w(TAG, "onClick() called for other View: " + v); // TODO remove
}

View File

@@ -53,7 +53,6 @@ final class BluetoothVisibilityTimeoutFragment extends DialogFragment
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(R.string.bluetooth_visibility_timeout)
.setSingleChoiceItems(R.array.bluetooth_visibility_timeout_entries,
mDiscoverableEnabler.getDiscoverableTimeoutIndex(), this)

View File

@@ -26,7 +26,6 @@ import java.util.List;
* CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
*/
final class CachedBluetoothDeviceManager {
// private static final String TAG = "CachedBluetoothDeviceManager";
private final List<CachedBluetoothDevice> mCachedDevices =
new ArrayList<CachedBluetoothDevice>();
@@ -35,20 +34,9 @@ final class CachedBluetoothDeviceManager {
return new ArrayList<CachedBluetoothDevice>(mCachedDevices);
}
public boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) {
public static boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) {
cachedDevice.setVisible(false);
return checkForDeviceRemoval(cachedDevice);
}
private boolean checkForDeviceRemoval(
CachedBluetoothDevice cachedDevice) {
if (cachedDevice.getBondState() == BluetoothDevice.BOND_NONE &&
!cachedDevice.isVisible()) {
// If device isn't paired, remove it altogether
mCachedDevices.remove(cachedDevice);
return true; // dispatch device deleted
}
return false;
return cachedDevice.getBondState() == BluetoothDevice.BOND_NONE;
}
public void onDeviceNameUpdated(BluetoothDevice device) {
@@ -120,7 +108,6 @@ final class CachedBluetoothDeviceManager {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
cachedDevice.setVisible(false);
checkForDeviceRemoval(cachedDevice);
}
}

View File

@@ -128,7 +128,6 @@ public abstract class DeviceListPreferenceFragment extends
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
if (KEY_BT_SCAN.equals(preference.getKey())) {
mLocalAdapter.startScanning(true);
return true;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -46,15 +47,12 @@ import java.util.HashMap;
* (or disconnected).
*/
public final class DeviceProfilesSettings extends SettingsPreferenceFragment
implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener,
View.OnClickListener {
implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
private static final String TAG = "DeviceProfilesSettings";
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";
public static final String EXTRA_DEVICE = "device";
private RenameEditTextPreference mRenameDeviceNamePref;
@@ -69,6 +67,8 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
= new HashMap<LocalBluetoothProfile, CheckBoxPreference>();
private AlertDialog mDisconnectDialog;
private boolean mProfileGroupIsRemoved;
private class RenameEditTextPreference implements TextWatcher{
public void afterTextChanged(Editable s) {
Dialog d = mDeviceNamePref.getDialog();
@@ -87,6 +87,7 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
// not used
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -126,11 +127,6 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
mDeviceNamePref.setText(deviceName);
mDeviceNamePref.setOnPreferenceChangeListener(this);
// Set the title of the screen
findPreference(KEY_TITLE).setTitle(
getString(R.string.bluetooth_device_advanced_title,
deviceName));
// Add a preference for each profile
addPreferencesForProfiles();
}
@@ -183,6 +179,18 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
Preference pref = createProfilePreference(profile);
mProfileContainer.addPreference(pref);
}
showOrHideProfileGroup();
}
private void showOrHideProfileGroup() {
int numProfiles = mProfileContainer.getPreferenceCount();
if (!mProfileGroupIsRemoved && numProfiles == 0) {
getPreferenceScreen().removePreference(mProfileContainer);
mProfileGroupIsRemoved = true;
} else if (mProfileGroupIsRemoved && numProfiles != 0) {
getPreferenceScreen().addPreference(mProfileContainer);
mProfileGroupIsRemoved = false;
}
}
/**
@@ -193,18 +201,17 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
* @return A preference that allows the user to choose whether this profile
* will be connected to.
*/
private Preference createProfilePreference(LocalBluetoothProfile profile) {
BluetoothProfilePreference pref = new BluetoothProfilePreference(getActivity(), profile);
private CheckBoxPreference createProfilePreference(LocalBluetoothProfile profile) {
CheckBoxPreference pref = new CheckBoxPreference(getActivity());
pref.setKey(profile.toString());
pref.setTitle(profile.getNameResource());
pref.setExpanded(false);
pref.setTitle(profile.getNameResource(mCachedDevice.getDevice()));
pref.setPersistent(false);
pref.setOrder(getProfilePreferenceIndex(profile.getOrdinal()));
pref.setOnExpandClickListener(this);
pref.setOnPreferenceChangeListener(this);
int iconResource = profile.getDrawableResource(mCachedDevice.getBtClass());
if (iconResource != 0) {
pref.setProfileDrawable(getResources().getDrawable(iconResource));
pref.setIcon(getResources().getDrawable(iconResource));
}
/**
@@ -220,10 +227,7 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
@Override
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
String key = preference.getKey();
if (preference instanceof BluetoothProfilePreference) {
onProfileClicked(mProfileManager.getProfileByName(key));
return true;
} else if (key.equals(KEY_UNPAIR)) {
if (key.equals(KEY_UNPAIR)) {
unpairDevice();
finish();
return true;
@@ -236,11 +240,9 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
if (preference == mDeviceNamePref) {
mCachedDevice.setName((String) newValue);
} else if (preference instanceof CheckBoxPreference) {
boolean autoConnect = (Boolean) newValue;
LocalBluetoothProfile prof = getProfileOf(preference);
prof.setPreferred(mCachedDevice.getDevice(),
autoConnect);
return true;
onProfileClicked(prof);
return false; // checkbox will update from onDeviceAttributesChanged() callback
} else {
return false;
}
@@ -258,6 +260,7 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
if (isConnected) {
askDisconnect(getActivity(), profile);
} else {
profile.setPreferred(device, true);
mCachedDevice.connectProfile(profile);
}
}
@@ -270,22 +273,23 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
if (TextUtils.isEmpty(name)) {
name = context.getString(R.string.bluetooth_device);
}
int disconnectMessage = profile.getDisconnectResource(device.getDevice());
if (disconnectMessage == 0) {
Log.w(TAG, "askDisconnect: unexpected profile " + profile);
disconnectMessage = R.string.bluetooth_disconnect_blank;
}
String message = context.getString(disconnectMessage, name);
String profileName = context.getString(profile.getNameResource(device.getDevice()));
String title = context.getString(R.string.bluetooth_disable_profile_title);
String message = context.getString(R.string.bluetooth_disable_profile_message,
profileName, name);
DialogInterface.OnClickListener disconnectListener =
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
device.disconnect(profile);
profile.setPreferred(device.getDevice(), false);
}
};
mDisconnectDialog = Utils.showDisconnectDialog(context,
mDisconnectDialog, disconnectListener, name, message);
mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
}
public void onDeviceAttributesChanged() {
@@ -294,15 +298,6 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
private void refresh() {
String deviceName = mCachedDevice.getName();
// TODO: figure out how to update "bread crumb" title in action bar
// FragmentTransaction transaction = getFragmentManager().openTransaction();
// transaction.setBreadCrumbTitle(deviceName);
// transaction.commit();
findPreference(KEY_TITLE).setTitle(getString(
R.string.bluetooth_device_advanced_title,
deviceName));
mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
mDeviceNamePref.setSummary(deviceName);
mDeviceNamePref.setText(deviceName);
@@ -311,7 +306,7 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
private void refreshProfiles() {
for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
Preference profilePref = findPreference(profile.toString());
CheckBoxPreference profilePref = (CheckBoxPreference)findPreference(profile.toString());
if (profilePref == null) {
profilePref = createProfilePreference(profile);
mProfileContainer.addPreference(profilePref);
@@ -326,15 +321,18 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
mProfileContainer.removePreference(profilePref);
}
}
showOrHideProfileGroup();
}
private void refreshProfilePreference(Preference profilePref, LocalBluetoothProfile profile) {
private void refreshProfilePreference(CheckBoxPreference profilePref,
LocalBluetoothProfile profile) {
BluetoothDevice device = mCachedDevice.getDevice();
/*
* Gray out checkbox while connecting and disconnecting
*/
profilePref.setEnabled(!mCachedDevice.isBusy());
profilePref.setChecked(mCachedDevice.isConnectedProfile(profile));
profilePref.setSummary(profile.getSummaryResourceForDevice(device));
}
@@ -352,32 +350,6 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
}
}
public void onClick(View v) {
if (v.getTag() instanceof LocalBluetoothProfile) {
LocalBluetoothProfile prof = (LocalBluetoothProfile) v.getTag();
CheckBoxPreference autoConnectPref = mAutoConnectPrefs.get(prof);
if (autoConnectPref == null) {
autoConnectPref = new CheckBoxPreference(getActivity());
autoConnectPref.setLayoutResource(com.android.internal.R.layout.preference_child);
autoConnectPref.setKey(prof.toString());
autoConnectPref.setTitle(R.string.bluetooth_auto_connect);
autoConnectPref.setOrder(getProfilePreferenceIndex(prof.getOrdinal()) + 1);
autoConnectPref.setChecked(getAutoConnect(prof));
autoConnectPref.setOnPreferenceChangeListener(this);
mAutoConnectPrefs.put(prof, autoConnectPref);
}
BluetoothProfilePreference profilePref =
(BluetoothProfilePreference) findPreference(prof.toString());
if (profilePref != null) {
if (profilePref.isExpanded()) {
mProfileContainer.addPreference(autoConnectPref);
} else {
mProfileContainer.removePreference(autoConnectPref);
}
}
}
}
private int getProfilePreferenceIndex(int profIndex) {
return mProfileContainer.getOrder() + profIndex * 10;
}
@@ -386,18 +358,6 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment
mCachedDevice.unpair();
}
/*
private void setIncomingFileTransfersAllowed(boolean allow) {
// TODO: make an IPC call into BluetoothOpp to update
Log.d(TAG, "Set allow incoming = " + allow);
}
private boolean isIncomingFileTransfersAllowed() {
// TODO: get this value from BluetoothOpp ???
return true;
}
*/
private boolean getAutoConnect(LocalBluetoothProfile prof) {
return prof.isPreferred(mCachedDevice.getDevice());
}

View File

@@ -170,14 +170,10 @@ final class HeadsetProfile implements LocalBluetoothProfile {
return ORDINAL;
}
public int getNameResource() {
public int getNameResource(BluetoothDevice device) {
return R.string.bluetooth_profile_headset;
}
public int getDisconnectResource(BluetoothDevice device) {
return R.string.bluetooth_disconnect_headset_profile;
}
public int getSummaryResourceForDevice(BluetoothDevice device) {
int state = mService.getConnectionState(device);
switch (state) {

View File

@@ -112,14 +112,11 @@ final class HidProfile implements LocalBluetoothProfile {
return ORDINAL;
}
public int getNameResource() {
public int getNameResource(BluetoothDevice device) {
// TODO: distinguish between keyboard and mouse?
return R.string.bluetooth_profile_hid;
}
public int getDisconnectResource(BluetoothDevice device) {
return R.string.bluetooth_disconnect_hid_profile;
}
public int getSummaryResourceForDevice(BluetoothDevice device) {
int state = mService.getConnectionState(device);
switch (state) {

View File

@@ -54,15 +54,9 @@ interface LocalBluetoothProfile {
/**
* Returns the string resource ID for the localized name for this profile.
* @param device the Bluetooth device (to distinguish between PAN roles)
*/
int getNameResource();
/**
* Returns the string resource ID for the disconnect confirmation text
* for this profile.
* @param device
*/
int getDisconnectResource(BluetoothDevice device);
int getNameResource(BluetoothDevice device);
/**
* Returns the string resource ID for the summary text for this profile

View File

@@ -75,14 +75,10 @@ final class OppProfile implements LocalBluetoothProfile {
return ORDINAL;
}
public int getNameResource() {
public int getNameResource(BluetoothDevice device) {
return R.string.bluetooth_profile_opp;
}
public int getDisconnectResource(BluetoothDevice device) {
return 0; // user must use notification to disconnect OPP transfer.
}
public int getSummaryResourceForDevice(BluetoothDevice device) {
return 0; // OPP profile not displayed in UI
}

View File

@@ -112,15 +112,11 @@ final class PanProfile implements LocalBluetoothProfile {
return ORDINAL;
}
public int getNameResource() {
return R.string.bluetooth_profile_pan;
}
public int getDisconnectResource(BluetoothDevice device) {
public int getNameResource(BluetoothDevice device) {
if (isLocalRoleNap(device)) {
return R.string.bluetooth_disconnect_pan_nap_profile;
return R.string.bluetooth_profile_pan_nap;
} else {
return R.string.bluetooth_disconnect_pan_user_profile;
return R.string.bluetooth_profile_pan;
}
}