New public APIs for BluetoothA2dp and BluetoothHeadset profiles.
Change-Id: I1cc4b109542dfd62473cb95797c8c3d0d15725f4
diff --git a/framework/java/android/bluetooth/BluetoothHeadset.java b/framework/java/android/bluetooth/BluetoothHeadset.java
index be21d46..0496b1f 100644
--- a/framework/java/android/bluetooth/BluetoothHeadset.java
+++ b/framework/java/android/bluetooth/BluetoothHeadset.java
@@ -18,6 +18,8 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -26,63 +28,66 @@
import android.os.IBinder;
import android.util.Log;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
/**
- * The Android Bluetooth API is not finalized, and *will* change. Use at your
- * own risk.
- *
* Public API for controlling the Bluetooth Headset Service. This includes both
- * Bluetooth Headset and Handsfree (v1.5) profiles. The Headset service will
- * attempt a handsfree connection first, and fall back to headset.
+ * Bluetooth Headset and Handsfree (v1.5) profiles.
*
- * BluetoothHeadset is a proxy object for controlling the Bluetooth Headset
+ * <p>BluetoothHeadset is a proxy object for controlling the Bluetooth Headset
* Service via IPC.
*
- * Creating a BluetoothHeadset object will create a binding with the
- * BluetoothHeadset service. Users of this object should call close() when they
- * are finished with the BluetoothHeadset, so that this proxy object can unbind
- * from the service.
+ * <p> Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothHeadset proxy object. Use
+ * {@link BluetoothAdapter#closeProfileProxy} to close the service connection.
*
- * This BluetoothHeadset object is not immediately bound to the
- * BluetoothHeadset service. Use the ServiceListener interface to obtain a
- * notification when it is bound, this is especially important if you wish to
- * immediately call methods on BluetoothHeadset after construction.
- *
- * Android only supports one connected Bluetooth Headset at a time.
- *
- * @hide
+ * <p> Android only supports one connected Bluetooth Headset at a time.
+ * Each method is protected with its appropriate permission.
*/
-public final class BluetoothHeadset {
-
+public final class BluetoothHeadset implements BluetoothProfile {
private static final String TAG = "BluetoothHeadset";
private static final boolean DBG = false;
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_STATE_CHANGED =
- "android.bluetooth.headset.action.STATE_CHANGED";
/**
- * TODO(API release): Consider incorporating as new state in
- * HEADSET_STATE_CHANGED
+ * Intent used to broadcast the change in connection state of the Headset
+ * profile.
+ *
+ * <p>This intent will have 3 extras:
+ * {@link #EXTRA_STATE} - The current state of the profile.
+ * {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile
+ * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device.
+ *
+ * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
+
+ /**
+ * Intent used to broadcast the change in the Audio Connection state of the
+ * A2DP profile.
+ *
+ * <p>This intent will have 3 extras:
+ * {@link #EXTRA_STATE} - The current state of the profile.
+ * {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile
+ * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device.
+ *
+ * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_AUDIO_STATE_CHANGED =
- "android.bluetooth.headset.action.AUDIO_STATE_CHANGED";
- public static final String EXTRA_STATE =
- "android.bluetooth.headset.extra.STATE";
- public static final String EXTRA_PREVIOUS_STATE =
- "android.bluetooth.headset.extra.PREVIOUS_STATE";
- public static final String EXTRA_AUDIO_STATE =
- "android.bluetooth.headset.extra.AUDIO_STATE";
+ "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
- /** Extra to be used with the Headset State change intent.
- * This will be used only when Headset state changes to
- * {@link #STATE_DISCONNECTED} from any previous state.
- * This extra field is optional and will be used when
- * we have deterministic information regarding whether
- * the disconnect was initiated by the remote device or
- * by the local adapter.
- */
- public static final String EXTRA_DISCONNECT_INITIATOR =
- "android.bluetooth.headset.extra.DISCONNECT_INITIATOR";
/**
* Broadcast Action: Indicates a headset has posted a vendor-specific event.
@@ -124,100 +129,47 @@
public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
"android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
+ /*
+ * Headset state when SCO audio is connected
+ * This state can be one of
+ * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
+ * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
+ */
+ public static final int STATE_AUDIO_CONNECTED = 10;
/**
- * TODO(API release): Consider incorporating as new state in
- * HEADSET_STATE_CHANGED
+ * Headset state when SCO audio is NOT connected
+ * This state can be one of
+ * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
+ * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
*/
+ public static final int STATE_AUDIO_DISCONNECTED = 11;
+
+
+ private Context mContext;
+ private ServiceListener mServiceListener;
private IBluetoothHeadset mService;
- private final Context mContext;
- private final ServiceListener mServiceListener;
-
- /** There was an error trying to obtain the state */
- public static final int STATE_ERROR = -1;
- /** No headset currently connected */
- public static final int STATE_DISCONNECTED = 0;
- /** Connection attempt in progress */
- public static final int STATE_CONNECTING = 1;
- /** A headset is currently connected */
- public static final int STATE_CONNECTED = 2;
-
- /** A SCO audio channel is not established */
- public static final int AUDIO_STATE_DISCONNECTED = 0;
- /** A SCO audio channel is established */
- public static final int AUDIO_STATE_CONNECTED = 1;
-
- public static final int RESULT_FAILURE = 0;
- public static final int RESULT_SUCCESS = 1;
- /** Connection canceled before completion. */
- public static final int RESULT_CANCELED = 2;
-
- /** Values for {@link #EXTRA_DISCONNECT_INITIATOR} */
- public static final int REMOTE_DISCONNECT = 0;
- public static final int LOCAL_DISCONNECT = 1;
-
-
- /** Default priority for headsets that for which we will accept
- * inconing connections and auto-connect */
- public static final int PRIORITY_AUTO_CONNECT = 1000;
- /** Default priority for headsets that for which we will accept
- * inconing connections but not auto-connect */
- public static final int PRIORITY_ON = 100;
- /** Default priority for headsets that should not be auto-connected
- * and not allow incoming connections. */
- public static final int PRIORITY_OFF = 0;
- /** Default priority when not set or when the device is unpaired */
- public static final int PRIORITY_UNDEFINED = -1;
-
- /**
- * An interface for notifying BluetoothHeadset IPC clients when they have
- * been connected to the BluetoothHeadset service.
- */
- public interface ServiceListener {
- /**
- * Called to notify the client when this proxy object has been
- * connected to the BluetoothHeadset service. Clients must wait for
- * this callback before making IPC calls on the BluetoothHeadset
- * service.
- */
- public void onServiceConnected();
-
- /**
- * Called to notify the client that this proxy object has been
- * disconnected from the BluetoothHeadset service. Clients must not
- * make IPC calls on the BluetoothHeadset service after this callback.
- * This callback will currently only occur if the application hosting
- * the BluetoothHeadset service, but may be called more often in future.
- */
- public void onServiceDisconnected();
- }
+ BluetoothAdapter mAdapter;
/**
* Create a BluetoothHeadset proxy object.
*/
- public BluetoothHeadset(Context context, ServiceListener l) {
+ /*package*/ BluetoothHeadset(Context context, ServiceListener l) {
mContext = context;
mServiceListener = l;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth Headset Service");
}
}
- protected void finalize() throws Throwable {
- try {
- close();
- } finally {
- super.finalize();
- }
- }
-
/**
* Close the connection to the backing service.
* Other public functions of BluetoothHeadset will return default error
* results once close() has been called. Multiple invocations of close()
* are ok.
*/
- public synchronized void close() {
+ /*package*/ synchronized void close() {
if (DBG) log("close()");
if (mConnection != null) {
mContext.unbindService(mConnection);
@@ -226,190 +178,212 @@
}
/**
- * Get the current state of the Bluetooth Headset service.
- * @return One of the STATE_ return codes, or STATE_ERROR if this proxy
- * object is currently not connected to the Headset service.
+ * {@inheritDoc}
+ * @hide
*/
- public int getState(BluetoothDevice device) {
- if (DBG) log("getState()");
- if (mService != null) {
+ public boolean connect(BluetoothDevice device) {
+ if (DBG) log("connect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
try {
- return mService.getState(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ return mService.connect(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
- return BluetoothHeadset.STATE_ERROR;
- }
-
- /**
- * Get the BluetoothDevice for the current headset.
- * @return current headset, or null if not in connected or connecting
- * state, or if this proxy object is not connected to the Headset
- * service.
- */
- public BluetoothDevice getCurrentHeadset() {
- if (DBG) log("getCurrentHeadset()");
- if (mService != null) {
- try {
- return mService.getCurrentHeadset();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
- }
- return null;
- }
-
- /**
- * Request to initiate a connection to a headset.
- * This call does not block. Fails if a headset is already connecting
- * or connected.
- * Initiates auto-connection if device is null. Tries to connect to all
- * devices with priority greater than PRIORITY_AUTO in descending order.
- * @param device device to connect to, or null to auto-connect last connected
- * headset
- * @return false if there was a problem initiating the connection
- * procedure, and no further HEADSET_STATE_CHANGED intents
- * will be expected.
- */
- public boolean connectHeadset(BluetoothDevice device) {
- if (DBG) log("connectHeadset(" + device + ")");
- if (mService != null) {
- try {
- if (mService.connectHeadset(device)) {
- return true;
- }
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
- }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
/**
- * Returns true if the specified headset is connected (does not include
- * connecting). Returns false if not connected, or if this proxy object
- * if not currently connected to the headset service.
+ * {@inheritDoc}
+ * @hide
*/
- public boolean isConnected(BluetoothDevice device) {
- if (DBG) log("isConnected(" + device + ")");
- if (mService != null) {
+ public boolean disconnect(BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
try {
- return mService.isConnected(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ return mService.disconnect(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
/**
- * Disconnects the current headset. Currently this call blocks, it may soon
- * be made asynchornous. Returns false if this proxy object is
- * not currently connected to the Headset service.
+ * {@inheritDoc}
*/
- public boolean disconnectHeadset(BluetoothDevice device) {
- if (DBG) log("disconnectHeadset()");
- if (mService != null) {
+ public Set<BluetoothDevice> getConnectedDevices() {
+ if (DBG) log("getConnectedDevices()");
+ if (mService != null && isEnabled()) {
try {
- mService.disconnectHeadset(device);
- return true;
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ return toDeviceSet(mService.getConnectedDevices());
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return toDeviceSet(new BluetoothDevice[0]);
+ }
}
- return false;
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return toDeviceSet(new BluetoothDevice[0]);
}
/**
- * Start BT Voice Recognition mode, and set up Bluetooth audio path.
- * Returns false if there is no headset connected, or if the
- * connected headset does not support voice recognition, or on
- * error.
+ * {@inheritDoc}
*/
- public boolean startVoiceRecognition() {
- if (DBG) log("startVoiceRecognition()");
- if (mService != null) {
+ public Set<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (DBG) log("getDevicesMatchingStates()");
+ if (mService != null && isEnabled()) {
try {
- return mService.startVoiceRecognition();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ return toDeviceSet(mService.getDevicesMatchingConnectionStates(states));
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return toDeviceSet(new BluetoothDevice[0]);
+ }
}
- return false;
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return toDeviceSet(new BluetoothDevice[0]);
}
/**
- * Stop BT Voice Recognition mode, and shut down Bluetooth audio path.
- * Returns false if there is no headset connected, or the connected
- * headset is not in voice recognition mode, or on error.
+ * {@inheritDoc}
*/
- public boolean stopVoiceRecognition() {
- if (DBG) log("stopVoiceRecognition()");
- if (mService != null) {
+ public int getConnectionState(BluetoothDevice device) {
+ if (DBG) log("getConnectionState(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
try {
- return mService.stopVoiceRecognition();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ return mService.getConnectionState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
}
- return false;
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
}
/**
- * Set priority of headset.
- * Priority is a non-negative integer. By default paired headsets will have
- * a priority of PRIORITY_AUTO, and unpaired headset PRIORITY_NONE (0).
- * Headsets with priority greater than zero will be auto-connected, and
- * incoming connections will be accepted (if no other headset is
- * connected).
- * Auto-connection occurs at the following events: boot, incoming phone
- * call, outgoing phone call.
- * Headsets with priority equal to zero, or that are unpaired, are not
- * auto-connected.
- * Incoming connections are ignored regardless of priority if there is
- * already a headset connected.
- * @param device paired headset
- * @param priority Integer priority, for example PRIORITY_AUTO or
- * PRIORITY_NONE
- * @return true if successful, false if there was some error
+ * {@inheritDoc}
+ * @hide
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null) {
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF &&
+ priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
+ }
try {
return mService.setPriority(device, priority);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
/**
- * Get priority of headset.
- * @param device headset
- * @return non-negative priority, or negative error code on error
+ * {@inheritDoc}
+ * @hide
*/
public int getPriority(BluetoothDevice device) {
if (DBG) log("getPriority(" + device + ")");
- if (mService != null) {
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
try {
return mService.getPriority(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return PRIORITY_OFF;
+ }
}
- return -1;
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return PRIORITY_OFF;
+ }
+
+ /**
+ * Start Bluetooth voice recognition. This methods sends the voice
+ * recognition AT command to the headset and establishes the
+ * audio connection.
+ *
+ * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
+ * {@link #EXTRA_STATE} will be set to {@link #STATE_AUDIO_CONNECTED}
+ * when the audio connection is established.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+ *
+ * @param device Bluetooth headset
+ * @return false if there is no headset connected of if the
+ * connected headset doesn't support voice recognition
+ * or on error, true otherwise
+ */
+ public boolean startVoiceRecognition(BluetoothDevice device) {
+ if (DBG) log("startVoiceRecognition()");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.startVoiceRecognition(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
+ * Stop Bluetooth Voice Recognition mode, and shut down the
+ * Bluetooth audio path.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+ *
+ * @param device Bluetooth headset
+ * @return false if there is no headset connected
+ * or on error, true otherwise
+ */
+ public boolean stopVoiceRecognition(BluetoothDevice device) {
+ if (DBG) log("stopVoiceRecognition()");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.stopVoiceRecognition(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
+ * Check if Bluetooth SCO audio is connected.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+ *
+ * @param device Bluetooth headset
+ * @return true if SCO is connected,
+ * false otherwise or on error
+ */
+ public boolean isAudioConnected(BluetoothDevice device) {
+ if (DBG) log("isAudioConnected()");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.isAudioConnected(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
/**
@@ -420,24 +394,29 @@
* boot. This is a good indicator for spammy headset/handsfree units that
* can keep the device awake by polling for cellular status updates. As a
* rule of thumb, each AT command prevents the CPU from sleeping for 500 ms
+ *
+ * @param device the bluetooth headset.
* @return monotonically increasing battery usage hint, or a negative error
* code on error
* @hide
*/
- public int getBatteryUsageHint() {
+ public int getBatteryUsageHint(BluetoothDevice device) {
if (DBG) log("getBatteryUsageHint()");
- if (mService != null) {
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
try {
- return mService.getBatteryUsageHint();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ return mService.getBatteryUsageHint(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
return -1;
}
+
/**
* Indicates if current platform supports voice dialing over bluetooth SCO.
+ *
* @return true if voice dialing over bluetooth is supported, false otherwise.
* @hide
*/
@@ -448,11 +427,13 @@
/**
* Cancel the outgoing connection.
+ * Note: This is an internal function and shouldn't be exposed
+ *
* @hide
*/
public boolean cancelConnectThread() {
if (DBG) log("cancelConnectThread");
- if (mService != null) {
+ if (mService != null && isEnabled()) {
try {
return mService.cancelConnectThread();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
@@ -465,11 +446,13 @@
/**
* Accept the incoming connection.
+ * Note: This is an internal function and shouldn't be exposed
+ *
* @hide
*/
public boolean acceptIncomingConnect(BluetoothDevice device) {
if (DBG) log("acceptIncomingConnect");
- if (mService != null) {
+ if (mService != null && isEnabled()) {
try {
return mService.acceptIncomingConnect(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
@@ -481,12 +464,14 @@
}
/**
- * Create the connect thread the incoming connection.
+ * Create the connect thread for the incoming connection.
+ * Note: This is an internal function and shouldn't be exposed
+ *
* @hide
*/
public boolean createIncomingConnect(BluetoothDevice device) {
if (DBG) log("createIncomingConnect");
- if (mService != null) {
+ if (mService != null && isEnabled()) {
try {
return mService.createIncomingConnect(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
@@ -500,11 +485,12 @@
/**
* Connect to a Bluetooth Headset.
* Note: This is an internal function and shouldn't be exposed
+ *
* @hide
*/
public boolean connectHeadsetInternal(BluetoothDevice device) {
if (DBG) log("connectHeadsetInternal");
- if (mService != null) {
+ if (mService != null && isEnabled()) {
try {
return mService.connectHeadsetInternal(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
@@ -518,11 +504,12 @@
/**
* Disconnect a Bluetooth Headset.
* Note: This is an internal function and shouldn't be exposed
+ *
* @hide
*/
public boolean disconnectHeadsetInternal(BluetoothDevice device) {
if (DBG) log("disconnectHeadsetInternal");
- if (mService != null) {
+ if (mService != null && isEnabled()) {
try {
return mService.disconnectHeadsetInternal(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
@@ -532,23 +519,61 @@
}
return false;
}
+
+ /**
+ * Set the audio state of the Headset.
+ * Note: This is an internal function and shouldn't be exposed
+ *
+ * @hide
+ */
+ public boolean setAudioState(BluetoothDevice device, int state) {
+ if (DBG) log("setAudioState");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.setAudioState(device, state);
+ } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ return false;
+ }
+
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothHeadset.Stub.asInterface(service);
+
if (mServiceListener != null) {
- mServiceListener.onServiceConnected();
+ mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected();
+ mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
}
}
};
+ private boolean isEnabled() {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+ return false;
+ }
+
+ private boolean isValidDevice(BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
+ }
+
+ private Set<BluetoothDevice> toDeviceSet(BluetoothDevice[] devices) {
+ return Collections.unmodifiableSet(
+ new HashSet<BluetoothDevice>(Arrays.asList(devices)));
+ }
+
private static void log(String msg) {
Log.d(TAG, msg);
}