BondStateMachine.java revision fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5
1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 2ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * Copyright (C) 2012 Google Inc. 3ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 4ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 5ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth.btservice; 6ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 7ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter; 84f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport android.bluetooth.BluetoothProfile; 9ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothDevice; 104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.a2dp.A2dpService; 114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.hid.HidService; 124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.hfp.HeadsetService; 13ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context; 14ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent; 15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message; 16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log; 17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.Utils; 19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State; 21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine; 22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.ArrayList; 24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/** 26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State. 27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States: 28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link StableState} : No device is in bonding / unbonding state. 29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link PendingCommandState} : Some device is in bonding / unbonding state. 30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT) This class can be removed and this logic moved to the stack. 31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class BondStateMachine extends StateMachine { 34fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie private static final boolean DBG = false; 35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private static final String TAG = "BluetoothBondStateMachine"; 36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int CREATE_BOND = 1; 38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int CANCEL_BOND = 2; 39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int REMOVE_BOND = 3; 40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int BONDING_STATE_CHANGE = 4; 41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 42986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan static final int BOND_STATE_NONE = 0; 43986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan static final int BOND_STATE_BONDING = 1; 44986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan static final int BOND_STATE_BONDED = 2; 45986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan 466654f5c903de510a70f9e72cd5ad7837b615d93ffredc private AdapterService mAdapterService; 476654f5c903de510a70f9e72cd5ad7837b615d93ffredc private AdapterProperties mAdapterProperties; 486654f5c903de510a70f9e72cd5ad7837b615d93ffredc private RemoteDevices mRemoteDevices; 49179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy private BluetoothAdapter mAdapter; 50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private PendingCommandState mPendingCommandState = new PendingCommandState(); 52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private StableState mStableState = new StableState(); 53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 546893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville private BondStateMachine(AdapterService service, 5531ba132491053bc86d419a7d51fc04af3299c076fredc AdapterProperties prop, RemoteDevices remoteDevices) { 56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh super("BondStateMachine:"); 57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mStableState); 58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mPendingCommandState); 5931ba132491053bc86d419a7d51fc04af3299c076fredc mRemoteDevices = remoteDevices; 60ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh mAdapterService = service; 61ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh mAdapterProperties = prop; 62179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy mAdapter = BluetoothAdapter.getDefaultAdapter(); 636654f5c903de510a70f9e72cd5ad7837b615d93ffredc setInitialState(mStableState); 646654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 656654f5c903de510a70f9e72cd5ad7837b615d93ffredc 666893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville public static BondStateMachine make(AdapterService service, 676893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville AdapterProperties prop, RemoteDevices remoteDevices) { 686893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville Log.d(TAG, "make"); 696893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville BondStateMachine bsm = new BondStateMachine(service, prop, remoteDevices); 706893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville bsm.start(); 716893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville return bsm; 726893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville } 736893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville 7415d36984a79d6e35c659edb0efdf929f0b526bd5Fred public void doQuit() { 7515d36984a79d6e35c659edb0efdf929f0b526bd5Fred quitNow(); 7615d36984a79d6e35c659edb0efdf929f0b526bd5Fred } 7715d36984a79d6e35c659edb0efdf929f0b526bd5Fred 786654f5c903de510a70f9e72cd5ad7837b615d93ffredc public void cleanup() { 7974ae04c73312403e89db0f8e9bd9601d403b4783fredc mAdapterService = null; 8074ae04c73312403e89db0f8e9bd9601d403b4783fredc mRemoteDevices = null; 8174ae04c73312403e89db0f8e9bd9601d403b4783fredc mAdapterProperties = null; 82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class StableState extends State { 85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 877aab11364743cbca6eeefecbbde19f0434aff362fredc infoLog("StableState(): Entering Off State"); 88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 92b5cc776c9353a203cdde97e62b25f05d9633d14cfredc 93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice dev = (BluetoothDevice)msg.obj; 946654f5c903de510a70f9e72cd5ad7837b615d93ffredc 95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch(msg.what) { 966654f5c903de510a70f9e72cd5ad7837b615d93ffredc 97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case CREATE_BOND: 98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh createBond(dev, true); 99ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 100ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case REMOVE_BOND: 101ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh removeBond(dev, true); 102ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 103ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case BONDING_STATE_CHANGE: 104986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan int newState = msg.arg1; 105986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan /* if incoming pairing, transition to pending state */ 106986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan if (newState == BluetoothDevice.BOND_BONDING) 107986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan { 108ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan sendIntent(dev, newState, 0); 109986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan transitionTo(mPendingCommandState); 110986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan } 111986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan else 112986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan { 113986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan Log.e(TAG, "In stable state, received invalid newState: " + newState); 114986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan } 115986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan break; 116986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan 117986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan case CANCEL_BOND: 118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Received unhandled state: " + msg.what); 120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class PendingCommandState extends State { 128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private final ArrayList<BluetoothDevice> mDevices = 129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh new ArrayList<BluetoothDevice>(); 130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Entering PendingCommandState State"); 134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj; 135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 1397aab11364743cbca6eeefecbbde19f0434aff362fredc 140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice dev = (BluetoothDevice)msg.obj; 141aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera boolean result = false; 142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (mDevices.contains(dev) && 143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE) { 144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh deferMessage(msg); 145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch (msg.what) { 149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case CREATE_BOND: 150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = createBond(dev, false); 151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case REMOVE_BOND: 153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = removeBond(dev, false); 154ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case CANCEL_BOND: 156ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = cancelBond(dev); 157ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case BONDING_STATE_CHANGE: 159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int newState = msg.arg1; 160ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan int reason = getUnbondReasonFromHALCode(msg.arg2); 161ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan sendIntent(dev, newState, reason); 162aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera if(newState != BluetoothDevice.BOND_BONDING ) 163986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan { 164986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan /* this is either none/bonded, remove and transition */ 165986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan result = !mDevices.remove(dev); 166986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan if (mDevices.isEmpty()) { 167c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // Whenever mDevices is empty, then we need to 168c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // set result=false. Else, we will end up adding 169c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // the device to the list again. This prevents us 170c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // from pairing with a device that we just unpaired 171c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy result = false; 172986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan transitionTo(mStableState); 173986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan } 1744f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (newState == BluetoothDevice.BOND_NONE) 1754f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta { 1764f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta // Set the profile Priorities to undefined 1774f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta clearProfilePriorty(dev); 1784f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1794f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta else if (newState == BluetoothDevice.BOND_BONDED) 1804f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta { 1814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta // Restore the profile priorty settings 1824f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta setProfilePriorty(dev); 1834f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 185aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera else if(!mDevices.contains(dev)) 186aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera result=true; 187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Received unhandled event:" + msg.what); 190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (result) mDevices.add(dev); 193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private boolean cancelBond(BluetoothDevice dev) { 199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (dev.getBondState() == BluetoothDevice.BOND_BONDING) { 200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); 201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!mAdapterService.cancelBondNative(addr)) { 202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Unexpected error while cancelling bond:"); 203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private boolean removeBond(BluetoothDevice dev, boolean transition) { 211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (dev.getBondState() == BluetoothDevice.BOND_BONDED) { 212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); 213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!mAdapterService.removeBondNative(addr)) { 214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Unexpected error while removing bond:"); 215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (transition) transitionTo(mPendingCommandState); 217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private boolean createBond(BluetoothDevice dev, boolean transition) { 225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (dev.getBondState() == BluetoothDevice.BOND_NONE) { 226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Bond address is:" + dev); 227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); 228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!mAdapterService.createBondNative(addr)) { 229ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan sendIntent(dev, BluetoothDevice.BOND_NONE, 230ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan BluetoothDevice.UNBOND_REASON_REMOVED); 231986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan return false; 232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else if (transition) { 233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh transitionTo(mPendingCommandState); 234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 240ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan private void sendIntent(BluetoothDevice device, int newState, int reason) { 241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device); 242179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy int oldState = BluetoothDevice.BOND_NONE; 243179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy if (devProp != null) { 244179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy oldState = devProp.getBondState(); 245179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy } 246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (oldState == newState) return; 247179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy mAdapterProperties.onBondStateChanged(device, newState); 2482f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan 249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState); 252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState); 253ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan if (newState == BluetoothDevice.BOND_NONE) 254ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan intent.putExtra(BluetoothDevice.EXTRA_REASON, reason); 25574ae04c73312403e89db0f8e9bd9601d403b4783fredc mAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM); 256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Bond State Change Intent:" + device + " OldState: " + oldState 257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh + " NewState: " + newState); 258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh void bondStateChangeCallback(int status, byte[] address, int newState) { 261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice device = mRemoteDevices.getDevice(address); 262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (device == null) { 264179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy infoLog("No record of the device:" + device); 265179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy // This device will be added as part of the BONDING_STATE_CHANGE intent processing 266179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy // in sendIntent above 267179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address)); 268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device 271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh + " newState: " + newState); 272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Message msg = obtainMessage(BONDING_STATE_CHANGE); 274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh msg.obj = device; 275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 276986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan if (newState == BOND_STATE_BONDED) 277986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan msg.arg1 = BluetoothDevice.BOND_BONDED; 278986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan else if (newState == BOND_STATE_BONDING) 279986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan msg.arg1 = BluetoothDevice.BOND_BONDING; 280986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan else 281986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan msg.arg1 = BluetoothDevice.BOND_NONE; 282ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan msg.arg2 = status; 283986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan 284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sendMessage(msg); 285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 2874f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private void setProfilePriorty (BluetoothDevice device){ 2884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HidService hidService = HidService.getHidService(); 2894f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta A2dpService a2dpService = A2dpService.getA2dpService(); 2904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HeadsetService headsetService = HeadsetService.getHeadsetService(); 2914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 2924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if ((hidService != null) && 2934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 2944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta hidService.setPriority(device,BluetoothProfile.PRIORITY_ON); 2954f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 2964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 2974f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if ((a2dpService != null) && 2984f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 2994f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON); 3004f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if ((headsetService != null) && 3034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 3044f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON); 3054f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3084f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private void clearProfilePriorty (BluetoothDevice device){ 3094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HidService hidService = HidService.getHidService(); 3104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta A2dpService a2dpService = A2dpService.getA2dpService(); 3114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HeadsetService headsetService = HeadsetService.getHeadsetService(); 3124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (hidService != null) 3144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta hidService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED); 3154f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if(a2dpService != null) 3164f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta a2dpService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED); 3174f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if(headsetService != null) 3184f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta headsetService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED); 3194f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3204f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private void infoLog(String msg) { 322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.i(TAG, msg); 323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private void errorLog(String msg) { 326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, msg); 327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 32815d36984a79d6e35c659edb0efdf929f0b526bd5Fred 329ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan private int getUnbondReasonFromHALCode (int reason) { 330ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan if (reason == AbstractionLayer.BT_STATUS_SUCCESS) 331ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.BOND_SUCCESS; 332ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan else if (reason == AbstractionLayer.BT_STATUS_RMT_DEV_DOWN) 333ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN; 334ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan else if (reason == AbstractionLayer.BT_STATUS_AUTH_FAILURE) 335ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.UNBOND_REASON_AUTH_FAILED; 336ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan 337ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan /* default */ 338ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.UNBOND_REASON_REMOVED; 339ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan } 340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 341