BondStateMachine.java revision 7aab11364743cbca6eeefecbbde19f0434aff362
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 Context mContext;
446654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterProperties mAdapterProperties;
456654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private RemoteDevices mRemoteDevices;
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private StableState mStableState = new StableState();
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    public BondStateMachine(AdapterService service, Context context,
51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            AdapterProperties prop) {
52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BondStateMachine:");
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mStableState);
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
556654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mRemoteDevices = RemoteDevices.getInstance(service, context);
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = prop;
58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mContext = context;
596654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mStableState);
606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
616654f5c903de510a70f9e72cd5ad7837b615d93ffredc
626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
63ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class StableState extends State {
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
687aab11364743cbca6eeefecbbde19f0434aff362fredc            infoLog("StableState(): Entering Off State");
69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
736654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (msg.what == SM_QUIT_CMD) {
74b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                Log.d(TAG, "Received quit request...");
756654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return false;
766654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc
78b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
826654f5c903de510a70f9e72cd5ad7837b615d93ffredc
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case CREATE_BOND:
84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  createBond(dev, true);
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case REMOVE_BOND:
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  removeBond(dev, true);
88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case BONDING_STATE_CHANGE:
90986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                int newState = msg.arg1;
91986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                /* if incoming pairing, transition to pending state */
92986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                if (newState == BluetoothDevice.BOND_BONDING)
93986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
94986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    sendIntent(dev, newState);
95986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    transitionTo(mPendingCommandState);
96986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
97986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                else
98986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
99986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    Log.e(TAG, "In stable state, received invalid newState: " + newState);
100986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
101986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                break;
102986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
103986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan              case CANCEL_BOND:
104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              default:
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   Log.e(TAG, "Received unhandled state: " + msg.what);
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        private final ArrayList<BluetoothDevice> mDevices =
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            new ArrayList<BluetoothDevice>();
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Entering PendingCommandState State");
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj;
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1257aab11364743cbca6eeefecbbde19f0434aff362fredc            if (msg.what == SM_QUIT_CMD) {
1267aab11364743cbca6eeefecbbde19f0434aff362fredc                Log.d(TAG, "PendingCommandState(): Received quit request...");
1277aab11364743cbca6eeefecbbde19f0434aff362fredc                return false;
1287aab11364743cbca6eeefecbbde19f0434aff362fredc            }
1297aab11364743cbca6eeefecbbde19f0434aff362fredc
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
131aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera            boolean result = false;
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (mDevices.contains(dev) &&
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE) {
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                deferMessage(msg);
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CREATE_BOND:
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = createBond(dev, false);
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case REMOVE_BOND:
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = removeBond(dev, false);
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CANCEL_BOND:
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = cancelBond(dev);
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case BONDING_STATE_CHANGE:
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    int newState = msg.arg1;
150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    sendIntent(dev, newState);
151aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    if(newState != BluetoothDevice.BOND_BONDING )
152986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    {
153986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        /* this is either none/bonded, remove and transition */
154986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        result = !mDevices.remove(dev);
155986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        if (mDevices.isEmpty()) {
156986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                            transitionTo(mStableState);
157986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        }
158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    }
159aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    else if(!mDevices.contains(dev))
160aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                        result=true;
161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
162ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
163ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    Log.e(TAG, "Received unhandled event:" + msg.what);
164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (result) mDevices.add(dev);
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean cancelBond(BluetoothDevice dev) {
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDING) {
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.cancelBondNative(addr)) {
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while cancelling bond:");
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean removeBond(BluetoothDevice dev, boolean transition) {
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDED) {
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.removeBondNative(addr)) {
188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while removing bond:");
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                if (transition) transitionTo(mPendingCommandState);
191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean createBond(BluetoothDevice dev, boolean transition) {
199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Bond address is:" + dev);
201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.createBondNative(addr)) {
203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                sendIntent(dev, BluetoothDevice.BOND_NONE);
204986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                return false;
205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else if (transition) {
206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                transitionTo(mPendingCommandState);
207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void sendIntent(BluetoothDevice device, int newState) {
214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int oldState = devProp.getBondState();
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (oldState == newState) return;
217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        devProp.setBondState(newState);
219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mContext.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("Bond State Change Intent:" + device + " OldState: " + oldState
226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " NewState: " + newState);
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void bondStateChangeCallback(int status, byte[] address, int newState) {
230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        BluetoothDevice device = mRemoteDevices.getDevice(address);
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (device == null) {
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            errorLog("No record of the device:" + device);
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return;
235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " newState: " + newState);
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Message msg = obtainMessage(BONDING_STATE_CHANGE);
241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        msg.obj = device;
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
243986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        if (newState == BOND_STATE_BONDED)
244986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDED;
245986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else if (newState == BOND_STATE_BONDING)
246986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDING;
247986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else
248986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_NONE;
249986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        sendMessage(msg);
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.i(TAG, msg);
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
261