BondStateMachine.java revision 2f9a79b2d545e1a8b50a0018456892a9934db99a
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;
45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private StableState mStableState = new StableState();
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4974ae04c73312403e89db0f8e9bd9601d403b4783fredc    public BondStateMachine(AdapterService service,
5031ba132491053bc86d419a7d51fc04af3299c076fredc            AdapterProperties prop, RemoteDevices remoteDevices) {
51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BondStateMachine:");
52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mStableState);
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
5431ba132491053bc86d419a7d51fc04af3299c076fredc        mRemoteDevices = remoteDevices;
55ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = prop;
576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mStableState);
586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
596654f5c903de510a70f9e72cd5ad7837b615d93ffredc
606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
6174ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterService = null;
6274ae04c73312403e89db0f8e9bd9601d403b4783fredc        mRemoteDevices = null;
6374ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterProperties = null;
64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class StableState extends State {
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
697aab11364743cbca6eeefecbbde19f0434aff362fredc            infoLog("StableState(): Entering Off State");
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
746654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (msg.what == SM_QUIT_CMD) {
75b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                Log.d(TAG, "Received quit request...");
766654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return false;
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc
79b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
816654f5c903de510a70f9e72cd5ad7837b615d93ffredc
82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
836654f5c903de510a70f9e72cd5ad7837b615d93ffredc
84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case CREATE_BOND:
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  createBond(dev, true);
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case REMOVE_BOND:
88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  removeBond(dev, true);
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case BONDING_STATE_CHANGE:
91986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                int newState = msg.arg1;
92986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                /* if incoming pairing, transition to pending state */
93986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                if (newState == BluetoothDevice.BOND_BONDING)
94986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
95986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    sendIntent(dev, newState);
96986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    transitionTo(mPendingCommandState);
97986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
98986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                else
99986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
100986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    Log.e(TAG, "In stable state, received invalid newState: " + newState);
101986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
102986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                break;
103986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
104986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan              case CANCEL_BOND:
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              default:
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   Log.e(TAG, "Received unhandled state: " + msg.what);
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        private final ArrayList<BluetoothDevice> mDevices =
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            new ArrayList<BluetoothDevice>();
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Entering PendingCommandState State");
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj;
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1267aab11364743cbca6eeefecbbde19f0434aff362fredc            if (msg.what == SM_QUIT_CMD) {
1277aab11364743cbca6eeefecbbde19f0434aff362fredc                Log.d(TAG, "PendingCommandState(): Received quit request...");
1287aab11364743cbca6eeefecbbde19f0434aff362fredc                return false;
1297aab11364743cbca6eeefecbbde19f0434aff362fredc            }
1307aab11364743cbca6eeefecbbde19f0434aff362fredc
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
132aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera            boolean result = false;
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (mDevices.contains(dev) &&
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE) {
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                deferMessage(msg);
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CREATE_BOND:
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = createBond(dev, false);
142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case REMOVE_BOND:
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = removeBond(dev, false);
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CANCEL_BOND:
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = cancelBond(dev);
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case BONDING_STATE_CHANGE:
150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    int newState = msg.arg1;
151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    sendIntent(dev, newState);
152aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    if(newState != BluetoothDevice.BOND_BONDING )
153986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    {
154986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        /* this is either none/bonded, remove and transition */
155986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        result = !mDevices.remove(dev);
156986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        if (mDevices.isEmpty()) {
157c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // Whenever mDevices is empty, then we need to
158c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // set result=false. Else, we will end up adding
159c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // the device to the list again. This prevents us
160c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // from pairing with a device that we just unpaired
161c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            result = false;
162986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                            transitionTo(mStableState);
163986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        }
164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    }
165aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    else if(!mDevices.contains(dev))
166aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                        result=true;
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    Log.e(TAG, "Received unhandled event:" + msg.what);
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (result) mDevices.add(dev);
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean cancelBond(BluetoothDevice dev) {
179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDING) {
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.cancelBondNative(addr)) {
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while cancelling bond:");
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean removeBond(BluetoothDevice dev, boolean transition) {
191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDED) {
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.removeBondNative(addr)) {
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while removing bond:");
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                if (transition) transitionTo(mPendingCommandState);
197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean createBond(BluetoothDevice dev, boolean transition) {
205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Bond address is:" + dev);
207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.createBondNative(addr)) {
209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                sendIntent(dev, BluetoothDevice.BOND_NONE);
210986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                return false;
211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else if (transition) {
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                transitionTo(mPendingCommandState);
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void sendIntent(BluetoothDevice device, int newState) {
220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int oldState = devProp.getBondState();
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (oldState == newState) return;
223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        devProp.setBondState(newState);
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
2262f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan        if (newState == BluetoothDevice.BOND_NONE)
2272f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan            mAdapterProperties.removeBondedDevice(device);
2282f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan        else if (newState == BluetoothDevice.BOND_BONDED)
2292f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan            mAdapterProperties.addBondedDevice(device);
2302f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
23574ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("Bond State Change Intent:" + device + " OldState: " + oldState
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " NewState: " + newState);
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void bondStateChangeCallback(int status, byte[] address, int newState) {
241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        BluetoothDevice device = mRemoteDevices.getDevice(address);
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (device == null) {
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            errorLog("No record of the device:" + device);
245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return;
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " newState: " + newState);
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Message msg = obtainMessage(BONDING_STATE_CHANGE);
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        msg.obj = device;
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
254986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        if (newState == BOND_STATE_BONDED)
255986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDED;
256986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else if (newState == BOND_STATE_BONDING)
257986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDING;
258986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else
259986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_NONE;
260986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        sendMessage(msg);
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.i(TAG, msg);
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
272