BondStateMachine.java revision 15d36984a79d6e35c659edb0efdf929f0b526bd5
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;
8ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothDevice;
9ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context;
10ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent;
11ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message;
12ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log;
13ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
14ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.Utils;
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State;
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine;
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.ArrayList;
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/**
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State.
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States:
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link StableState} :  No device is in bonding / unbonding state.
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link PendingCommandState} : Some device is in bonding / unbonding state.
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT) This class can be removed and this logic moved to the stack.
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class BondStateMachine extends StateMachine {
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final boolean DBG = true;
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final String TAG = "BluetoothBondStateMachine";
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int CREATE_BOND = 1;
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int CANCEL_BOND = 2;
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int REMOVE_BOND = 3;
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int BONDING_STATE_CHANGE = 4;
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
38986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan    static final int BOND_STATE_NONE = 0;
39986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan    static final int BOND_STATE_BONDING = 1;
40986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan    static final int BOND_STATE_BONDED = 2;
41986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterService mAdapterService;
436654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterProperties mAdapterProperties;
446654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private RemoteDevices mRemoteDevices;
45179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy    private BluetoothAdapter mAdapter;
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private StableState mStableState = new StableState();
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
5074ae04c73312403e89db0f8e9bd9601d403b4783fredc    public BondStateMachine(AdapterService service,
5131ba132491053bc86d419a7d51fc04af3299c076fredc            AdapterProperties prop, RemoteDevices remoteDevices) {
52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BondStateMachine:");
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mStableState);
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
5531ba132491053bc86d419a7d51fc04af3299c076fredc        mRemoteDevices = remoteDevices;
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = prop;
58179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        mAdapter = BluetoothAdapter.getDefaultAdapter();
596654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mStableState);
606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
616654f5c903de510a70f9e72cd5ad7837b615d93ffredc
6215d36984a79d6e35c659edb0efdf929f0b526bd5Fred    public void doQuit() {
6315d36984a79d6e35c659edb0efdf929f0b526bd5Fred        quitNow();
6415d36984a79d6e35c659edb0efdf929f0b526bd5Fred    }
6515d36984a79d6e35c659edb0efdf929f0b526bd5Fred
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) {
80b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
826654f5c903de510a70f9e72cd5ad7837b615d93ffredc
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
846654f5c903de510a70f9e72cd5ad7837b615d93ffredc
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case CREATE_BOND:
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  createBond(dev, true);
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case REMOVE_BOND:
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  removeBond(dev, true);
90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case BONDING_STATE_CHANGE:
92986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                int newState = msg.arg1;
93986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                /* if incoming pairing, transition to pending state */
94986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                if (newState == BluetoothDevice.BOND_BONDING)
95986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
96986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    sendIntent(dev, newState);
97986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    transitionTo(mPendingCommandState);
98986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
99986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                else
100986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
101986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    Log.e(TAG, "In stable state, received invalid newState: " + newState);
102986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
103986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                break;
104986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
105986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan              case CANCEL_BOND:
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              default:
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   Log.e(TAG, "Received unhandled state: " + msg.what);
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        private final ArrayList<BluetoothDevice> mDevices =
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            new ArrayList<BluetoothDevice>();
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Entering PendingCommandState State");
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj;
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1277aab11364743cbca6eeefecbbde19f0434aff362fredc
128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
129aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera            boolean result = false;
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (mDevices.contains(dev) &&
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE) {
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                deferMessage(msg);
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CREATE_BOND:
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = createBond(dev, false);
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case REMOVE_BOND:
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = removeBond(dev, false);
142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CANCEL_BOND:
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = cancelBond(dev);
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case BONDING_STATE_CHANGE:
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    int newState = msg.arg1;
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    sendIntent(dev, newState);
149aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    if(newState != BluetoothDevice.BOND_BONDING )
150986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    {
151986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        /* this is either none/bonded, remove and transition */
152986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        result = !mDevices.remove(dev);
153986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        if (mDevices.isEmpty()) {
154c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // Whenever mDevices is empty, then we need to
155c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // set result=false. Else, we will end up adding
156c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // the device to the list again. This prevents us
157c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // from pairing with a device that we just unpaired
158c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            result = false;
159986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                            transitionTo(mStableState);
160986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        }
161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    }
162aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    else if(!mDevices.contains(dev))
163aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                        result=true;
164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    Log.e(TAG, "Received unhandled event:" + msg.what);
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (result) mDevices.add(dev);
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean cancelBond(BluetoothDevice dev) {
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDING) {
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.cancelBondNative(addr)) {
179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while cancelling bond:");
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean removeBond(BluetoothDevice dev, boolean transition) {
188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDED) {
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.removeBondNative(addr)) {
191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while removing bond:");
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                if (transition) transitionTo(mPendingCommandState);
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean createBond(BluetoothDevice dev, boolean transition) {
202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Bond address is:" + dev);
204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.createBondNative(addr)) {
206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                sendIntent(dev, BluetoothDevice.BOND_NONE);
207986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                return false;
208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else if (transition) {
209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                transitionTo(mPendingCommandState);
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void sendIntent(BluetoothDevice device, int newState) {
217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
218179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        int oldState = BluetoothDevice.BOND_NONE;
219179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        if (devProp != null) {
220179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            oldState = devProp.getBondState();
221179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        }
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (oldState == newState) return;
223179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        mAdapterProperties.onBondStateChanged(device, newState);
2242f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
22974ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("Bond State Change Intent:" + device + " OldState: " + oldState
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " NewState: " + newState);
232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void bondStateChangeCallback(int status, byte[] address, int newState) {
235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        BluetoothDevice device = mRemoteDevices.getDevice(address);
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (device == null) {
238179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            infoLog("No record of the device:" + device);
239179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            // This device will be added as part of the BONDING_STATE_CHANGE intent processing
240179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            // in sendIntent above
241179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device
245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " newState: " + newState);
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Message msg = obtainMessage(BONDING_STATE_CHANGE);
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        msg.obj = device;
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
250986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        if (newState == BOND_STATE_BONDED)
251986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDED;
252986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else if (newState == BOND_STATE_BONDING)
253986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDING;
254986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else
255986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_NONE;
256986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        sendMessage(msg);
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.i(TAG, msg);
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
26715d36984a79d6e35c659edb0efdf929f0b526bd5Fred
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
269