BondStateMachine.java revision 4f5430babbc5a8f870e5a578a4ea3452f41dd97a
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 {
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final boolean DBG = true;
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
5474ae04c73312403e89db0f8e9bd9601d403b4783fredc    public 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
666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
6774ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterService = null;
6874ae04c73312403e89db0f8e9bd9601d403b4783fredc        mRemoteDevices = null;
6974ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterProperties = null;
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class StableState extends State {
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
757aab11364743cbca6eeefecbbde19f0434aff362fredc            infoLog("StableState(): Entering Off State");
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
804603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            // TODO(BT)
814603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            // if (msg.what == SM_QUIT_CMD) {
824603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            //     Log.d(TAG, "Received quit request...");
834603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            //     return false;
844603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            // }
856654f5c903de510a70f9e72cd5ad7837b615d93ffredc
86b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
886654f5c903de510a70f9e72cd5ad7837b615d93ffredc
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
906654f5c903de510a70f9e72cd5ad7837b615d93ffredc
91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case CREATE_BOND:
92ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  createBond(dev, true);
93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
94ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case REMOVE_BOND:
95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  removeBond(dev, true);
96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case BONDING_STATE_CHANGE:
98986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                int newState = msg.arg1;
99986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                /* if incoming pairing, transition to pending state */
100986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                if (newState == BluetoothDevice.BOND_BONDING)
101986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
102986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    sendIntent(dev, newState);
103986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    transitionTo(mPendingCommandState);
104986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
105986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                else
106986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
107986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    Log.e(TAG, "In stable state, received invalid newState: " + newState);
108986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
109986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                break;
110986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
111986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan              case CANCEL_BOND:
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              default:
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   Log.e(TAG, "Received unhandled state: " + msg.what);
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        private final ArrayList<BluetoothDevice> mDevices =
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            new ArrayList<BluetoothDevice>();
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Entering PendingCommandState State");
128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj;
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1334603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            // TODO(BT)
1344603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            // if (msg.what == SM_QUIT_CMD) {
1354603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            //     Log.d(TAG, "PendingCommandState(): Received quit request...");
1364603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            //     return false;
1374603dc081506452854023a1c6eacdfca468e0dc4Matthew Xie            // }
1387aab11364743cbca6eeefecbbde19f0434aff362fredc
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
140aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera            boolean result = false;
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (mDevices.contains(dev) &&
142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE) {
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                deferMessage(msg);
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CREATE_BOND:
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = createBond(dev, false);
150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case REMOVE_BOND:
152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = removeBond(dev, false);
153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
154ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CANCEL_BOND:
155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = cancelBond(dev);
156ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
157ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case BONDING_STATE_CHANGE:
158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    int newState = msg.arg1;
159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    sendIntent(dev, newState);
160aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    if(newState != BluetoothDevice.BOND_BONDING )
161986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    {
162986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        /* this is either none/bonded, remove and transition */
163986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        result = !mDevices.remove(dev);
164986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        if (mDevices.isEmpty()) {
165c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // Whenever mDevices is empty, then we need to
166c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // set result=false. Else, we will end up adding
167c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // the device to the list again. This prevents us
168c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // from pairing with a device that we just unpaired
169c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            result = false;
170986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                            transitionTo(mStableState);
171986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        }
1724f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        if (newState == BluetoothDevice.BOND_NONE)
1734f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        {
1744f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                            // Set the profile Priorities to undefined
1754f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                            clearProfilePriorty(dev);
1764f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        }
1774f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        else if (newState == BluetoothDevice.BOND_BONDED)
1784f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        {
1794f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                           // Restore the profile priorty settings
1804f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                           setProfilePriorty(dev);
1814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        }
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    }
183aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    else if(!mDevices.contains(dev))
184aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                        result=true;
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    Log.e(TAG, "Received unhandled event:" + msg.what);
188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (result) mDevices.add(dev);
191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean cancelBond(BluetoothDevice dev) {
197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDING) {
198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.cancelBondNative(addr)) {
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while cancelling bond:");
201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean removeBond(BluetoothDevice dev, boolean transition) {
209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDED) {
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.removeBondNative(addr)) {
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while removing bond:");
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                if (transition) transitionTo(mPendingCommandState);
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean createBond(BluetoothDevice dev, boolean transition) {
223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Bond address is:" + dev);
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.createBondNative(addr)) {
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                sendIntent(dev, BluetoothDevice.BOND_NONE);
228986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                return false;
229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else if (transition) {
230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                transitionTo(mPendingCommandState);
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void sendIntent(BluetoothDevice device, int newState) {
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
239179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        int oldState = BluetoothDevice.BOND_NONE;
240179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        if (devProp != null) {
241179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            oldState = devProp.getBondState();
242179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        }
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (oldState == newState) return;
244179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        mAdapterProperties.onBondStateChanged(device, newState);
2452f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
25074ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("Bond State Change Intent:" + device + " OldState: " + oldState
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " NewState: " + newState);
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void bondStateChangeCallback(int status, byte[] address, int newState) {
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        BluetoothDevice device = mRemoteDevices.getDevice(address);
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (device == null) {
259179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            infoLog("No record of the device:" + device);
260179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            // This device will be added as part of the BONDING_STATE_CHANGE intent processing
261179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            // in sendIntent above
262179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " newState: " + newState);
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Message msg = obtainMessage(BONDING_STATE_CHANGE);
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        msg.obj = device;
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
271986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        if (newState == BOND_STATE_BONDED)
272986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDED;
273986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else if (newState == BOND_STATE_BONDING)
274986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDING;
275986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else
276986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_NONE;
277986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        sendMessage(msg);
279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
2814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private void setProfilePriorty (BluetoothDevice device){
2824f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HidService hidService = HidService.getHidService();
2834f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        A2dpService a2dpService = A2dpService.getA2dpService();
2844f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HeadsetService headsetService = HeadsetService.getHeadsetService();
2854f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
2864f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((hidService != null) &&
2874f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){
2884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            hidService.setPriority(device,BluetoothProfile.PRIORITY_ON);
2894f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
2904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
2914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((a2dpService != null) &&
2924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){
2934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON);
2944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
2954f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
2964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((headsetService != null) &&
2974f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){
2984f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON);
2994f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
3004f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
3014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
3024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private void clearProfilePriorty (BluetoothDevice device){
3034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HidService hidService = HidService.getHidService();
3044f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        A2dpService a2dpService = A2dpService.getA2dpService();
3054f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HeadsetService headsetService = HeadsetService.getHeadsetService();
3064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
3074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (hidService != null)
3084f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            hidService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED);
3094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if(a2dpService != null)
3104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            a2dpService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED);
3114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if(headsetService != null)
3124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            headsetService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED);
3134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
3144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.i(TAG, msg);
317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
319ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
320ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
323