Bluetooth: Update Settings.apk to match BT API change.

Split BluetoothDevice into BluetoothDevice and BluetoothAdapter.

BluetoothAdapter: Represents the local BT adapter. Operations on the local
                  adapter (start a scan, etc).
BluetoothDevice: Represents a remote BT device. Operations on remote devices
                 (pair, connect, etc).
This commit is contained in:
Nick Pelly
2009-08-14 18:43:18 -07:00
parent 5eb32e86a2
commit d63c011225
16 changed files with 518 additions and 507 deletions

View File

@@ -28,20 +28,20 @@ import android.widget.ImageView;
* BluetoothDevicePreference is the preference type used to display each remote * BluetoothDevicePreference is the preference type used to display each remote
* Bluetooth device in the Bluetooth Settings screen. * Bluetooth device in the Bluetooth Settings screen.
*/ */
public class BluetoothDevicePreference extends Preference implements LocalBluetoothDevice.Callback { public class BluetoothDevicePreference extends Preference implements CachedBluetoothDevice.Callback {
private static final String TAG = "BluetoothDevicePreference"; private static final String TAG = "BluetoothDevicePreference";
private static int sDimAlpha = Integer.MIN_VALUE; private static int sDimAlpha = Integer.MIN_VALUE;
private LocalBluetoothDevice mLocalDevice; private CachedBluetoothDevice mCachedDevice;
/** /**
* Cached local copy of whether the device is busy. This is only updated * Cached local copy of whether the device is busy. This is only updated
* from {@link #onDeviceAttributesChanged(LocalBluetoothDevice)}. * from {@link #onDeviceAttributesChanged(CachedBluetoothDevice)}.
*/ */
private boolean mIsBusy; private boolean mIsBusy;
public BluetoothDevicePreference(Context context, LocalBluetoothDevice localDevice) { public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice) {
super(context); super(context);
if (sDimAlpha == Integer.MIN_VALUE) { if (sDimAlpha == Integer.MIN_VALUE) {
@@ -50,43 +50,43 @@ public class BluetoothDevicePreference extends Preference implements LocalBlueto
sDimAlpha = (int) (outValue.getFloat() * 255); sDimAlpha = (int) (outValue.getFloat() * 255);
} }
mLocalDevice = localDevice; mCachedDevice = cachedDevice;
setLayoutResource(R.layout.preference_bluetooth); setLayoutResource(R.layout.preference_bluetooth);
localDevice.registerCallback(this); cachedDevice.registerCallback(this);
onDeviceAttributesChanged(localDevice); onDeviceAttributesChanged(cachedDevice);
} }
public LocalBluetoothDevice getDevice() { public CachedBluetoothDevice getCachedDevice() {
return mLocalDevice; return mCachedDevice;
} }
@Override @Override
protected void onPrepareForRemoval() { protected void onPrepareForRemoval() {
super.onPrepareForRemoval(); super.onPrepareForRemoval();
mLocalDevice.unregisterCallback(this); mCachedDevice.unregisterCallback(this);
} }
public void onDeviceAttributesChanged(LocalBluetoothDevice device) { public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {
/* /*
* The preference framework takes care of making sure the value has * The preference framework takes care of making sure the value has
* changed before proceeding. * changed before proceeding.
*/ */
setTitle(mLocalDevice.getName()); setTitle(mCachedDevice.getName());
/* /*
* TODO: Showed "Paired" even though it was "Connected". This may be * TODO: Showed "Paired" even though it was "Connected". This may be
* related to BluetoothHeadset not bound to the actual * related to BluetoothHeadset not bound to the actual
* BluetoothHeadsetService when we got here. * BluetoothHeadsetService when we got here.
*/ */
setSummary(mLocalDevice.getSummary()); setSummary(mCachedDevice.getSummary());
// Used to gray out the item // Used to gray out the item
mIsBusy = mLocalDevice.isBusy(); mIsBusy = mCachedDevice.isBusy();
// Data has changed // Data has changed
notifyChanged(); notifyChanged();
@@ -110,7 +110,7 @@ public class BluetoothDevicePreference extends Preference implements LocalBlueto
super.onBindView(view); super.onBindView(view);
ImageView btClass = (ImageView) view.findViewById(R.id.btClass); ImageView btClass = (ImageView) view.findViewById(R.id.btClass);
btClass.setImageResource(mLocalDevice.getBtClassDrawable()); btClass.setImageResource(mCachedDevice.getBtClassDrawable());
btClass.setAlpha(isEnabled() ? 255 : sDimAlpha); btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
} }
@@ -121,7 +121,7 @@ public class BluetoothDevicePreference extends Preference implements LocalBlueto
return 1; return 1;
} }
return mLocalDevice.compareTo(((BluetoothDevicePreference) another).mLocalDevice); return mCachedDevice.compareTo(((BluetoothDevicePreference) another).mCachedDevice);
} }
} }

View File

@@ -18,7 +18,7 @@ package com.android.settings.bluetooth;
import com.android.settings.R; import com.android.settings.R;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothError; import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@@ -93,7 +93,7 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
mContext.registerReceiver(mReceiver, filter); mContext.registerReceiver(mReceiver, filter);
mCheckBoxPreference.setOnPreferenceChangeListener(this); mCheckBoxPreference.setOnPreferenceChangeListener(this);
handleModeChanged(mLocalManager.getBluetoothManager().getScanMode()); handleModeChanged(mLocalManager.getBluetoothAdapter().getScanMode());
} }
public void pause() { public void pause() {
@@ -114,7 +114,7 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
} }
private void setEnabled(final boolean enable) { private void setEnabled(final boolean enable) {
BluetoothDevice manager = mLocalManager.getBluetoothManager(); BluetoothAdapter manager = mLocalManager.getBluetoothAdapter();
if (enable) { if (enable) {
@@ -127,9 +127,9 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
long endTimestamp = System.currentTimeMillis() + timeout * 1000; long endTimestamp = System.currentTimeMillis() + timeout * 1000;
persistDiscoverableEndTimestamp(endTimestamp); persistDiscoverableEndTimestamp(endTimestamp);
manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE); manager.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
} else { } else {
manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE); manager.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
} }
} }
@@ -149,7 +149,7 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
} }
private void handleModeChanged(int mode) { private void handleModeChanged(int mode) {
if (mode == BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
mCheckBoxPreference.setChecked(true); mCheckBoxPreference.setChecked(true);
updateCountdownSummary(); updateCountdownSummary();
@@ -159,8 +159,8 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
} }
private void updateCountdownSummary() { private void updateCountdownSummary() {
int mode = mLocalManager.getBluetoothManager().getScanMode(); int mode = mLocalManager.getBluetoothAdapter().getScanMode();
if (mode != BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { if (mode != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
return; return;
} }

View File

@@ -18,7 +18,7 @@ package com.android.settings.bluetooth;
import com.android.settings.R; import com.android.settings.R;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothError; import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@@ -76,8 +76,8 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
int state = mLocalManager.getBluetoothState(); int state = mLocalManager.getBluetoothState();
// This is the widget enabled state, not the preference toggled state // This is the widget enabled state, not the preference toggled state
mCheckBoxPreference.setEnabled(state == BluetoothDevice.BLUETOOTH_STATE_ON || mCheckBoxPreference.setEnabled(state == BluetoothAdapter.BLUETOOTH_STATE_ON ||
state == BluetoothDevice.BLUETOOTH_STATE_OFF); state == BluetoothAdapter.BLUETOOTH_STATE_OFF);
// BT state is not a sticky broadcast, so set it manually // BT state is not a sticky broadcast, so set it manually
handleStateChanged(state); handleStateChanged(state);
@@ -112,18 +112,18 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
private void handleStateChanged(int state) { private void handleStateChanged(int state) {
if (state == BluetoothDevice.BLUETOOTH_STATE_OFF || if (state == BluetoothAdapter.BLUETOOTH_STATE_OFF ||
state == BluetoothDevice.BLUETOOTH_STATE_ON) { state == BluetoothAdapter.BLUETOOTH_STATE_ON) {
mCheckBoxPreference.setChecked(state == BluetoothDevice.BLUETOOTH_STATE_ON); mCheckBoxPreference.setChecked(state == BluetoothAdapter.BLUETOOTH_STATE_ON);
mCheckBoxPreference.setSummary(state == BluetoothDevice.BLUETOOTH_STATE_OFF ? mCheckBoxPreference.setSummary(state == BluetoothAdapter.BLUETOOTH_STATE_OFF ?
mOriginalSummary : mOriginalSummary :
null); null);
mCheckBoxPreference.setEnabled(isEnabledByDependency()); mCheckBoxPreference.setEnabled(isEnabledByDependency());
} else if (state == BluetoothDevice.BLUETOOTH_STATE_TURNING_ON || } else if (state == BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON ||
state == BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) { state == BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF) {
mCheckBoxPreference.setSummary(state == BluetoothDevice.BLUETOOTH_STATE_TURNING_ON mCheckBoxPreference.setSummary(state == BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON
? R.string.wifi_starting ? R.string.wifi_starting
: R.string.wifi_stopping); : R.string.wifi_stopping);

View File

@@ -49,7 +49,7 @@ public class BluetoothEventRedirector {
} }
String action = intent.getAction(); String action = intent.getAction();
String address = intent.getStringExtra(BluetoothIntent.ADDRESS); BluetoothDevice device = intent.getParcelableExtra(BluetoothIntent.DEVICE);
if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) { if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE, int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
@@ -65,23 +65,23 @@ public class BluetoothEventRedirector {
short rssi = intent.getShortExtra(BluetoothIntent.RSSI, Short.MIN_VALUE); short rssi = intent.getShortExtra(BluetoothIntent.RSSI, Short.MIN_VALUE);
int btClass = intent.getIntExtra(BluetoothIntent.CLASS, BluetoothClass.ERROR); int btClass = intent.getIntExtra(BluetoothIntent.CLASS, BluetoothClass.ERROR);
String name = intent.getStringExtra(BluetoothIntent.NAME); String name = intent.getStringExtra(BluetoothIntent.NAME);
mManager.getLocalDeviceManager().onDeviceAppeared(address, rssi, btClass, name); mManager.getCachedDeviceManager().onDeviceAppeared(device, rssi, btClass, name);
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION)) { } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION)) {
mManager.getLocalDeviceManager().onDeviceDisappeared(address); mManager.getCachedDeviceManager().onDeviceDisappeared(device);
} else if (action.equals(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION)) { } else if (action.equals(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION)) {
mManager.getLocalDeviceManager().onDeviceNameUpdated(address); mManager.getCachedDeviceManager().onDeviceNameUpdated(device);
} else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) { } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE, int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
BluetoothError.ERROR); BluetoothError.ERROR);
mManager.getLocalDeviceManager().onBondingStateChanged(address, bondState); mManager.getCachedDeviceManager().onBondingStateChanged(device, bondState);
if (bondState == BluetoothDevice.BOND_NOT_BONDED) { if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
int reason = intent.getIntExtra(BluetoothIntent.REASON, BluetoothError.ERROR); int reason = intent.getIntExtra(BluetoothIntent.REASON, BluetoothError.ERROR);
if (reason == BluetoothDevice.UNBOND_REASON_AUTH_REJECTED || if (reason == BluetoothDevice.UNBOND_REASON_AUTH_REJECTED ||
reason == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN) { reason == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN) {
mManager.getLocalDeviceManager().onBondingError(address, reason); mManager.getCachedDeviceManager().onBondingError(device, reason);
} }
} }
@@ -93,7 +93,7 @@ public class BluetoothEventRedirector {
Log.i(TAG, "Failed to connect BT headset"); Log.i(TAG, "Failed to connect BT headset");
} }
mManager.getLocalDeviceManager().onProfileStateChanged(address, mManager.getCachedDeviceManager().onProfileStateChanged(device,
Profile.HEADSET, newState); Profile.HEADSET, newState);
} else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) { } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
@@ -104,11 +104,11 @@ public class BluetoothEventRedirector {
Log.i(TAG, "Failed to connect BT A2DP"); Log.i(TAG, "Failed to connect BT A2DP");
} }
mManager.getLocalDeviceManager().onProfileStateChanged(address, mManager.getCachedDeviceManager().onProfileStateChanged(device,
Profile.A2DP, newState); Profile.A2DP, newState);
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) { } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) {
mManager.getLocalDeviceManager().onBtClassChanged(address); mManager.getCachedDeviceManager().onBtClassChanged(device);
} }
} }

View File

@@ -18,7 +18,8 @@ package com.android.settings.bluetooth;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothError; import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@@ -50,7 +51,7 @@ public class BluetoothNamePreference extends EditTextPreference implements TextW
setSummaryToName(); setSummaryToName();
} else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) && } else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) &&
(intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE, (intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
BluetoothError.ERROR) == BluetoothDevice.BLUETOOTH_STATE_ON)) { BluetoothError.ERROR) == BluetoothAdapter.BLUETOOTH_STATE_ON)) {
setSummaryToName(); setSummaryToName();
} }
} }
@@ -91,16 +92,16 @@ public class BluetoothNamePreference extends EditTextPreference implements TextW
} }
private void setSummaryToName() { private void setSummaryToName() {
BluetoothDevice manager = mLocalManager.getBluetoothManager(); BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
if (manager.isEnabled()) { if (adapter.isEnabled()) {
setSummary(manager.getName()); setSummary(adapter.getName());
} }
} }
@Override @Override
protected boolean persistString(String value) { protected boolean persistString(String value) {
BluetoothDevice manager = mLocalManager.getBluetoothManager(); BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
manager.setName(value); adapter.setName(value);
return true; return true;
} }
@@ -111,7 +112,7 @@ public class BluetoothNamePreference extends EditTextPreference implements TextW
// The dialog should be created by now // The dialog should be created by now
EditText et = getEditText(); EditText et = getEditText();
if (et != null) { if (et != null) {
et.setText(mLocalManager.getBluetoothManager().getName()); et.setText(mLocalManager.getBluetoothAdapter().getName());
} }
} }

View File

@@ -51,7 +51,7 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
private final int BLUETOOTH_PIN_MAX_LENGTH = 16; private final int BLUETOOTH_PIN_MAX_LENGTH = 16;
private final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6; private final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6;
private LocalBluetoothManager mLocalManager; private LocalBluetoothManager mLocalManager;
private String mAddress; private BluetoothDevice mDevice;
private int mType; private int mType;
private int mConfirmationPasskey; private int mConfirmationPasskey;
private EditText mPairingView; private EditText mPairingView;
@@ -67,8 +67,8 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
return; return;
} }
String address = intent.getStringExtra(BluetoothIntent.ADDRESS); BluetoothDevice device = intent.getParcelableExtra(BluetoothIntent.DEVICE);
if (address == null || address.equals(mAddress)) { if (device == null || device.equals(mDevice)) {
onReceivedPairingCanceled(); onReceivedPairingCanceled();
} }
} }
@@ -88,7 +88,7 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
} }
mLocalManager = LocalBluetoothManager.getInstance(this); mLocalManager = LocalBluetoothManager.getInstance(this);
mAddress = intent.getStringExtra(BluetoothIntent.ADDRESS); mDevice = intent.getParcelableExtra(BluetoothIntent.DEVICE);
mType = intent.getIntExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothClass.ERROR); mType = intent.getIntExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothClass.ERROR);
if (mType == BluetoothDevice.PAIRING_VARIANT_PIN) { if (mType == BluetoothDevice.PAIRING_VARIANT_PIN) {
createUserEntryDialog(); createUserEntryDialog();
@@ -131,7 +131,7 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
private View createView() { private View createView() {
View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null); View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
String name = mLocalManager.getLocalDeviceManager().getName(mAddress); String name = mLocalManager.getCachedDeviceManager().getName(mDevice);
TextView messageView = (TextView) view.findViewById(R.id.message); TextView messageView = (TextView) view.findViewById(R.id.message);
mPairingView = (EditText) view.findViewById(R.id.text); mPairingView = (EditText) view.findViewById(R.id.text);
mPairingView.addTextChangedListener(this); mPairingView.addTextChangedListener(this);
@@ -202,7 +202,7 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
TextView messageView = (TextView) findViewById(R.id.message); TextView messageView = (TextView) findViewById(R.id.message);
messageView.setText(getString(R.string.bluetooth_pairing_error_message, messageView.setText(getString(R.string.bluetooth_pairing_error_message,
mLocalManager.getLocalDeviceManager().getName(mAddress))); mDevice.getName()));
mPairingView.setVisibility(View.GONE); mPairingView.setVisibility(View.GONE);
mPairingView.clearFocus(); mPairingView.clearFocus();
@@ -220,20 +220,20 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
if (pinBytes == null) { if (pinBytes == null) {
return; return;
} }
mLocalManager.getBluetoothManager().setPin(mAddress, pinBytes); mDevice.setPin(pinBytes);
} else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY) { } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY) {
int passkey = Integer.getInteger(value); int passkey = Integer.getInteger(value);
mLocalManager.getBluetoothManager().setPasskey(mAddress, passkey); mDevice.setPasskey(passkey);
} else { } else {
mLocalManager.getBluetoothManager().setPairingConfirmation(mAddress, true); mDevice.setPairingConfirmation(true);
} }
} }
private void onCancel() { private void onCancel() {
if (mType == BluetoothDevice.PAIRING_VARIANT_CONFIRMATION) { if (mType == BluetoothDevice.PAIRING_VARIANT_CONFIRMATION) {
mLocalManager.getBluetoothManager().setPairingConfirmation(mAddress, false); mDevice.setPairingConfirmation(false);
} else { } else {
mLocalManager.getBluetoothManager().cancelBondProcess(mAddress); mDevice.cancelBondProcess();
} }
} }

View File

@@ -47,11 +47,12 @@ public class BluetoothPairingRequest extends BroadcastReceiver {
LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(context); LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(context);
String address = intent.getStringExtra(BluetoothIntent.ADDRESS); BluetoothDevice device =
intent.getParcelableExtra(BluetoothIntent.DEVICE);
int type = intent.getIntExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothClass.ERROR); int type = intent.getIntExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothClass.ERROR);
Intent pairingIntent = new Intent(); Intent pairingIntent = new Intent();
pairingIntent.setClass(context, BluetoothPairingDialog.class); pairingIntent.setClass(context, BluetoothPairingDialog.class);
pairingIntent.putExtra(BluetoothIntent.ADDRESS, address); pairingIntent.putExtra(BluetoothIntent.DEVICE, device);
pairingIntent.putExtra(BluetoothIntent.PAIRING_VARIANT, type); pairingIntent.putExtra(BluetoothIntent.PAIRING_VARIANT, type);
if (type == BluetoothDevice.PAIRING_VARIANT_CONFIRMATION) { if (type == BluetoothDevice.PAIRING_VARIANT_CONFIRMATION) {
int passkey = intent.getIntExtra(BluetoothIntent.PASSKEY, BluetoothClass.ERROR); int passkey = intent.getIntExtra(BluetoothIntent.PASSKEY, BluetoothClass.ERROR);
@@ -78,7 +79,7 @@ public class BluetoothPairingRequest extends BroadcastReceiver {
String name = intent.getStringExtra(BluetoothIntent.NAME); String name = intent.getStringExtra(BluetoothIntent.NAME);
if (TextUtils.isEmpty(name)) { if (TextUtils.isEmpty(name)) {
name = localManager.getLocalDeviceManager().getName(address); name = device.getName();
} }
notification.setLatestEventInfo(context, notification.setLatestEventInfo(context,

View File

@@ -22,7 +22,7 @@ import com.android.settings.R;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@@ -66,8 +66,8 @@ public class BluetoothSettings extends PreferenceActivity
private ProgressCategory mDeviceList; private ProgressCategory mDeviceList;
private WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap = private WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
new WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference>(); new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override @Override
@@ -116,7 +116,7 @@ public class BluetoothSettings extends PreferenceActivity
mNamePreference.resume(); mNamePreference.resume();
mLocalManager.registerCallback(this); mLocalManager.registerCallback(this);
mDeviceList.setProgress(mLocalManager.getBluetoothManager().isDiscovering()); mDeviceList.setProgress(mLocalManager.getBluetoothAdapter().isDiscovering());
mLocalManager.startScanning(false); mLocalManager.startScanning(false);
registerReceiver(mReceiver, registerReceiver(mReceiver,
@@ -140,9 +140,10 @@ public class BluetoothSettings extends PreferenceActivity
} }
private void addDevices() { private void addDevices() {
List<LocalBluetoothDevice> devices = mLocalManager.getLocalDeviceManager().getDevicesCopy(); List<CachedBluetoothDevice> cachedDevices =
for (LocalBluetoothDevice device : devices) { mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
onDeviceAdded(device); for (CachedBluetoothDevice cachedDevice : cachedDevices) {
onDeviceAdded(cachedDevice);
} }
} }
@@ -156,7 +157,7 @@ public class BluetoothSettings extends PreferenceActivity
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(MENU_SCAN).setEnabled(mLocalManager.getBluetoothManager().isEnabled()); menu.findItem(MENU_SCAN).setEnabled(mLocalManager.getBluetoothAdapter().isEnabled());
return true; return true;
} }
@@ -184,7 +185,7 @@ public class BluetoothSettings extends PreferenceActivity
if (preference instanceof BluetoothDevicePreference) { if (preference instanceof BluetoothDevicePreference) {
BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference; BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
btPreference.getDevice().onClicked(); btPreference.getCachedDevice().onClicked();
return true; return true;
} }
@@ -194,22 +195,22 @@ public class BluetoothSettings extends PreferenceActivity
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) { ContextMenuInfo menuInfo) {
LocalBluetoothDevice device = getDeviceFromMenuInfo(menuInfo); CachedBluetoothDevice cachedDevice = getDeviceFromMenuInfo(menuInfo);
if (device == null) return; if (cachedDevice == null) return;
device.onCreateContextMenu(menu); cachedDevice.onCreateContextMenu(menu);
} }
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
LocalBluetoothDevice device = getDeviceFromMenuInfo(item.getMenuInfo()); CachedBluetoothDevice cachedDevice = getDeviceFromMenuInfo(item.getMenuInfo());
if (device == null) return false; if (cachedDevice == null) return false;
device.onContextItemSelected(item); cachedDevice.onContextItemSelected(item);
return true; return true;
} }
private LocalBluetoothDevice getDeviceFromMenuInfo(ContextMenuInfo menuInfo) { private CachedBluetoothDevice getDeviceFromMenuInfo(ContextMenuInfo menuInfo) {
if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) { if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) {
return null; return null;
} }
@@ -221,26 +222,26 @@ public class BluetoothSettings extends PreferenceActivity
return null; return null;
} }
return ((BluetoothDevicePreference) pref).getDevice(); return ((BluetoothDevicePreference) pref).getCachedDevice();
} }
public void onDeviceAdded(LocalBluetoothDevice device) { public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
if (mDevicePreferenceMap.get(device) != null) { if (mDevicePreferenceMap.get(cachedDevice) != null) {
throw new IllegalStateException("Got onDeviceAdded, but device already exists"); throw new IllegalStateException("Got onDeviceAdded, but cachedDevice already exists");
} }
createDevicePreference(device); createDevicePreference(cachedDevice);
} }
private void createDevicePreference(LocalBluetoothDevice device) { private void createDevicePreference(CachedBluetoothDevice cachedDevice) {
BluetoothDevicePreference preference = new BluetoothDevicePreference(this, device); BluetoothDevicePreference preference = new BluetoothDevicePreference(this, cachedDevice);
mDeviceList.addPreference(preference); mDeviceList.addPreference(preference);
mDevicePreferenceMap.put(device, preference); mDevicePreferenceMap.put(cachedDevice, preference);
} }
public void onDeviceDeleted(LocalBluetoothDevice device) { public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
BluetoothDevicePreference preference = mDevicePreferenceMap.remove(device); BluetoothDevicePreference preference = mDevicePreferenceMap.remove(cachedDevice);
if (preference != null) { if (preference != null) {
mDeviceList.removePreference(preference); mDeviceList.removePreference(preference);
} }
@@ -253,9 +254,9 @@ public class BluetoothSettings extends PreferenceActivity
private void onBluetoothStateChanged(int bluetoothState) { private void onBluetoothStateChanged(int bluetoothState) {
// When bluetooth is enabled (and we are in the activity, which we are), // When bluetooth is enabled (and we are in the activity, which we are),
// we should start a scan // we should start a scan
if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON) { if (bluetoothState == BluetoothAdapter.BLUETOOTH_STATE_ON) {
mLocalManager.startScanning(false); mLocalManager.startScanning(false);
} else if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_OFF) { } else if (bluetoothState == BluetoothAdapter.BLUETOOTH_STATE_OFF) {
mDeviceList.setProgress(false); mDeviceList.setProgress(false);
} }
} }

View File

@@ -18,6 +18,7 @@ package com.android.settings.bluetooth;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@@ -40,13 +41,13 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
/** /**
* LocalBluetoothDevice represents a remote Bluetooth device. It contains * CachedBluetoothDevice represents a remote Bluetooth device. It contains
* attributes of the device (such as the address, name, RSSI, etc.) and * attributes of the device (such as the address, name, RSSI, etc.) and
* functionality that can be performed on the device (connect, pair, disconnect, * functionality that can be performed on the device (connect, pair, disconnect,
* etc.). * etc.).
*/ */
public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> { public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
private static final String TAG = "LocalBluetoothDevice"; private static final String TAG = "CachedBluetoothDevice";
private static final boolean D = LocalBluetoothManager.D; private static final boolean D = LocalBluetoothManager.D;
private static final boolean V = LocalBluetoothManager.V; private static final boolean V = LocalBluetoothManager.V;
@@ -55,7 +56,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3; private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4; private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
private final String mAddress; private final BluetoothDevice mDevice;
private String mName; private String mName;
private short mRssi; private short mRssi;
private int mBtClass = BluetoothClass.ERROR; private int mBtClass = BluetoothClass.ERROR;
@@ -84,15 +85,15 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
static class BluetoothJob { static class BluetoothJob {
final BluetoothCommand command; // CONNECT, DISCONNECT final BluetoothCommand command; // CONNECT, DISCONNECT
final LocalBluetoothDevice device; final CachedBluetoothDevice cachedDevice;
final Profile profile; // HEADSET, A2DP, etc final Profile profile; // HEADSET, A2DP, etc
// 0 means this command was not been sent to the bt framework. // 0 means this command was not been sent to the bt framework.
long timeSent; long timeSent;
public BluetoothJob(BluetoothCommand command, public BluetoothJob(BluetoothCommand command,
LocalBluetoothDevice device, Profile profile) { CachedBluetoothDevice cachedDevice, Profile profile) {
this.command = command; this.command = command;
this.device = device; this.cachedDevice = cachedDevice;
this.profile = profile; this.profile = profile;
this.timeSent = 0; this.timeSent = 0;
} }
@@ -101,7 +102,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(command.name()); sb.append(command.name());
sb.append(" Address:").append(device.mAddress); sb.append(" Address:").append(cachedDevice.mDevice);
sb.append(" Profile:").append(profile.name()); sb.append(" Profile:").append(profile.name());
sb.append(" TimeSent:"); sb.append(" TimeSent:");
if (timeSent == 0) { if (timeSent == 0) {
@@ -159,7 +160,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
if (job != null && job.command == BluetoothCommand.DISCONNECT) { if (job != null && job.command == BluetoothCommand.DISCONNECT) {
if (existingJob.timeSent == 0 if (existingJob.timeSent == 0
&& existingJob.command == BluetoothCommand.CONNECT && existingJob.command == BluetoothCommand.CONNECT
&& existingJob.device.mAddress.equals(job.device.mAddress) && existingJob.cachedDevice.mDevice.equals(job.cachedDevice.mDevice)
&& existingJob.profile == job.profile) { && existingJob.profile == job.profile) {
if (D) { if (D) {
Log.d(TAG, "Removed because of a pending disconnect. " + existingJob); Log.d(TAG, "Removed because of a pending disconnect. " + existingJob);
@@ -189,10 +190,10 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
job.timeSent = System.currentTimeMillis(); job.timeSent = System.currentTimeMillis();
switch (job.command) { switch (job.command) {
case CONNECT: case CONNECT:
successful = connectInt(job.device, job.profile); successful = connectInt(job.cachedDevice, job.profile);
break; break;
case DISCONNECT: case DISCONNECT:
successful = disconnectInt(job.device, job.profile); successful = disconnectInt(job.cachedDevice, job.profile);
break; break;
} }
@@ -230,12 +231,12 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
BluetoothJob job = workQueue.peek(); BluetoothJob job = workQueue.peek();
if (job == null) { if (job == null) {
return; return;
} else if (job.device.mAddress != mAddress) { } else if (job.cachedDevice.mDevice.equals(mDevice)) {
// This can happen in 2 cases: 1) BT device initiated pairing and // This can happen in 2 cases: 1) BT device initiated pairing and
// 2) disconnects of one headset that's triggered by connects of // 2) disconnects of one headset that's triggered by connects of
// another. // another.
if (D) { if (D) {
Log.d(TAG, "mAddresses:" + mAddress + " != head:" + job.toString()); Log.d(TAG, "mDevice:" + mDevice + " != head:" + job.toString());
} }
// Check to see if we need to remove the stale items from the queue // Check to see if we need to remove the stale items from the queue
@@ -281,14 +282,14 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
} }
} }
LocalBluetoothDevice(Context context, String address) { CachedBluetoothDevice(Context context, BluetoothDevice device) {
mLocalManager = LocalBluetoothManager.getInstance(context); mLocalManager = LocalBluetoothManager.getInstance(context);
if (mLocalManager == null) { if (mLocalManager == null) {
throw new IllegalStateException( throw new IllegalStateException(
"Cannot use LocalBluetoothDevice without Bluetooth hardware"); "Cannot use CachedBluetoothDevice without Bluetooth hardware");
} }
mAddress = address; mDevice = device;
fillData(); fillData();
} }
@@ -315,12 +316,13 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
queueCommand(new BluetoothJob(BluetoothCommand.DISCONNECT, this, profile)); queueCommand(new BluetoothJob(BluetoothCommand.DISCONNECT, this, profile));
} }
private boolean disconnectInt(LocalBluetoothDevice device, Profile profile) { private boolean disconnectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile); LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
int status = profileManager.getConnectionStatus(device.mAddress); int status = profileManager.getConnectionStatus(cachedDevice.mDevice);
if (SettingsBtStatus.isConnectionStatusConnected(status)) { if (SettingsBtStatus.isConnectionStatusConnected(status)) {
if (profileManager.disconnect(device.mAddress) == BluetoothDevice.RESULT_SUCCESS) { if (profileManager.disconnect(cachedDevice.mDevice) ==
BluetoothAdapter.RESULT_SUCCESS) {
return true; return true;
} }
} }
@@ -367,7 +369,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
for (Profile profile : mProfiles) { for (Profile profile : mProfiles) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile); LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
if (profileManager.isPreferred(mAddress)) { if (profileManager.isPreferred(mDevice)) {
hasAtLeastOnePreferredProfile = true; hasAtLeastOnePreferredProfile = true;
queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile)); queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
} }
@@ -387,7 +389,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
for (Profile profile : mProfiles) { for (Profile profile : mProfiles) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile); LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
profileManager.setPreferred(mAddress, true); profileManager.setPreferred(mDevice, true);
queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile)); queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
} }
} }
@@ -398,17 +400,17 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile)); queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
} }
private boolean connectInt(LocalBluetoothDevice device, Profile profile) { private boolean connectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
if (!device.ensurePaired()) return false; if (!cachedDevice.ensurePaired()) return false;
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile); LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
int status = profileManager.getConnectionStatus(device.mAddress); int status = profileManager.getConnectionStatus(cachedDevice.mDevice);
if (!SettingsBtStatus.isConnectionStatusConnected(status)) { if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
if (profileManager.connect(device.mAddress) == BluetoothDevice.RESULT_SUCCESS) { if (profileManager.connect(cachedDevice.mDevice) == BluetoothAdapter.RESULT_SUCCESS) {
return true; return true;
} }
Log.i(TAG, "Failed to connect " + profile.toString() + " to " + device.mName); Log.i(TAG, "Failed to connect " + profile.toString() + " to " + cachedDevice.mName);
} }
Log.i(TAG, "Not connected"); Log.i(TAG, "Not connected");
return false; return false;
@@ -418,7 +420,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
if (!mIsConnectingErrorPossible) return; if (!mIsConnectingErrorPossible) return;
mIsConnectingErrorPossible = false; mIsConnectingErrorPossible = false;
mLocalManager.showError(mAddress, R.string.bluetooth_error_title, mLocalManager.showError(mDevice, R.string.bluetooth_error_title,
R.string.bluetooth_connecting_error_message); R.string.bluetooth_connecting_error_message);
} }
@@ -432,15 +434,15 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
} }
public void pair() { public void pair() {
BluetoothDevice manager = mLocalManager.getBluetoothManager(); BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
// Pairing is unreliable while scanning, so cancel discovery // Pairing is unreliable while scanning, so cancel discovery
if (manager.isDiscovering()) { if (adapter.isDiscovering()) {
manager.cancelDiscovery(); adapter.cancelDiscovery();
} }
if (!mLocalManager.getBluetoothManager().createBond(mAddress)) { if (!mDevice.createBond()) {
mLocalManager.showError(mAddress, R.string.bluetooth_error_title, mLocalManager.showError(mDevice, R.string.bluetooth_error_title,
R.string.bluetooth_pairing_error_message); R.string.bluetooth_pairing_error_message);
} }
} }
@@ -452,7 +454,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
Iterator<BluetoothJob> it = workQueue.iterator(); Iterator<BluetoothJob> it = workQueue.iterator();
while (it.hasNext()) { while (it.hasNext()) {
BluetoothJob job = it.next(); BluetoothJob job = it.next();
if (job.device.mAddress.equals(this.mAddress)) { if (job.cachedDevice.mDevice.equals(this.mDevice)) {
it.remove(); it.remove();
if (job.timeSent != 0) { if (job.timeSent != 0) {
processNow = true; processNow = true;
@@ -464,15 +466,13 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
} }
} }
BluetoothDevice manager = mLocalManager.getBluetoothManager();
switch (getBondState()) { switch (getBondState()) {
case BluetoothDevice.BOND_BONDED: case BluetoothDevice.BOND_BONDED:
manager.removeBond(mAddress); mDevice.removeBond();
break; break;
case BluetoothDevice.BOND_BONDING: case BluetoothDevice.BOND_BONDING:
manager.cancelBondProcess(mAddress); mDevice.cancelBondProcess();
break; break;
} }
} }
@@ -486,8 +486,8 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
dispatchAttributesChanged(); dispatchAttributesChanged();
} }
public String getAddress() { public BluetoothDevice getDevice() {
return mAddress; return mDevice;
} }
public String getName() { public String getName() {
@@ -497,7 +497,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
public void setName(String name) { public void setName(String name) {
if (!mName.equals(name)) { if (!mName.equals(name)) {
if (TextUtils.isEmpty(name)) { if (TextUtils.isEmpty(name)) {
mName = mAddress; mName = mDevice.getAddress();
} else { } else {
mName = name; mName = name;
} }
@@ -511,10 +511,10 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
} }
private void fetchName() { private void fetchName() {
mName = mLocalManager.getBluetoothManager().getRemoteName(mAddress); mName = mDevice.getName();
if (TextUtils.isEmpty(mName)) { if (TextUtils.isEmpty(mName)) {
mName = mAddress; mName = mDevice.getAddress();
} }
} }
@@ -534,7 +534,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
} }
public int getBondState() { public int getBondState() {
return mLocalManager.getBluetoothManager().getBondState(mAddress); return mDevice.getBondState();
} }
void setRssi(short rssi) { void setRssi(short rssi) {
@@ -552,7 +552,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
public boolean isConnected() { public boolean isConnected() {
for (Profile profile : mProfiles) { for (Profile profile : mProfiles) {
int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile) int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
.getConnectionStatus(mAddress); .getConnectionStatus(mDevice);
if (SettingsBtStatus.isConnectionStatusConnected(status)) { if (SettingsBtStatus.isConnectionStatusConnected(status)) {
return true; return true;
} }
@@ -564,7 +564,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
public boolean isBusy() { public boolean isBusy() {
for (Profile profile : mProfiles) { for (Profile profile : mProfiles) {
int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile) int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
.getConnectionStatus(mAddress); .getConnectionStatus(mDevice);
if (SettingsBtStatus.isConnectionStatusBusy(status)) { if (SettingsBtStatus.isConnectionStatusBusy(status)) {
return true; return true;
} }
@@ -599,7 +599,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
* Fetches a new value for the cached BT class. * Fetches a new value for the cached BT class.
*/ */
private void fetchBtClass() { private void fetchBtClass() {
mBtClass = mLocalManager.getBluetoothManager().getRemoteClass(mAddress); mBtClass = mDevice.getBluetoothClass();
if (mBtClass != BluetoothClass.ERROR) { if (mBtClass != BluetoothClass.ERROR) {
LocalBluetoothProfileManager.fill(mBtClass, mProfiles); LocalBluetoothProfileManager.fill(mBtClass, mProfiles);
} }
@@ -632,7 +632,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
for (Profile profile : mProfiles) { for (Profile profile : mProfiles) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mLocalManager, profile); .getProfileManager(mLocalManager, profile);
int connectionStatus = profileManager.getConnectionStatus(mAddress); int connectionStatus = profileManager.getConnectionStatus(mDevice);
if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) || if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
@@ -656,17 +656,17 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
if (mProfiles.contains(Profile.A2DP)) { if (mProfiles.contains(Profile.A2DP)) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mLocalManager, Profile.A2DP); .getProfileManager(mLocalManager, Profile.A2DP);
isConnecting = profileManager.getConnectionStatus(mAddress) == isConnecting = profileManager.getConnectionStatus(mDevice) ==
SettingsBtStatus.CONNECTION_STATUS_CONNECTING; SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
isA2dpConnected = profileManager.isConnected(mAddress); isA2dpConnected = profileManager.isConnected(mDevice);
} }
if (mProfiles.contains(Profile.HEADSET)) { if (mProfiles.contains(Profile.HEADSET)) {
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mLocalManager, Profile.HEADSET); .getProfileManager(mLocalManager, Profile.HEADSET);
isConnecting |= profileManager.getConnectionStatus(mAddress) == isConnecting |= profileManager.getConnectionStatus(mDevice) ==
SettingsBtStatus.CONNECTION_STATUS_CONNECTING; SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
isHeadsetConnected = profileManager.isConnected(mAddress); isHeadsetConnected = profileManager.isConnected(mDevice);
} }
if (isConnecting) { if (isConnecting) {
@@ -690,7 +690,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
public void onCreateContextMenu(ContextMenu menu) { public void onCreateContextMenu(ContextMenu menu) {
// No context menu if it is busy (none of these items are applicable if busy) // No context menu if it is busy (none of these items are applicable if busy)
if (mLocalManager.getBluetoothState() != BluetoothDevice.BLUETOOTH_STATE_ON || isBusy()) { if (mLocalManager.getBluetoothState() != BluetoothAdapter.BLUETOOTH_STATE_ON || isBusy()) {
return; return;
} }
@@ -752,7 +752,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} }
intent.setClass(context, ConnectSpecificProfilesActivity.class); intent.setClass(context, ConnectSpecificProfilesActivity.class);
intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_ADDRESS, mAddress); intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE, mDevice);
context.startActivity(intent); context.startActivity(intent);
break; break;
} }
@@ -780,24 +780,24 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
@Override @Override
public String toString() { public String toString() {
return mAddress; return mDevice.toString();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if ((o == null) || !(o instanceof LocalBluetoothDevice)) { if ((o == null) || !(o instanceof CachedBluetoothDevice)) {
throw new ClassCastException(); throw new ClassCastException();
} }
return mAddress.equals(((LocalBluetoothDevice) o).mAddress); return mDevice.equals(((CachedBluetoothDevice) o).mDevice);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return mAddress.hashCode(); return mDevice.getAddress().hashCode();
} }
public int compareTo(LocalBluetoothDevice another) { public int compareTo(CachedBluetoothDevice another) {
int comparison; int comparison;
// Connected above not connected // Connected above not connected
@@ -822,6 +822,6 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
} }
public interface Callback { public interface Callback {
void onDeviceAttributesChanged(LocalBluetoothDevice device); void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice);
} }
} }

View File

@@ -0,0 +1,246 @@
/*
* Copyright (C) 2008 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.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
*/
public class CachedBluetoothDeviceManager {
private static final String TAG = "CachedBluetoothDeviceManager";
final LocalBluetoothManager mLocalManager;
final List<Callback> mCallbacks;
final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>();
public CachedBluetoothDeviceManager(LocalBluetoothManager localManager) {
mLocalManager = localManager;
mCallbacks = localManager.getCallbacks();
readPairedDevices();
}
private synchronized boolean readPairedDevices() {
BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
if (bondedDevices == null) return false;
boolean deviceAdded = false;
for (BluetoothDevice device : bondedDevices) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice == null) {
cachedDevice = new CachedBluetoothDevice(mLocalManager.getContext(), device);
mCachedDevices.add(cachedDevice);
dispatchDeviceAdded(cachedDevice);
deviceAdded = true;
}
}
return deviceAdded;
}
public synchronized List<CachedBluetoothDevice> getCachedDevicesCopy() {
return new ArrayList<CachedBluetoothDevice>(mCachedDevices);
}
void onBluetoothStateChanged(boolean enabled) {
if (enabled) {
readPairedDevices();
}
}
public synchronized void onDeviceAppeared(BluetoothDevice device, short rssi, int btClass,
String name) {
boolean deviceAdded = false;
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice == null) {
cachedDevice = new CachedBluetoothDevice(mLocalManager.getContext(), device);
mCachedDevices.add(cachedDevice);
deviceAdded = true;
}
cachedDevice.setRssi(rssi);
cachedDevice.setBtClass(btClass);
cachedDevice.setName(name);
cachedDevice.setVisible(true);
if (deviceAdded) {
dispatchDeviceAdded(cachedDevice);
}
}
public synchronized void onDeviceDisappeared(BluetoothDevice device) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice == null) return;
cachedDevice.setVisible(false);
checkForDeviceRemoval(cachedDevice);
}
private void checkForDeviceRemoval(CachedBluetoothDevice cachedDevice) {
if (cachedDevice.getBondState() == BluetoothDevice.BOND_NOT_BONDED &&
!cachedDevice.isVisible()) {
// If device isn't paired, remove it altogether
mCachedDevices.remove(cachedDevice);
dispatchDeviceDeleted(cachedDevice);
}
}
public synchronized void onDeviceNameUpdated(BluetoothDevice device) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice != null) {
cachedDevice.refreshName();
}
}
public synchronized CachedBluetoothDevice findDevice(BluetoothDevice device) {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
if (cachedDevice.getDevice().equals(device)) {
return cachedDevice;
}
}
return null;
}
/**
* Attempts to get the name of a remote device, otherwise returns the address.
*
* @param device The remote device.
* @return The name, or if unavailable, the address.
*/
public String getName(BluetoothDevice device) {
CachedBluetoothDevice cachedDevice = findDevice(device);
return cachedDevice != null ? cachedDevice.getName() : device.getAddress();
}
private void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
synchronized (mCallbacks) {
for (Callback callback : mCallbacks) {
callback.onDeviceAdded(cachedDevice);
}
}
// TODO: divider between prev paired/connected and scanned
}
private void dispatchDeviceDeleted(CachedBluetoothDevice cachedDevice) {
synchronized (mCallbacks) {
for (Callback callback : mCallbacks) {
callback.onDeviceDeleted(cachedDevice);
}
}
}
public synchronized void onBondingStateChanged(BluetoothDevice device, int bondState) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice == null) {
if (!readPairedDevices()) {
Log.e(TAG, "Got bonding state changed for " + device +
", but we have no record of that device.");
}
return;
}
cachedDevice.refresh();
if (bondState == BluetoothDevice.BOND_BONDED) {
// Auto-connect after pairing
cachedDevice.connect();
}
}
/**
* Called when there is a bonding error.
*
* @param device The remote device.
* @param reason The reason, one of the error reasons from
* BluetoothDevice.UNBOND_REASON_*
*/
public synchronized void onBondingError(BluetoothDevice device, int reason) {
int errorMsg;
switch(reason) {
case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
errorMsg = R.string.bluetooth_pairing_pin_error_message;
break;
case BluetoothDevice.UNBOND_REASON_AUTH_REJECTED:
errorMsg = R.string.bluetooth_pairing_rejected_error_message;
break;
case BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN:
errorMsg = R.string.bluetooth_pairing_device_down_error_message;
break;
default:
errorMsg = R.string.bluetooth_pairing_error_message;
}
mLocalManager.showError(device, R.string.bluetooth_error_title, errorMsg);
}
public synchronized void onProfileStateChanged(BluetoothDevice device, Profile profile,
int newProfileState) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice == null) return;
cachedDevice.onProfileStateChanged(profile, newProfileState);
cachedDevice.refresh();
}
public synchronized void onConnectingError(BluetoothDevice device) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice == null) return;
/*
* Go through the device's delegate so we don't spam the user with
* errors connecting to different profiles, and instead make sure the
* user sees a single error for his single 'connect' action.
*/
cachedDevice.showConnectingError();
}
public synchronized void onScanningStateChanged(boolean started) {
if (!started) return;
// If starting a new scan, clear old visibility
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
cachedDevice.setVisible(false);
checkForDeviceRemoval(cachedDevice);
}
}
public synchronized void onBtClassChanged(BluetoothDevice device) {
CachedBluetoothDevice cachedDevice = findDevice(device);
if (cachedDevice != null) {
cachedDevice.refreshBtClass();
}
}
}

View File

@@ -19,6 +19,7 @@ package com.android.settings.bluetooth;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile; import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import android.bluetooth.BluetoothDevice;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
@@ -34,17 +35,17 @@ import android.util.Log;
* (or disconnected). * (or disconnected).
*/ */
public class ConnectSpecificProfilesActivity extends PreferenceActivity public class ConnectSpecificProfilesActivity extends PreferenceActivity
implements LocalBluetoothDevice.Callback, Preference.OnPreferenceChangeListener { implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
private static final String TAG = "ConnectSpecificProfilesActivity"; private static final String TAG = "ConnectSpecificProfilesActivity";
private static final String KEY_ONLINE_MODE = "online_mode"; private static final String KEY_ONLINE_MODE = "online_mode";
private static final String KEY_TITLE = "title"; private static final String KEY_TITLE = "title";
private static final String KEY_PROFILE_CONTAINER = "profile_container"; private static final String KEY_PROFILE_CONTAINER = "profile_container";
public static final String EXTRA_ADDRESS = "address"; public static final String EXTRA_DEVICE = "device";
private LocalBluetoothManager mManager; private LocalBluetoothManager mManager;
private LocalBluetoothDevice mDevice; private CachedBluetoothDevice mCachedDevice;
private PreferenceGroup mProfileContainer; private PreferenceGroup mProfileContainer;
private CheckBoxPreference mOnlineModePreference; private CheckBoxPreference mOnlineModePreference;
@@ -62,22 +63,22 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
String address; BluetoothDevice device;
if (savedInstanceState != null) { if (savedInstanceState != null) {
address = savedInstanceState.getString(EXTRA_ADDRESS); device = savedInstanceState.getParcelable(EXTRA_DEVICE);
} else { } else {
Intent intent = getIntent(); Intent intent = getIntent();
address = intent.getStringExtra(EXTRA_ADDRESS); device = intent.getParcelableExtra(EXTRA_DEVICE);
} }
if (TextUtils.isEmpty(address)) { if (device == null) {
Log.w(TAG, "Activity started without address"); Log.w(TAG, "Activity started without a remote blueototh device");
finish(); finish();
} }
mManager = LocalBluetoothManager.getInstance(this); mManager = LocalBluetoothManager.getInstance(this);
mDevice = mManager.getLocalDeviceManager().findDevice(address); mCachedDevice = mManager.getCachedDeviceManager().findDevice(device);
if (mDevice == null) { if (mCachedDevice == null) {
Log.w(TAG, "Device not found, cannot connect to it"); Log.w(TAG, "Device not found, cannot connect to it");
finish(); finish();
} }
@@ -87,7 +88,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
// Set the title of the screen // Set the title of the screen
findPreference(KEY_TITLE).setTitle( findPreference(KEY_TITLE).setTitle(
getString(R.string.bluetooth_device_advanced_title, mDevice.getName())); getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
// Listen for check/uncheck of the online mode checkbox // Listen for check/uncheck of the online mode checkbox
mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE); mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
@@ -101,7 +102,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putString(EXTRA_ADDRESS, mDevice.getAddress()); outState.putParcelable(EXTRA_DEVICE, mCachedDevice.getDevice());
} }
@Override @Override
@@ -109,7 +110,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
super.onResume(); super.onResume();
mManager.setForegroundActivity(this); mManager.setForegroundActivity(this);
mDevice.registerCallback(this); mCachedDevice.registerCallback(this);
refresh(); refresh();
} }
@@ -118,12 +119,12 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
mDevice.unregisterCallback(this); mCachedDevice.unregisterCallback(this);
mManager.setForegroundActivity(null); mManager.setForegroundActivity(null);
} }
private void addPreferencesForProfiles() { private void addPreferencesForProfiles() {
for (Profile profile : mDevice.getProfiles()) { for (Profile profile : mCachedDevice.getProfiles()) {
Preference pref = createProfilePreference(profile); Preference pref = createProfilePreference(profile);
mProfileContainer.addPreference(pref); mProfileContainer.addPreference(pref);
} }
@@ -172,24 +173,24 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
private void onProfileCheckedStateChanged(Profile profile, boolean checked) { private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
if (mOnlineMode) { if (mOnlineMode) {
if (checked) { if (checked) {
mDevice.connect(profile); mCachedDevice.connect(profile);
} else { } else {
mDevice.disconnect(profile); mCachedDevice.disconnect(profile);
} }
} }
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile); .getProfileManager(mManager, profile);
profileManager.setPreferred(mDevice.getAddress(), checked); profileManager.setPreferred(mCachedDevice.getDevice(), checked);
} }
public void onDeviceAttributesChanged(LocalBluetoothDevice device) { public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {
refresh(); refresh();
} }
private void refresh() { private void refresh() {
// We are in 'online mode' if we are connected, connecting, or disconnecting // We are in 'online mode' if we are connected, connecting, or disconnecting
setOnlineMode(mDevice.isConnected() || mDevice.isBusy(), false); setOnlineMode(mCachedDevice.isConnected() || mCachedDevice.isBusy(), false);
refreshProfiles(); refreshProfiles();
} }
@@ -205,9 +206,9 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
if (takeAction) { if (takeAction) {
if (onlineMode) { if (onlineMode) {
mDevice.connect(); mCachedDevice.connect();
} else { } else {
mDevice.disconnect(); mCachedDevice.disconnect();
} }
} }
@@ -218,18 +219,18 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
mOnlineModePreference.setChecked(mOnlineMode); mOnlineModePreference.setChecked(mOnlineMode);
/* Gray out checkbox while connecting and disconnecting */ /* Gray out checkbox while connecting and disconnecting */
mOnlineModePreference.setEnabled(!mDevice.isBusy()); mOnlineModePreference.setEnabled(!mCachedDevice.isBusy());
/** /**
* If the device is online, show status. Otherwise, show a summary that * If the device is online, show status. Otherwise, show a summary that
* describes what the checkbox does. * describes what the checkbox does.
*/ */
mOnlineModePreference.setSummary(mOnlineMode ? mDevice.getSummary() mOnlineModePreference.setSummary(mOnlineMode ? mCachedDevice.getSummary()
: R.string.bluetooth_device_advanced_online_mode_summary); : R.string.bluetooth_device_advanced_online_mode_summary);
} }
private void refreshProfiles() { private void refreshProfiles() {
for (Profile profile : mDevice.getProfiles()) { for (Profile profile : mCachedDevice.getProfiles()) {
CheckBoxPreference profilePref = CheckBoxPreference profilePref =
(CheckBoxPreference) findPreference(profile.toString()); (CheckBoxPreference) findPreference(profile.toString());
if (profilePref == null) { if (profilePref == null) {
@@ -242,19 +243,19 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
} }
private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) { private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
String address = mDevice.getAddress(); BluetoothDevice device = mCachedDevice.getDevice();
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile); .getProfileManager(mManager, profile);
int connectionStatus = profileManager.getConnectionStatus(address); int connectionStatus = profileManager.getConnectionStatus(device);
/* Gray out checkbox while connecting and disconnecting */ /* Gray out checkbox while connecting and disconnecting */
profilePref.setEnabled(!mDevice.isBusy()); profilePref.setEnabled(!mCachedDevice.isBusy());
profilePref.setSummary(getProfileSummary(profileManager, profile, address, profilePref.setSummary(getProfileSummary(profileManager, profile, device,
connectionStatus, mOnlineMode)); connectionStatus, mOnlineMode));
profilePref.setChecked(profileManager.isPreferred(address)); profilePref.setChecked(profileManager.isPreferred(device));
} }
private Profile getProfileOf(Preference pref) { private Profile getProfileOf(Preference pref) {
@@ -270,11 +271,11 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
} }
private static int getProfileSummary(LocalBluetoothProfileManager profileManager, private static int getProfileSummary(LocalBluetoothProfileManager profileManager,
Profile profile, String address, int connectionStatus, boolean onlineMode) { Profile profile, BluetoothDevice device, int connectionStatus, boolean onlineMode) {
if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) { if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
return getProfileSummaryForSettingPreference(profile); return getProfileSummaryForSettingPreference(profile);
} else { } else {
return profileManager.getSummary(address); return profileManager.getSummary(device);
} }
} }

View File

@@ -1,244 +0,0 @@
/*
* Copyright (C) 2008 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.bluetooth.BluetoothDevice;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import java.util.ArrayList;
import java.util.List;
/**
* LocalBluetoothDeviceManager manages the set of remote Bluetooth devices.
*/
public class LocalBluetoothDeviceManager {
private static final String TAG = "LocalBluetoothDeviceManager";
final LocalBluetoothManager mLocalManager;
final List<Callback> mCallbacks;
final List<LocalBluetoothDevice> mDevices = new ArrayList<LocalBluetoothDevice>();
public LocalBluetoothDeviceManager(LocalBluetoothManager localManager) {
mLocalManager = localManager;
mCallbacks = localManager.getCallbacks();
readPairedDevices();
}
private synchronized boolean readPairedDevices() {
BluetoothDevice manager = mLocalManager.getBluetoothManager();
String[] bondedAddresses = manager.listBonds();
if (bondedAddresses == null) return false;
boolean deviceAdded = false;
for (String address : bondedAddresses) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) {
device = new LocalBluetoothDevice(mLocalManager.getContext(), address);
mDevices.add(device);
dispatchDeviceAdded(device);
deviceAdded = true;
}
}
return deviceAdded;
}
public synchronized List<LocalBluetoothDevice> getDevicesCopy() {
return new ArrayList<LocalBluetoothDevice>(mDevices);
}
void onBluetoothStateChanged(boolean enabled) {
if (enabled) {
readPairedDevices();
}
}
public synchronized void onDeviceAppeared(String address, short rssi, int btClass,
String name) {
boolean deviceAdded = false;
LocalBluetoothDevice device = findDevice(address);
if (device == null) {
device = new LocalBluetoothDevice(mLocalManager.getContext(), address);
mDevices.add(device);
deviceAdded = true;
}
device.setRssi(rssi);
device.setBtClass(btClass);
device.setName(name);
device.setVisible(true);
if (deviceAdded) {
dispatchDeviceAdded(device);
}
}
public synchronized void onDeviceDisappeared(String address) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) return;
device.setVisible(false);
checkForDeviceRemoval(device);
}
private void checkForDeviceRemoval(LocalBluetoothDevice device) {
if (device.getBondState() == BluetoothDevice.BOND_NOT_BONDED &&
!device.isVisible()) {
// If device isn't paired, remove it altogether
mDevices.remove(device);
dispatchDeviceDeleted(device);
}
}
public synchronized void onDeviceNameUpdated(String address) {
LocalBluetoothDevice device = findDevice(address);
if (device != null) {
device.refreshName();
}
}
public synchronized LocalBluetoothDevice findDevice(String address) {
for (int i = mDevices.size() - 1; i >= 0; i--) {
LocalBluetoothDevice device = mDevices.get(i);
if (device.getAddress().equals(address)) {
return device;
}
}
return null;
}
/**
* Attempts to get the name of a remote device, otherwise returns the address.
*
* @param address The address.
* @return The name, or if unavailable, the address.
*/
public String getName(String address) {
LocalBluetoothDevice device = findDevice(address);
return device != null ? device.getName() : address;
}
private void dispatchDeviceAdded(LocalBluetoothDevice device) {
synchronized (mCallbacks) {
for (Callback callback : mCallbacks) {
callback.onDeviceAdded(device);
}
}
// TODO: divider between prev paired/connected and scanned
}
private void dispatchDeviceDeleted(LocalBluetoothDevice device) {
synchronized (mCallbacks) {
for (Callback callback : mCallbacks) {
callback.onDeviceDeleted(device);
}
}
}
public synchronized void onBondingStateChanged(String address, int bondState) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) {
if (!readPairedDevices()) {
Log.e(TAG, "Got bonding state changed for " + address +
", but we have no record of that device.");
}
return;
}
device.refresh();
if (bondState == BluetoothDevice.BOND_BONDED) {
// Auto-connect after pairing
device.connect();
}
}
/**
* Called when there is a bonding error.
*
* @param address The address of the remote device.
* @param reason The reason, one of the error reasons from
* BluetoothDevice.UNBOND_REASON_*
*/
public synchronized void onBondingError(String address, int reason) {
int errorMsg;
switch(reason) {
case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
errorMsg = R.string.bluetooth_pairing_pin_error_message;
break;
case BluetoothDevice.UNBOND_REASON_AUTH_REJECTED:
errorMsg = R.string.bluetooth_pairing_rejected_error_message;
break;
case BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN:
errorMsg = R.string.bluetooth_pairing_device_down_error_message;
break;
default:
errorMsg = R.string.bluetooth_pairing_error_message;
}
mLocalManager.showError(address, R.string.bluetooth_error_title, errorMsg);
}
public synchronized void onProfileStateChanged(String address, Profile profile,
int newProfileState) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) return;
device.onProfileStateChanged(profile, newProfileState);
device.refresh();
}
public synchronized void onConnectingError(String address) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) return;
/*
* Go through the device's delegate so we don't spam the user with
* errors connecting to different profiles, and instead make sure the
* user sees a single error for his single 'connect' action.
*/
device.showConnectingError();
}
public synchronized void onScanningStateChanged(boolean started) {
if (!started) return;
// If starting a new scan, clear old visibility
for (int i = mDevices.size() - 1; i >= 0; i--) {
LocalBluetoothDevice device = mDevices.get(i);
device.setVisible(false);
checkForDeviceRemoval(device);
}
}
public synchronized void onBtClassChanged(String address) {
LocalBluetoothDevice device = findDevice(address);
if (device != null) {
device.refreshBtClass();
}
}
}

View File

@@ -20,10 +20,12 @@ import com.android.settings.R;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothError; import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothIntent;
@@ -56,9 +58,9 @@ public class LocalBluetoothManager {
private Activity mForegroundActivity; private Activity mForegroundActivity;
private AlertDialog mErrorDialog = null; private AlertDialog mErrorDialog = null;
private BluetoothDevice mManager; private BluetoothAdapter mAdapter;
private LocalBluetoothDeviceManager mLocalDeviceManager; private CachedBluetoothDeviceManager mCachedDeviceManager;
private BluetoothEventRedirector mEventRedirector; private BluetoothEventRedirector mEventRedirector;
private BluetoothA2dp mBluetoothA2dp; private BluetoothA2dp mBluetoothA2dp;
@@ -90,12 +92,12 @@ public class LocalBluetoothManager {
// This will be around as long as this process is // This will be around as long as this process is
mContext = context.getApplicationContext(); mContext = context.getApplicationContext();
mManager = (BluetoothDevice) context.getSystemService(Context.BLUETOOTH_SERVICE); mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE);
if (mManager == null) { if (mAdapter == null) {
return false; return false;
} }
mLocalDeviceManager = new LocalBluetoothDeviceManager(this); mCachedDeviceManager = new CachedBluetoothDeviceManager(this);
mEventRedirector = new BluetoothEventRedirector(this); mEventRedirector = new BluetoothEventRedirector(this);
mEventRedirector.start(); mEventRedirector.start();
@@ -105,8 +107,8 @@ public class LocalBluetoothManager {
return true; return true;
} }
public BluetoothDevice getBluetoothManager() { public BluetoothAdapter getBluetoothAdapter() {
return mManager; return mAdapter;
} }
public Context getContext() { public Context getContext() {
@@ -129,8 +131,8 @@ public class LocalBluetoothManager {
return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
} }
public LocalBluetoothDeviceManager getLocalDeviceManager() { public CachedBluetoothDeviceManager getCachedDeviceManager() {
return mLocalDeviceManager; return mCachedDeviceManager;
} }
List<Callback> getCallbacks() { List<Callback> getCallbacks() {
@@ -150,7 +152,7 @@ public class LocalBluetoothManager {
} }
public void startScanning(boolean force) { public void startScanning(boolean force) {
if (mManager.isDiscovering()) { if (mAdapter.isDiscovering()) {
/* /*
* Already discovering, but give the callback that information. * Already discovering, but give the callback that information.
* Note: we only call the callbacks, not the same path as if the * Note: we only call the callbacks, not the same path as if the
@@ -167,17 +169,17 @@ public class LocalBluetoothManager {
} }
// If we are playing music, don't scan unless forced. // If we are playing music, don't scan unless forced.
List<String> sinks = mBluetoothA2dp.listConnectedSinks(); Set<BluetoothDevice> sinks = mBluetoothA2dp.getConnectedSinks();
if (sinks != null) { if (sinks != null) {
for (String address : sinks) { for (BluetoothDevice sink : sinks) {
if (mBluetoothA2dp.getSinkState(address) == BluetoothA2dp.STATE_PLAYING) { if (mBluetoothA2dp.getSinkState(sink) == BluetoothA2dp.STATE_PLAYING) {
return; return;
} }
} }
} }
} }
if (mManager.startDiscovery()) { if (mAdapter.startDiscovery()) {
mLastScan = System.currentTimeMillis(); mLastScan = System.currentTimeMillis();
} }
} }
@@ -194,19 +196,20 @@ public class LocalBluetoothManager {
void setBluetoothStateInt(int state) { void setBluetoothStateInt(int state) {
mState = state; mState = state;
if (state == BluetoothDevice.BLUETOOTH_STATE_ON || if (state == BluetoothAdapter.BLUETOOTH_STATE_ON ||
state == BluetoothDevice.BLUETOOTH_STATE_OFF) { state == BluetoothAdapter.BLUETOOTH_STATE_OFF) {
mLocalDeviceManager.onBluetoothStateChanged(state == BluetoothDevice.BLUETOOTH_STATE_ON); mCachedDeviceManager.onBluetoothStateChanged(state ==
BluetoothAdapter.BLUETOOTH_STATE_ON);
} }
} }
private void syncBluetoothState() { private void syncBluetoothState() {
int bluetoothState; int bluetoothState;
if (mManager != null) { if (mAdapter != null) {
bluetoothState = mManager.isEnabled() bluetoothState = mAdapter.isEnabled()
? BluetoothDevice.BLUETOOTH_STATE_ON ? BluetoothAdapter.BLUETOOTH_STATE_ON
: BluetoothDevice.BLUETOOTH_STATE_OFF; : BluetoothAdapter.BLUETOOTH_STATE_OFF;
} else { } else {
bluetoothState = BluetoothError.ERROR; bluetoothState = BluetoothError.ERROR;
} }
@@ -216,13 +219,13 @@ public class LocalBluetoothManager {
public void setBluetoothEnabled(boolean enabled) { public void setBluetoothEnabled(boolean enabled) {
boolean wasSetStateSuccessful = enabled boolean wasSetStateSuccessful = enabled
? mManager.enable() ? mAdapter.enable()
: mManager.disable(); : mAdapter.disable();
if (wasSetStateSuccessful) { if (wasSetStateSuccessful) {
setBluetoothStateInt(enabled setBluetoothStateInt(enabled
? BluetoothDevice.BLUETOOTH_STATE_TURNING_ON ? BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON
: BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF); : BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF);
} else { } else {
if (V) { if (V) {
Log.v(TAG, Log.v(TAG,
@@ -239,7 +242,7 @@ public class LocalBluetoothManager {
*/ */
void onScanningStateChanged(boolean started) { void onScanningStateChanged(boolean started) {
// TODO: have it be a callback (once we switch bluetooth state changed to callback) // TODO: have it be a callback (once we switch bluetooth state changed to callback)
mLocalDeviceManager.onScanningStateChanged(started); mCachedDeviceManager.onScanningStateChanged(started);
dispatchScanningStateChanged(started); dispatchScanningStateChanged(started);
} }
@@ -251,11 +254,11 @@ public class LocalBluetoothManager {
} }
} }
public void showError(String address, int titleResId, int messageResId) { public void showError(BluetoothDevice device, int titleResId, int messageResId) {
LocalBluetoothDevice device = mLocalDeviceManager.findDevice(address); CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(device);
if (device == null) return; if (cachedDevice == null) return;
String name = device.getName(); String name = cachedDevice.getName();
String message = mContext.getString(messageResId, name); String message = mContext.getString(messageResId, name);
if (mForegroundActivity != null) { if (mForegroundActivity != null) {
@@ -274,8 +277,8 @@ public class LocalBluetoothManager {
public interface Callback { public interface Callback {
void onScanningStateChanged(boolean started); void onScanningStateChanged(boolean started);
void onDeviceAdded(LocalBluetoothDevice device); void onDeviceAdded(CachedBluetoothDevice cachedDevice);
void onDeviceDeleted(LocalBluetoothDevice device); void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
} }
} }

View File

@@ -17,6 +17,7 @@
package com.android.settings.bluetooth; package com.android.settings.bluetooth;
import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothError; import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadset;
import android.os.Handler; import android.os.Handler;
@@ -27,6 +28,7 @@ import com.android.settings.R;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* LocalBluetoothProfileManager is an abstract class defining the basic * LocalBluetoothProfileManager is an abstract class defining the basic
@@ -91,22 +93,22 @@ public abstract class LocalBluetoothProfileManager {
mLocalManager = localManager; mLocalManager = localManager;
} }
public abstract int connect(String address); public abstract int connect(BluetoothDevice device);
public abstract int disconnect(String address); public abstract int disconnect(BluetoothDevice device);
public abstract int getConnectionStatus(String address); public abstract int getConnectionStatus(BluetoothDevice device);
public abstract int getSummary(String address); public abstract int getSummary(BluetoothDevice device);
public abstract int convertState(int a2dpState); public abstract int convertState(int a2dpState);
public abstract boolean isPreferred(String address); public abstract boolean isPreferred(BluetoothDevice device);
public abstract void setPreferred(String address, boolean preferred); public abstract void setPreferred(BluetoothDevice device, boolean preferred);
public boolean isConnected(String address) { public boolean isConnected(BluetoothDevice device) {
return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(address)); return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(device));
} }
// TODO: int instead of enum // TODO: int instead of enum
@@ -133,29 +135,29 @@ public abstract class LocalBluetoothProfileManager {
} }
@Override @Override
public int connect(String address) { public int connect(BluetoothDevice device) {
List<String> sinks = mService.listConnectedSinks(); Set<BluetoothDevice> sinks = mService.getConnectedSinks();
if (sinks != null) { if (sinks != null) {
for (String sinkAddress : sinks) { for (BluetoothDevice sink : sinks) {
mService.disconnectSink(sinkAddress); mService.disconnectSink(sink);
} }
} }
return mService.connectSink(address); return mService.connectSink(device);
} }
@Override @Override
public int disconnect(String address) { public int disconnect(BluetoothDevice device) {
return mService.disconnectSink(address); return mService.disconnectSink(device);
} }
@Override @Override
public int getConnectionStatus(String address) { public int getConnectionStatus(BluetoothDevice device) {
return convertState(mService.getSinkState(address)); return convertState(mService.getSinkState(device));
} }
@Override @Override
public int getSummary(String address) { public int getSummary(BluetoothDevice device) {
int connectionStatus = getConnectionStatus(address); int connectionStatus = getConnectionStatus(device);
if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
return R.string.bluetooth_a2dp_profile_summary_connected; return R.string.bluetooth_a2dp_profile_summary_connected;
@@ -165,13 +167,13 @@ public abstract class LocalBluetoothProfileManager {
} }
@Override @Override
public boolean isPreferred(String address) { public boolean isPreferred(BluetoothDevice device) {
return mService.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF; return mService.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
} }
@Override @Override
public void setPreferred(String address, boolean preferred) { public void setPreferred(BluetoothDevice device, boolean preferred) {
mService.setSinkPriority(address, mService.setSinkPriority(device,
preferred ? BluetoothA2dp.PRIORITY_AUTO : BluetoothA2dp.PRIORITY_OFF); preferred ? BluetoothA2dp.PRIORITY_AUTO : BluetoothA2dp.PRIORITY_OFF);
} }
@@ -215,10 +217,10 @@ public abstract class LocalBluetoothProfileManager {
* We just bound to the service, so refresh the UI of the * We just bound to the service, so refresh the UI of the
* headset device. * headset device.
*/ */
String address = mService.getHeadsetAddress(); BluetoothDevice device = mService.getCurrentHeadset();
if (TextUtils.isEmpty(address)) return; if (device == null) return;
mLocalManager.getLocalDeviceManager() mLocalManager.getCachedDeviceManager()
.onProfileStateChanged(address, Profile.HEADSET, .onProfileStateChanged(device, Profile.HEADSET,
BluetoothHeadset.STATE_CONNECTED); BluetoothHeadset.STATE_CONNECTED);
} }
}); });
@@ -228,17 +230,17 @@ public abstract class LocalBluetoothProfileManager {
} }
@Override @Override
public int connect(String address) { public int connect(BluetoothDevice device) {
// Since connectHeadset fails if already connected to a headset, we // Since connectHeadset fails if already connected to a headset, we
// disconnect from any headset first // disconnect from any headset first
mService.disconnectHeadset(); mService.disconnectHeadset();
return mService.connectHeadset(address) return mService.connectHeadset(device)
? BluetoothError.SUCCESS : BluetoothError.ERROR; ? BluetoothError.SUCCESS : BluetoothError.ERROR;
} }
@Override @Override
public int disconnect(String address) { public int disconnect(BluetoothDevice device) {
if (mService.getHeadsetAddress().equals(address)) { if (mService.getCurrentHeadset().equals(device)) {
return mService.disconnectHeadset() ? BluetoothError.SUCCESS : BluetoothError.ERROR; return mService.disconnectHeadset() ? BluetoothError.SUCCESS : BluetoothError.ERROR;
} else { } else {
return BluetoothError.SUCCESS; return BluetoothError.SUCCESS;
@@ -246,16 +248,16 @@ public abstract class LocalBluetoothProfileManager {
} }
@Override @Override
public int getConnectionStatus(String address) { public int getConnectionStatus(BluetoothDevice device) {
String headsetAddress = mService.getHeadsetAddress(); BluetoothDevice currentDevice = mService.getCurrentHeadset();
return headsetAddress != null && headsetAddress.equals(address) return currentDevice != null && currentDevice.equals(device)
? convertState(mService.getState()) ? convertState(mService.getState())
: SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; : SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
} }
@Override @Override
public int getSummary(String address) { public int getSummary(BluetoothDevice device) {
int connectionStatus = getConnectionStatus(address); int connectionStatus = getConnectionStatus(device);
if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
return R.string.bluetooth_headset_profile_summary_connected; return R.string.bluetooth_headset_profile_summary_connected;
@@ -265,13 +267,13 @@ public abstract class LocalBluetoothProfileManager {
} }
@Override @Override
public boolean isPreferred(String address) { public boolean isPreferred(BluetoothDevice device) {
return mService.getPriority(address) > BluetoothHeadset.PRIORITY_OFF; return mService.getPriority(device) > BluetoothHeadset.PRIORITY_OFF;
} }
@Override @Override
public void setPreferred(String address, boolean preferred) { public void setPreferred(BluetoothDevice device, boolean preferred) {
mService.setPriority(address, mService.setPriority(device,
preferred ? BluetoothHeadset.PRIORITY_AUTO : BluetoothHeadset.PRIORITY_OFF); preferred ? BluetoothHeadset.PRIORITY_AUTO : BluetoothHeadset.PRIORITY_OFF);
} }

View File

@@ -16,7 +16,7 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -377,7 +377,7 @@ public class Status extends PreferenceActivity {
} }
private void setBtStatus() { private void setBtStatus() {
BluetoothDevice bluetooth = (BluetoothDevice) getSystemService(BLUETOOTH_SERVICE); BluetoothAdapter bluetooth = (BluetoothAdapter) getSystemService(BLUETOOTH_SERVICE);
Preference btAddressPref = findPreference(KEY_BT_ADDRESS); Preference btAddressPref = findPreference(KEY_BT_ADDRESS);
if (bluetooth == null) { if (bluetooth == null) {

View File

@@ -19,7 +19,7 @@ package com.android.settings.widget;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider; import android.appwidget.AppWidgetProvider;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
@@ -379,9 +379,9 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
} }
} }
int state = mLocalBluetoothManager.getBluetoothState(); int state = mLocalBluetoothManager.getBluetoothState();
if (state == BluetoothDevice.BLUETOOTH_STATE_OFF) { if (state == BluetoothAdapter.BLUETOOTH_STATE_OFF) {
return STATE_DISABLED; return STATE_DISABLED;
} else if (state == BluetoothDevice.BLUETOOTH_STATE_ON) { } else if (state == BluetoothAdapter.BLUETOOTH_STATE_ON) {
return STATE_ENABLED; return STATE_ENABLED;
} else { } else {
return STATE_INTERMEDIATE; return STATE_INTERMEDIATE;