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