FileDocCategorySizeDatePackage
BluetoothHeadsetService.javaAPI DocAndroid 1.5 API32511Wed May 06 22:42:46 BST 2009com.android.phone

BluetoothHeadsetService

public class BluetoothHeadsetService extends android.app.Service
Provides Bluetooth Headset and Handsfree profile, as a service in the Phone application.
hide

Fields Summary
private static final String
TAG
private static final boolean
DBG
private static final String
PREF_NAME
private static final String
PREF_LAST_HEADSET
private static final int
PHONE_STATE_CHANGED
private static final String
BLUETOOTH_ADMIN_PERM
private static final String
BLUETOOTH_PERM
private static boolean
sHasStarted
private android.bluetooth.BluetoothDevice
mBluetooth
private android.os.PowerManager
mPowerManager
private android.bluetooth.BluetoothAudioGateway
mAg
private android.bluetooth.HeadsetBase
mHeadset
private int
mState
private int
mHeadsetType
private BluetoothHandsfree
mBtHandsfree
private String
mHeadsetAddress
private LinkedList
mAutoConnectQueue
private com.android.internal.telephony.Call
mForegroundCall
private com.android.internal.telephony.Call
mRingingCall
private com.android.internal.telephony.Phone
mPhone
private final HeadsetPriority
mHeadsetPriority
private final android.os.Handler
mIncomingConnectionHandler
private final android.os.Handler
mStateChangeHandler
private final android.content.BroadcastReceiver
mBluetoothIntentReceiver
private static final int
RECONNECT_LAST_HEADSET
private android.os.Handler
mHandler
private static final int
SDP_RESULT
private static final int
RFCOMM_CONNECTED
private static final int
RFCOMM_ERROR
private static final short
HEADSET_UUID16
private static final short
HANDSFREE_UUID16
private long
mTimestamp
IBluetoothDeviceCallback.Stub
mDeviceCallback
private RfcommConnectThread
mConnectThread
Thread for RFCOMM connection Messages are sent to mConnectingStatusHandler as connection progresses.
private final android.os.Handler
mConnectingStatusHandler
Receives events from mConnectThread back in the main thread.
private final android.os.Handler
mConnectedStatusHandler
Receives events from a connected RFCOMM socket back in the main thread.
private final IBluetoothHeadset.Stub
mBinder
Handlers for incoming service calls
private static final String
DEBUG_AUTO_RECONNECT
If this property is false, then don't auto-reconnect BT headset
Constructors Summary
public BluetoothHeadsetService()


      
        mState = BluetoothHeadset.STATE_DISCONNECTED;
        mHeadsetType = BluetoothHandsfree.TYPE_UNKNOWN;
    
Methods Summary
private synchronized voidautoConnectHeadset()


        
        if (DBG && debugDontReconnect()) {
            return;
        }
        if (mBluetooth.isEnabled()) {
            try {
                mBinder.connectHeadset(null);
            } catch (RemoteException e) {}
        }
    
private booleandebugDontReconnect()


       
        return (!SystemProperties.getBoolean(DEBUG_AUTO_RECONNECT, true));
    
private voiddoHandsfreeSdp()

        if (DBG) log("Handsfree SDP request");
        mTimestamp = System.currentTimeMillis();
        mHeadsetType = BluetoothHandsfree.TYPE_HANDSFREE;
        if (!mBluetooth.getRemoteServiceChannel(mHeadsetAddress, HANDSFREE_UUID16,
                    mDeviceCallback)) {
            Log.e(TAG, "Could not start handsfree SDP query");
            setState(BluetoothHeadset.STATE_DISCONNECTED, BluetoothHeadset.RESULT_FAILURE);
        }
    
private voiddoHeadsetSdp()

        if (DBG) log("Headset SDP request");
        mTimestamp = System.currentTimeMillis();
        mHeadsetType = BluetoothHandsfree.TYPE_HEADSET;
        if (!mBluetooth.getRemoteServiceChannel(mHeadsetAddress, HEADSET_UUID16,
                    mDeviceCallback)) {
            Log.e(TAG, "Could not start headset SDP query");
            setState(BluetoothHeadset.STATE_DISCONNECTED, BluetoothHeadset.RESULT_FAILURE);
        }
    
private synchronized booleandoNextAutoConnect()

        if (mAutoConnectQueue == null || mAutoConnectQueue.size() == 0) {
            mAutoConnectQueue = null;
            return false;
        }
        mHeadsetAddress = mAutoConnectQueue.removeFirst();
        if (DBG) log("pulled " + mHeadsetAddress + " off auto-connect queue");
        setState(BluetoothHeadset.STATE_CONNECTING);
        doHandsfreeSdp();

        return true;
    
private static voidlog(java.lang.String msg)

        Log.d(TAG, msg);
    
public android.os.IBinderonBind(android.content.Intent intent)


    
        
        return mBinder;
    
public voidonCreate()

        super.onCreate();
        mBluetooth = (BluetoothDevice)getSystemService(Context.BLUETOOTH_SERVICE);
        mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
        mBtHandsfree = PhoneApp.getInstance().getBluetoothHandsfree();
        mAg = new BluetoothAudioGateway(mBluetooth);
        mPhone = PhoneFactory.getDefaultPhone();
        mRingingCall = mPhone.getRingingCall();
        mForegroundCall = mPhone.getForegroundCall();
        if (mBluetooth.isEnabled()) {
            mHeadsetPriority.load();
        }
        IntentFilter filter = new IntentFilter(
                BluetoothIntent.REMOTE_DEVICE_DISCONNECT_REQUESTED_ACTION);
        filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
        filter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
        filter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
        registerReceiver(mBluetoothIntentReceiver, filter);

        mPhone.registerForPhoneStateChanged(mStateChangeHandler, PHONE_STATE_CHANGED, null);
    
public voidonDestroy()


    
       
        super.onDestroy();
        if (DBG) log("Stopping BluetoothHeadsetService");
        unregisterReceiver(mBluetoothIntentReceiver);
        mBtHandsfree.onBluetoothDisabled();
        mAg.stop();
        sHasStarted = false;
        setState(BluetoothHeadset.STATE_DISCONNECTED, BluetoothHeadset.RESULT_CANCELED);
        mHeadsetType = BluetoothHandsfree.TYPE_UNKNOWN;
    
public voidonStart(android.content.Intent intent, int startId)

         if (mBluetooth == null) {
            Log.w(TAG, "Stopping BluetoothHeadsetService: device does not have BT");
            stopSelf();
        } else {
            if (!sHasStarted) {
                if (DBG) log("Starting BluetoothHeadsetService");
                if (mBluetooth.isEnabled()) {
                    mAg.start(mIncomingConnectionHandler);
                    mBtHandsfree.onBluetoothEnabled();
                    // BT might have only just started, wait 6 seconds until
                    // SDP records are registered before reconnecting headset
                    mHandler.sendMessageDelayed(mHandler.obtainMessage(RECONNECT_LAST_HEADSET),
                            6000);
                }
                sHasStarted = true;
            }
        }
    
private voidsetState(int state)


        
        setState(state, BluetoothHeadset.RESULT_SUCCESS);
    
private synchronized voidsetState(int state, int result)

        if (state != mState) {
            if (DBG) log("Headset state " + mState + " -> " + state + ", result = " + result);
            if (mState == BluetoothHeadset.STATE_CONNECTED) {
                // no longer connected - make sure BT audio is taken down
                mBtHandsfree.audioOff();
                mBtHandsfree.disconnectHeadset();
            }
            Intent intent = new Intent(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
            intent.putExtra(BluetoothIntent.HEADSET_PREVIOUS_STATE, mState);
            mState = state;
            intent.putExtra(BluetoothIntent.HEADSET_STATE, mState);
            intent.putExtra(BluetoothIntent.ADDRESS, mHeadsetAddress);
            sendBroadcast(intent, BLUETOOTH_PERM);
            if (mState == BluetoothHeadset.STATE_DISCONNECTED) {
                mHeadset = null;
                mHeadsetAddress = null;
                mHeadsetType = BluetoothHandsfree.TYPE_UNKNOWN;
                if (mAutoConnectQueue != null) {
                    doNextAutoConnect();
                }
            } else if (mState == BluetoothHeadset.STATE_CONNECTED) {
                mAutoConnectQueue = null;  // cancel further auto-connection
                mHeadsetPriority.bump(mHeadsetAddress.toUpperCase());
            }
        }