summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/bluetooth
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-18 17:39:48 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-18 17:39:48 -0700
commite6dd1fa1851302710ac7845d25d8ad8a5b6ee438 (patch)
treef5a8545397cd15f5bedf524a0673d88d5dd8d182 /src/com/android/settings/bluetooth
parent72ed6feab24308a0acd1fa2135afa3476759cf39 (diff)
downloadpackages_apps_settings-e6dd1fa1851302710ac7845d25d8ad8a5b6ee438.zip
packages_apps_settings-e6dd1fa1851302710ac7845d25d8ad8a5b6ee438.tar.gz
packages_apps_settings-e6dd1fa1851302710ac7845d25d8ad8a5b6ee438.tar.bz2
auto import from //branches/cupcake_rel/...@140373
Diffstat (limited to 'src/com/android/settings/bluetooth')
-rw-r--r--src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java1
-rw-r--r--src/com/android/settings/bluetooth/BluetoothEnabler.java31
-rw-r--r--src/com/android/settings/bluetooth/BluetoothEventRedirector.java31
-rw-r--r--src/com/android/settings/bluetooth/BluetoothNamePreference.java12
-rw-r--r--src/com/android/settings/bluetooth/BluetoothSettings.java13
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothDevice.java224
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java8
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothManager.java34
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java13
9 files changed, 284 insertions, 83 deletions
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index f1a2a1e..d458c5f 100644
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -92,7 +92,6 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
}
IntentFilter filter = new IntentFilter(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
- filter.addAction(BluetoothIntent.DISABLED_ACTION);
mContext.registerReceiver(mReceiver, filter);
mCheckBoxPreference.setOnPreferenceChangeListener(this);
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 661700f..82961b8 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -17,8 +17,9 @@
package com.android.settings.bluetooth;
import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -70,15 +71,15 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
return;
}
- ExtendedBluetoothState state = mLocalManager.getBluetoothState();
+ int state = mLocalManager.getBluetoothState();
// This is the widget enabled state, not the preference toggled state
- mCheckBoxPreference.setEnabled(state == ExtendedBluetoothState.ENABLED ||
- state == ExtendedBluetoothState.DISABLED);
+ mCheckBoxPreference.setEnabled(state == BluetoothDevice.BLUETOOTH_STATE_ON ||
+ state == BluetoothDevice.BLUETOOTH_STATE_OFF);
// BT state is not a sticky broadcast, so set it manually
handleStateChanged(state);
mContext.registerReceiver(mReceiver,
- new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+ new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION));
mCheckBoxPreference.setOnPreferenceChangeListener(this);
}
@@ -106,22 +107,24 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
mLocalManager.setBluetoothEnabled(enable);
}
- private void handleStateChanged(ExtendedBluetoothState state) {
+ private void handleStateChanged(int state) {
- if (state == ExtendedBluetoothState.DISABLED || state == ExtendedBluetoothState.ENABLED) {
- mCheckBoxPreference.setChecked(state == ExtendedBluetoothState.ENABLED);
- mCheckBoxPreference
- .setSummary(state == ExtendedBluetoothState.DISABLED ? mOriginalSummary : null);
+ if (state == BluetoothDevice.BLUETOOTH_STATE_OFF ||
+ state == BluetoothDevice.BLUETOOTH_STATE_ON) {
+ mCheckBoxPreference.setChecked(state == BluetoothDevice.BLUETOOTH_STATE_ON);
+ mCheckBoxPreference.setSummary(state == BluetoothDevice.BLUETOOTH_STATE_OFF ?
+ mOriginalSummary :
+ null);
mCheckBoxPreference.setEnabled(isEnabledByDependency());
- } else if (state == ExtendedBluetoothState.ENABLING ||
- state == ExtendedBluetoothState.DISABLING) {
- mCheckBoxPreference.setSummary(state == ExtendedBluetoothState.ENABLING
+ } else if (state == BluetoothDevice.BLUETOOTH_STATE_TURNING_ON ||
+ state == BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) {
+ mCheckBoxPreference.setSummary(state == BluetoothDevice.BLUETOOTH_STATE_TURNING_ON
? R.string.wifi_starting
: R.string.wifi_stopping);
- } else if (state == ExtendedBluetoothState.UNKNOWN) {
+ } else {
mCheckBoxPreference.setChecked(false);
mCheckBoxPreference.setSummary(R.string.wifi_error);
mCheckBoxPreference.setEnabled(true);
diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
index 2ad5726..71b91d3 100644
--- a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
+++ b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
@@ -16,8 +16,6 @@
package com.android.settings.bluetooth;
-import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
-
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
@@ -50,12 +48,10 @@ public class BluetoothEventRedirector {
String action = intent.getAction();
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
- if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
- mManager.setBluetoothStateInt(ExtendedBluetoothState.ENABLED);
-
- } else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
- mManager.setBluetoothStateInt(ExtendedBluetoothState.DISABLED);
-
+ if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
+ int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
+ BluetoothError.ERROR);
+ mManager.setBluetoothStateInt(state);
} else if (action.equals(BluetoothIntent.DISCOVERY_STARTED_ACTION)) {
mManager.onScanningStateChanged(true);
@@ -86,25 +82,29 @@ public class BluetoothEventRedirector {
}
} else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
- mManager.getLocalDeviceManager().onProfileStateChanged(address);
-
int newState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, 0);
int oldState = intent.getIntExtra(BluetoothIntent.HEADSET_PREVIOUS_STATE, 0);
if (newState == BluetoothHeadset.STATE_DISCONNECTED &&
oldState == BluetoothHeadset.STATE_CONNECTING) {
Log.i(TAG, "Failed to connect BT headset");
}
-
- } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
- mManager.getLocalDeviceManager().onProfileStateChanged(address);
+ boolean transientState = !(newState == BluetoothHeadset.STATE_CONNECTED
+ || newState == BluetoothHeadset.STATE_DISCONNECTED);
+ mManager.getLocalDeviceManager().onProfileStateChanged(address,transientState);
+
+ } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
int newState = intent.getIntExtra(BluetoothA2dp.SINK_STATE, 0);
int oldState = intent.getIntExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, 0);
if (newState == BluetoothA2dp.STATE_DISCONNECTED &&
oldState == BluetoothA2dp.STATE_CONNECTING) {
Log.i(TAG, "Failed to connect BT A2DP");
}
-
+
+ boolean transientState = !(newState == BluetoothA2dp.STATE_CONNECTED
+ || newState == BluetoothA2dp.STATE_DISCONNECTED);
+ mManager.getLocalDeviceManager().onProfileStateChanged(address, transientState);
+
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) {
mManager.getLocalDeviceManager().onBtClassChanged(address);
@@ -120,8 +120,7 @@ public class BluetoothEventRedirector {
IntentFilter filter = new IntentFilter();
// Bluetooth on/off broadcasts
- filter.addAction(BluetoothIntent.ENABLED_ACTION);
- filter.addAction(BluetoothIntent.DISABLED_ACTION);
+ filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
// Discovery broadcasts
filter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION);
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
index 3065b26..40bab2c 100644
--- a/src/com/android/settings/bluetooth/BluetoothNamePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
@@ -17,6 +17,7 @@
package com.android.settings.bluetooth;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -39,7 +40,14 @@ public class BluetoothNamePreference extends EditTextPreference {
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- setSummaryToName();
+ String action = intent.getAction();
+ if (action.equals(BluetoothIntent.NAME_CHANGED_ACTION)) {
+ setSummaryToName();
+ } else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) &&
+ (intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
+ BluetoothError.ERROR) == BluetoothDevice.BLUETOOTH_STATE_ON)) {
+ setSummaryToName();
+ }
}
};
@@ -53,7 +61,7 @@ public class BluetoothNamePreference extends EditTextPreference {
public void resume() {
IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothIntent.ENABLED_ACTION);
+ filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
filter.addAction(BluetoothIntent.NAME_CHANGED_ACTION);
getContext().registerReceiver(mReceiver, filter);
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 5adada3..e6ac5fd 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,11 +18,12 @@ package com.android.settings.bluetooth;
import com.android.settings.ProgressCategory;
import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
import java.util.List;
import java.util.WeakHashMap;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -117,8 +118,8 @@ public class BluetoothSettings extends PreferenceActivity
mLocalManager.startScanning(false);
- registerReceiver(mReceiver,
- new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+ registerReceiver(mReceiver,
+ new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION));
mLocalManager.setForegroundActivity(this);
}
@@ -248,12 +249,12 @@ public class BluetoothSettings extends PreferenceActivity
mDeviceList.setProgress(started);
}
- private void onBluetoothStateChanged(ExtendedBluetoothState bluetoothState) {
+ private void onBluetoothStateChanged(int bluetoothState) {
// When bluetooth is enabled (and we are in the activity, which we are),
// we should start a scan
- if (bluetoothState == ExtendedBluetoothState.ENABLED) {
+ if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON) {
mLocalManager.startScanning(false);
- } else if (bluetoothState == ExtendedBluetoothState.DISABLED) {
+ } else if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_OFF) {
mDeviceList.setProgress(false);
}
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
index a488540..eedae93 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
@@ -20,22 +20,23 @@ import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import android.app.AlertDialog;
-import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothClass;
-import android.bluetooth.IBluetoothDeviceCallback;
+import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
-import android.os.IBinder;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
+import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
/**
@@ -71,6 +72,173 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
*/
private boolean mIsConnectingErrorPossible;
+ // Max time to hold the work queue if we don't get or missed a response
+ // from the bt framework.
+ private static final long MAX_WAIT_TIME_FOR_FRAMEWORK = 25 * 1000;
+
+ private enum BluetoothCommand {
+ CONNECT, DISCONNECT,
+ }
+
+ class BluetoothJob {
+ final BluetoothCommand command; // CONNECT, DISCONNECT
+ final LocalBluetoothDevice device;
+ final Profile profile; // HEADSET, A2DP, etc
+ // 0 means this command was not been sent to the bt framework.
+ long timeSent;
+
+ public BluetoothJob(BluetoothCommand command,
+ LocalBluetoothDevice device, Profile profile) {
+ this.command = command;
+ this.device = device;
+ this.profile = profile;
+ this.timeSent = 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(command.name());
+ sb.append(" Address:").append(device.mAddress);
+ sb.append(" Profile:").append(profile.name());
+ sb.append(" TimeSent:");
+ if (timeSent == 0) {
+ sb.append("not yet");
+ } else {
+ sb.append(DateFormat.getTimeInstance().format(new Date(timeSent)));
+ }
+ return sb.toString();
+ }
+ }
+
+ /**
+ * We want to serialize connect and disconnect calls. http://b/170538
+ * This are some headsets that may have L2CAP resource limitation. We want
+ * to limit the bt bandwidth usage.
+ *
+ * A queue to keep track of asynchronous calls to the bt framework. The
+ * first item, if exist, should be in progress i.e. went to the bt framework
+ * already, waiting for a notification to come back. The second item and
+ * beyond have not been sent to the bt framework yet.
+ */
+ private static LinkedList<BluetoothJob> workQueue = new LinkedList<BluetoothJob>();
+
+ private void queueCommand(BluetoothJob job) {
+ Log.d(TAG, workQueue.toString());
+ synchronized (workQueue) {
+ boolean processNow = false;
+ long now = System.currentTimeMillis();
+
+ Iterator<BluetoothJob> it = workQueue.iterator();
+ while (it.hasNext()) {
+ BluetoothJob existingJob = it.next();
+
+ // Remove any pending CONNECTS when we receive a DISCONNECT
+ if (job.command == BluetoothCommand.DISCONNECT) {
+ if (existingJob.timeSent == 0
+ && existingJob.command == BluetoothCommand.CONNECT
+ && existingJob.device.mAddress.equals(job.device.mAddress)
+ && existingJob.profile == job.profile) {
+ it.remove();
+ continue;
+ }
+ }
+
+ // Defensive Code: Remove any job that older than a preset time.
+ // We never got a call back. It is better to have overlapping
+ // calls than to get stuck.
+ Log.d(TAG, "Age:" + (now - existingJob.timeSent));
+ if (existingJob.timeSent != 0
+ && (now - existingJob.timeSent) >= MAX_WAIT_TIME_FOR_FRAMEWORK) {
+ Log.w(TAG, "Timeout. Removing Job:" + existingJob.toString());
+ it.remove();
+ processNow = true;
+ continue;
+ }
+ }
+
+ // Add job to queue
+ Log.d(TAG, "Adding: " + job.toString());
+ workQueue.add(job);
+
+ // if there's nothing pending from before, send the command to bt
+ // framework immediately.
+ if (workQueue.size() == 1 || processNow) {
+ Log.d(TAG, "workQueue.size() == 1 || TimeOut -> process command now");
+ // If the failed to process, just drop it from the queue.
+ // There will be no callback to remove this from the queue.
+ processCommands();
+ }
+ }
+ }
+
+ private boolean processCommand(BluetoothJob job) {
+ boolean successful = false;
+ if (job.timeSent == 0) {
+ job.timeSent = System.currentTimeMillis();
+ switch (job.command) {
+ case CONNECT:
+ successful = connectInt(job.device, job.profile);
+ break;
+ case DISCONNECT:
+ successful = disconnectInt(job.device, job.profile);
+ break;
+ }
+
+ if (successful) {
+ Log.d(TAG, "Command sent successfully:" + job.toString());
+ } else {
+ Log.d(TAG, "Framework rejected command immediately:" + job.toString());
+ }
+
+ } else {
+ Log.d(TAG, "Job already has a sent time. Skip. " + job.toString());
+ }
+
+ return successful;
+ }
+
+ public void onProfileStateChanged() {
+ // Remove the first item and process the next one
+ BluetoothJob job = workQueue.poll();
+ if (job == null) {
+ Log.w(TAG, "Yikes, onProfileStateChanged called but job queue is empty");
+ } else if (job.device.mAddress != mAddress) {
+ Log.w(TAG, "Yikes, onProfileStateChanged called but the address differ. this.mAddress="
+ + mAddress + " workQueue.head=" + job.toString());
+ } else {
+ Log.d(TAG, "LocalBluetoothDevice.onProfileStateChanged() called. MAC addr matched");
+ }
+
+ processCommands();
+ }
+
+ /*
+ * This method is called in 2 places:
+ * 1) queryCommand() - when someone or something want to connect or
+ * disconnect
+ * 2) onProfileStateChanged() - when the framework sends an intent
+ * notification when it finishes processing a command
+ */
+ private void processCommands() {
+ Iterator<BluetoothJob> it = workQueue.iterator();
+ while (it.hasNext()) {
+ BluetoothJob job = it.next();
+ if (processCommand(job)) {
+ // Sent to bt framework. Done for now. Will remove this job
+ // from queue when we get an event
+ return;
+ } else {
+ /*
+ * If the command failed immediately, there will be no event
+ * callbacks. So delete the job immediately and move on to the
+ * next one
+ */
+ it.remove();
+ }
+ }
+ }
+
LocalBluetoothDevice(Context context, String address) {
mLocalManager = LocalBluetoothManager.getInstance(context);
if (mLocalManager == null) {
@@ -102,12 +270,19 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
}
public void disconnect(Profile profile) {
+ queueCommand(new BluetoothJob(BluetoothCommand.DISCONNECT, this, profile));
+ }
+
+ private boolean disconnectInt(LocalBluetoothDevice device, Profile profile) {
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- int status = profileManager.getConnectionStatus(mAddress);
+ int status = profileManager.getConnectionStatus(device.mAddress);
if (SettingsBtStatus.isConnectionStatusConnected(status)) {
- profileManager.disconnect(mAddress);
+ if (profileManager.disconnect(device.mAddress) == BluetoothDevice.RESULT_SUCCESS) {
+ return true;
+ }
}
+ return false;
}
public void askDisconnect() {
@@ -153,7 +328,7 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
if (profileManager.isPreferred(mAddress)) {
hasAtLeastOnePreferredProfile = true;
- connectInt(profile);
+ queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
}
}
@@ -173,27 +348,30 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
profileManager.setPreferred(mAddress, true);
- connectInt(profile);
+ queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
}
}
public void connect(Profile profile) {
// Reset the only-show-one-error-dialog tracking variable
mIsConnectingErrorPossible = true;
- connectInt(profile);
+ queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
}
- public void connectInt(Profile profile) {
- if (!ensurePaired()) return;
+ private boolean connectInt(LocalBluetoothDevice device, Profile profile) {
+ if (!device.ensurePaired()) return false;
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- int status = profileManager.getConnectionStatus(mAddress);
+ int status = profileManager.getConnectionStatus(device.mAddress);
if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
- if (profileManager.connect(mAddress) != BluetoothDevice.RESULT_SUCCESS) {
- Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
+ if (profileManager.connect(device.mAddress) == BluetoothDevice.RESULT_SUCCESS) {
+ return true;
}
+ Log.i(TAG, "Failed to connect " + profile.toString() + " to " + device.mName);
}
+ Log.i(TAG, "Not connected");
+ return false;
}
public void showConnectingError() {
@@ -228,6 +406,24 @@ public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
}
public void unpair() {
+ synchronized (workQueue) {
+ // Remove any pending commands for this device
+ boolean processNow = false;
+ Iterator<BluetoothJob> it = workQueue.iterator();
+ while (it.hasNext()) {
+ BluetoothJob job = it.next();
+ if (job.device.mAddress.equals(this.mAddress)) {
+ it.remove();
+ if (job.timeSent != 0) {
+ processNow = true;
+ }
+ }
+ }
+ if (processNow) {
+ processCommands();
+ }
+ }
+
BluetoothDevice manager = mLocalManager.getBluetoothManager();
switch (getBondState()) {
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
index 6bb2b4a..9527980 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
@@ -16,11 +16,8 @@
package com.android.settings.bluetooth;
-import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.util.Log;
-import android.widget.Toast;
-import android.content.Context;
import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
@@ -190,10 +187,13 @@ public class LocalBluetoothDeviceManager {
R.string.bluetooth_pairing_error_message);
}
- public synchronized void onProfileStateChanged(String address) {
+ public synchronized void onProfileStateChanged(String address, boolean transientState) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) return;
+ if (!transientState) {
+ device.onProfileStateChanged();
+ }
device.refresh();
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index 4671fac..1a848b2 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -25,6 +25,8 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
+import android.bluetooth.BluetoothIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -40,8 +42,6 @@ public class LocalBluetoothManager {
private static final String TAG = "LocalBluetoothManager";
static final boolean V = true;
- public static final String EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION =
- "com.android.settings.bluetooth.intent.action.EXTENDED_BLUETOOTH_STATE_CHANGED";
private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
private static LocalBluetoothManager INSTANCE;
@@ -60,8 +60,7 @@ public class LocalBluetoothManager {
private BluetoothEventRedirector mEventRedirector;
private BluetoothA2dp mBluetoothA2dp;
- public static enum ExtendedBluetoothState { ENABLED, ENABLING, DISABLED, DISABLING, UNKNOWN }
- private ExtendedBluetoothState mState = ExtendedBluetoothState.UNKNOWN;
+ private int mState = BluetoothError.ERROR;
private List<Callback> mCallbacks = new ArrayList<Callback>();
@@ -182,34 +181,27 @@ public class LocalBluetoothManager {
}
}
- public ExtendedBluetoothState getBluetoothState() {
+ public int getBluetoothState() {
- if (mState == ExtendedBluetoothState.UNKNOWN) {
+ if (mState == BluetoothError.ERROR) {
syncBluetoothState();
}
return mState;
}
- void setBluetoothStateInt(ExtendedBluetoothState state) {
+ void setBluetoothStateInt(int state) {
mState = state;
-
- /*
- * TODO: change to callback method. originally it was broadcast to
- * parallel the framework's method, but it just complicates things here.
- */
- // If this were a real API, I'd add as an extra
- mContext.sendBroadcast(new Intent(EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
-
- if (state == ExtendedBluetoothState.ENABLED || state == ExtendedBluetoothState.DISABLED) {
- mLocalDeviceManager.onBluetoothStateChanged(state == ExtendedBluetoothState.ENABLED);
+ if (state == BluetoothDevice.BLUETOOTH_STATE_ON ||
+ state == BluetoothDevice.BLUETOOTH_STATE_OFF) {
+ mLocalDeviceManager.onBluetoothStateChanged(state == BluetoothDevice.BLUETOOTH_STATE_ON);
}
}
private void syncBluetoothState() {
setBluetoothStateInt(mManager.isEnabled()
- ? ExtendedBluetoothState.ENABLED
- : ExtendedBluetoothState.DISABLED);
+ ? BluetoothDevice.BLUETOOTH_STATE_ON
+ : BluetoothDevice.BLUETOOTH_STATE_OFF);
}
public void setBluetoothEnabled(boolean enabled) {
@@ -219,8 +211,8 @@ public class LocalBluetoothManager {
if (wasSetStateSuccessful) {
setBluetoothStateInt(enabled
- ? ExtendedBluetoothState.ENABLING
- : ExtendedBluetoothState.DISABLING);
+ ? BluetoothDevice.BLUETOOTH_STATE_TURNING_ON
+ : BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF);
} else {
if (V) {
Log.v(TAG,
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index 50edf86..24563a7 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -72,19 +72,22 @@ public abstract class LocalBluetoothProfileManager {
/**
* Temporary method to fill profiles based on a device's class.
*
+ * NOTE: This list happens to define the connection order. We should put this logic in a more
+ * well known place when this method is no longer temporary.
+ *
* @param btClass The class
* @param profiles The list of profiles to fill
*/
public static void fill(int btClass, List<Profile> profiles) {
profiles.clear();
- if (BluetoothA2dp.doesClassMatchSink(btClass)) {
- profiles.add(Profile.A2DP);
- }
-
if (BluetoothHeadset.doesClassMatch(btClass)) {
profiles.add(Profile.HEADSET);
}
+
+ if (BluetoothA2dp.doesClassMatchSink(btClass)) {
+ profiles.add(Profile.A2DP);
+ }
}
protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
@@ -214,7 +217,7 @@ public abstract class LocalBluetoothProfileManager {
*/
String address = mService.getHeadsetAddress();
if (TextUtils.isEmpty(address)) return;
- mLocalManager.getLocalDeviceManager().onProfileStateChanged(address);
+ mLocalManager.getLocalDeviceManager().onProfileStateChanged(address, true);
}
});
}