1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License. 6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at 7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and 14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License. 15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth.btservice; 18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter; 204f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport android.bluetooth.BluetoothProfile; 21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothDevice; 224f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.a2dp.A2dpService; 234f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.hid.HidService; 244f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.hfp.HeadsetService; 25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context; 26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent; 27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message; 28bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xuimport android.os.UserHandle; 29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log; 30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.Utils; 32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State; 34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine; 35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.ArrayList; 37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/** 39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State. 40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States: 41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link StableState} : No device is in bonding / unbonding state. 42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link PendingCommandState} : Some device is in bonding / unbonding state. 43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT) This class can be removed and this logic moved to the stack. 44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class BondStateMachine extends StateMachine { 47fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie private static final boolean DBG = false; 48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private static final String TAG = "BluetoothBondStateMachine"; 49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int CREATE_BOND = 1; 51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int CANCEL_BOND = 2; 52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int REMOVE_BOND = 3; 53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int BONDING_STATE_CHANGE = 4; 54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 55986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan static final int BOND_STATE_NONE = 0; 56986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan static final int BOND_STATE_BONDING = 1; 57986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan static final int BOND_STATE_BONDED = 2; 58986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan 596654f5c903de510a70f9e72cd5ad7837b615d93ffredc private AdapterService mAdapterService; 606654f5c903de510a70f9e72cd5ad7837b615d93ffredc private AdapterProperties mAdapterProperties; 616654f5c903de510a70f9e72cd5ad7837b615d93ffredc private RemoteDevices mRemoteDevices; 62179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy private BluetoothAdapter mAdapter; 63ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private PendingCommandState mPendingCommandState = new PendingCommandState(); 65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private StableState mStableState = new StableState(); 66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 676893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville private BondStateMachine(AdapterService service, 6831ba132491053bc86d419a7d51fc04af3299c076fredc AdapterProperties prop, RemoteDevices remoteDevices) { 69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh super("BondStateMachine:"); 70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mStableState); 71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mPendingCommandState); 7231ba132491053bc86d419a7d51fc04af3299c076fredc mRemoteDevices = remoteDevices; 73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh mAdapterService = service; 74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh mAdapterProperties = prop; 75179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy mAdapter = BluetoothAdapter.getDefaultAdapter(); 766654f5c903de510a70f9e72cd5ad7837b615d93ffredc setInitialState(mStableState); 776654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 786654f5c903de510a70f9e72cd5ad7837b615d93ffredc 796893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville public static BondStateMachine make(AdapterService service, 806893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville AdapterProperties prop, RemoteDevices remoteDevices) { 816893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville Log.d(TAG, "make"); 826893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville BondStateMachine bsm = new BondStateMachine(service, prop, remoteDevices); 836893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville bsm.start(); 846893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville return bsm; 856893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville } 866893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville 8715d36984a79d6e35c659edb0efdf929f0b526bd5Fred public void doQuit() { 8815d36984a79d6e35c659edb0efdf929f0b526bd5Fred quitNow(); 8915d36984a79d6e35c659edb0efdf929f0b526bd5Fred } 9015d36984a79d6e35c659edb0efdf929f0b526bd5Fred 916654f5c903de510a70f9e72cd5ad7837b615d93ffredc public void cleanup() { 9274ae04c73312403e89db0f8e9bd9601d403b4783fredc mAdapterService = null; 9374ae04c73312403e89db0f8e9bd9601d403b4783fredc mRemoteDevices = null; 9474ae04c73312403e89db0f8e9bd9601d403b4783fredc mAdapterProperties = null; 95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class StableState extends State { 98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 99ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 1007aab11364743cbca6eeefecbbde19f0434aff362fredc infoLog("StableState(): Entering Off State"); 101ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 102ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 103ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 105b5cc776c9353a203cdde97e62b25f05d9633d14cfredc 106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice dev = (BluetoothDevice)msg.obj; 1076654f5c903de510a70f9e72cd5ad7837b615d93ffredc 108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch(msg.what) { 1096654f5c903de510a70f9e72cd5ad7837b615d93ffredc 110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case CREATE_BOND: 111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh createBond(dev, true); 112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case REMOVE_BOND: 114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh removeBond(dev, true); 115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case BONDING_STATE_CHANGE: 117986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan int newState = msg.arg1; 118986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan /* if incoming pairing, transition to pending state */ 119986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan if (newState == BluetoothDevice.BOND_BONDING) 120986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan { 121ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan sendIntent(dev, newState, 0); 122986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan transitionTo(mPendingCommandState); 123986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan } 124986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan else 125986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan { 126986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan Log.e(TAG, "In stable state, received invalid newState: " + newState); 127986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan } 128986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan break; 129986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan 130986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan case CANCEL_BOND: 131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Received unhandled state: " + msg.what); 133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class PendingCommandState extends State { 141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private final ArrayList<BluetoothDevice> mDevices = 142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh new ArrayList<BluetoothDevice>(); 143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Entering PendingCommandState State"); 147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj; 148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 1527aab11364743cbca6eeefecbbde19f0434aff362fredc 153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice dev = (BluetoothDevice)msg.obj; 154aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera boolean result = false; 155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (mDevices.contains(dev) && 156ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE) { 157ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh deferMessage(msg); 158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 160ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch (msg.what) { 162ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case CREATE_BOND: 163ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = createBond(dev, false); 164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case REMOVE_BOND: 166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = removeBond(dev, false); 167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case CANCEL_BOND: 169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = cancelBond(dev); 170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case BONDING_STATE_CHANGE: 172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int newState = msg.arg1; 173ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan int reason = getUnbondReasonFromHALCode(msg.arg2); 174ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan sendIntent(dev, newState, reason); 175aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera if(newState != BluetoothDevice.BOND_BONDING ) 176986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan { 177986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan /* this is either none/bonded, remove and transition */ 178986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan result = !mDevices.remove(dev); 179986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan if (mDevices.isEmpty()) { 180c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // Whenever mDevices is empty, then we need to 181c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // set result=false. Else, we will end up adding 182c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // the device to the list again. This prevents us 183c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy // from pairing with a device that we just unpaired 184c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy result = false; 185986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan transitionTo(mStableState); 186986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan } 1874f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (newState == BluetoothDevice.BOND_NONE) 1884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta { 1894f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta // Set the profile Priorities to undefined 1904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta clearProfilePriorty(dev); 1914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta else if (newState == BluetoothDevice.BOND_BONDED) 1934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta { 1944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta // Restore the profile priorty settings 1954f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta setProfilePriorty(dev); 1964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 198aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera else if(!mDevices.contains(dev)) 199aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera result=true; 200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Received unhandled event:" + msg.what); 203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (result) mDevices.add(dev); 206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private boolean cancelBond(BluetoothDevice dev) { 212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (dev.getBondState() == BluetoothDevice.BOND_BONDING) { 213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); 214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!mAdapterService.cancelBondNative(addr)) { 215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Unexpected error while cancelling bond:"); 216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private boolean removeBond(BluetoothDevice dev, boolean transition) { 224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (dev.getBondState() == BluetoothDevice.BOND_BONDED) { 225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); 226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!mAdapterService.removeBondNative(addr)) { 227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, "Unexpected error while removing bond:"); 228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (transition) transitionTo(mPendingCommandState); 230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private boolean createBond(BluetoothDevice dev, boolean transition) { 238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (dev.getBondState() == BluetoothDevice.BOND_NONE) { 239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Bond address is:" + dev); 240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); 241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!mAdapterService.createBondNative(addr)) { 242ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan sendIntent(dev, BluetoothDevice.BOND_NONE, 243ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan BluetoothDevice.UNBOND_REASON_REMOVED); 244986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan return false; 245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else if (transition) { 246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh transitionTo(mPendingCommandState); 247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 253ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan private void sendIntent(BluetoothDevice device, int newState, int reason) { 254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device); 255179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy int oldState = BluetoothDevice.BOND_NONE; 256179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy if (devProp != null) { 257179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy oldState = devProp.getBondState(); 258179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy } 259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (oldState == newState) return; 260179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy mAdapterProperties.onBondStateChanged(device, newState); 2612f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan 262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState); 265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState); 266ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan if (newState == BluetoothDevice.BOND_NONE) 267ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan intent.putExtra(BluetoothDevice.EXTRA_REASON, reason); 268bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu mAdapterService.sendBroadcastAsUser(intent, UserHandle.ALL, 269bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu AdapterService.BLUETOOTH_PERM); 270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Bond State Change Intent:" + device + " OldState: " + oldState 271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh + " NewState: " + newState); 272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh void bondStateChangeCallback(int status, byte[] address, int newState) { 275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh BluetoothDevice device = mRemoteDevices.getDevice(address); 276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 277ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (device == null) { 278179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy infoLog("No record of the device:" + device); 279179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy // This device will be added as part of the BONDING_STATE_CHANGE intent processing 280179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy // in sendIntent above 281179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address)); 282ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 283ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device 285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh + " newState: " + newState); 286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Message msg = obtainMessage(BONDING_STATE_CHANGE); 288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh msg.obj = device; 289ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 290986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan if (newState == BOND_STATE_BONDED) 291986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan msg.arg1 = BluetoothDevice.BOND_BONDED; 292986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan else if (newState == BOND_STATE_BONDING) 293986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan msg.arg1 = BluetoothDevice.BOND_BONDING; 294986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan else 295986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan msg.arg1 = BluetoothDevice.BOND_NONE; 296ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan msg.arg2 = status; 297986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan 298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sendMessage(msg); 299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 3014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private void setProfilePriorty (BluetoothDevice device){ 3024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HidService hidService = HidService.getHidService(); 3034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta A2dpService a2dpService = A2dpService.getA2dpService(); 3044f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HeadsetService headsetService = HeadsetService.getHeadsetService(); 3054f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if ((hidService != null) && 3074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 3084f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta hidService.setPriority(device,BluetoothProfile.PRIORITY_ON); 3094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if ((a2dpService != null) && 3124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 3134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON); 3144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3154f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3164f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if ((headsetService != null) && 3174f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 3184f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON); 3194f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3204f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3214f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3224f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private void clearProfilePriorty (BluetoothDevice device){ 3234f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HidService hidService = HidService.getHidService(); 3244f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta A2dpService a2dpService = A2dpService.getA2dpService(); 3254f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta HeadsetService headsetService = HeadsetService.getHeadsetService(); 3264f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 3274f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (hidService != null) 3284f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta hidService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED); 3294f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if(a2dpService != null) 3304f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta a2dpService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED); 3314f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if(headsetService != null) 3324f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta headsetService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED); 3334f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 3344f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private void infoLog(String msg) { 336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.i(TAG, msg); 337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private void errorLog(String msg) { 340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, msg); 341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 34215d36984a79d6e35c659edb0efdf929f0b526bd5Fred 343ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan private int getUnbondReasonFromHALCode (int reason) { 344ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan if (reason == AbstractionLayer.BT_STATUS_SUCCESS) 345ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.BOND_SUCCESS; 346ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan else if (reason == AbstractionLayer.BT_STATUS_RMT_DEV_DOWN) 347ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN; 348ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan else if (reason == AbstractionLayer.BT_STATUS_AUTH_FAILURE) 349ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.UNBOND_REASON_AUTH_FAILED; 35003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta else if (reason == AbstractionLayer.BT_STATUS_AUTH_REJECTED) 35103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return BluetoothDevice.UNBOND_REASON_AUTH_REJECTED; 35203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta else if (reason == AbstractionLayer.BT_STATUS_AUTH_TIMEOUT) 35303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return BluetoothDevice.UNBOND_REASON_AUTH_TIMEOUT; 354ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan 355ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan /* default */ 356ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan return BluetoothDevice.UNBOND_REASON_REMOVED; 357ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan } 358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 359