1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth.btservice;
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
2011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananthimport android.bluetooth.BluetoothClass;
214f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport android.bluetooth.BluetoothProfile;
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothDevice;
234f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.a2dp.A2dpService;
244f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.hid.HidService;
254f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport com.android.bluetooth.hfp.HeadsetService;
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context;
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent;
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message;
29bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xuimport android.os.UserHandle;
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log;
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.Utils;
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State;
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine;
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.ArrayList;
38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/**
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State.
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States:
42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link StableState} :  No device is in bonding / unbonding state.
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link PendingCommandState} : Some device is in bonding / unbonding state.
44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT) This class can be removed and this logic moved to the stack.
45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class BondStateMachine extends StateMachine {
48fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie    private static final boolean DBG = false;
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final String TAG = "BluetoothBondStateMachine";
50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int CREATE_BOND = 1;
52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int CANCEL_BOND = 2;
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int REMOVE_BOND = 3;
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int BONDING_STATE_CHANGE = 4;
5511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    static final int SSP_REQUEST = 5;
5611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    static final int PIN_REQUEST = 6;
57986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan    static final int BOND_STATE_NONE = 0;
58986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan    static final int BOND_STATE_BONDING = 1;
59986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan    static final int BOND_STATE_BONDED = 2;
60986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
616654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterService mAdapterService;
626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterProperties mAdapterProperties;
636654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private RemoteDevices mRemoteDevices;
64179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy    private BluetoothAdapter mAdapter;
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private StableState mStableState = new StableState();
68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
696893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    private BondStateMachine(AdapterService service,
7031ba132491053bc86d419a7d51fc04af3299c076fredc            AdapterProperties prop, RemoteDevices remoteDevices) {
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BondStateMachine:");
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mStableState);
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
7431ba132491053bc86d419a7d51fc04af3299c076fredc        mRemoteDevices = remoteDevices;
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = prop;
77179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        mAdapter = BluetoothAdapter.getDefaultAdapter();
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mStableState);
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc
816893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    public static BondStateMachine make(AdapterService service,
826893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville            AdapterProperties prop, RemoteDevices remoteDevices) {
836893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        Log.d(TAG, "make");
846893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        BondStateMachine bsm = new BondStateMachine(service, prop, remoteDevices);
856893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        bsm.start();
866893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        return bsm;
876893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    }
886893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville
8915d36984a79d6e35c659edb0efdf929f0b526bd5Fred    public void doQuit() {
9015d36984a79d6e35c659edb0efdf929f0b526bd5Fred        quitNow();
9115d36984a79d6e35c659edb0efdf929f0b526bd5Fred    }
9215d36984a79d6e35c659edb0efdf929f0b526bd5Fred
936654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
9474ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterService = null;
9574ae04c73312403e89db0f8e9bd9601d403b4783fredc        mRemoteDevices = null;
9674ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterProperties = null;
97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
99ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class StableState extends State {
100ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
101ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
1027aab11364743cbca6eeefecbbde19f0434aff362fredc            infoLog("StableState(): Entering Off State");
103ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
107b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
1096654f5c903de510a70f9e72cd5ad7837b615d93ffredc
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
1116654f5c903de510a70f9e72cd5ad7837b615d93ffredc
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case CREATE_BOND:
113db681f3973bd8a088a878fd6f41d4330cdbc5522Andre Eisenbach                  createBond(dev, msg.arg1, true);
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case REMOVE_BOND:
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  removeBond(dev, true);
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                  break;
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              case BONDING_STATE_CHANGE:
119986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                int newState = msg.arg1;
120986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                /* if incoming pairing, transition to pending state */
121986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                if (newState == BluetoothDevice.BOND_BONDING)
122986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
123ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan                    sendIntent(dev, newState, 0);
124986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    transitionTo(mPendingCommandState);
125986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
126986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                else
127986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                {
128986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    Log.e(TAG, "In stable state, received invalid newState: " + newState);
129986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                }
130986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                break;
131986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
132986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan              case CANCEL_BOND:
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh              default:
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   Log.e(TAG, "Received unhandled state: " + msg.what);
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        private final ArrayList<BluetoothDevice> mDevices =
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            new ArrayList<BluetoothDevice>();
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Entering PendingCommandState State");
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)getCurrentMessage().obj;
150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1547aab11364743cbca6eeefecbbde19f0434aff362fredc
155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            BluetoothDevice dev = (BluetoothDevice)msg.obj;
15611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            DeviceProperties devProp = mRemoteDevices.getDeviceProperties(dev);
157aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera            boolean result = false;
15811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth             if (mDevices.contains(dev) && msg.what != CANCEL_BOND &&
15911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                   msg.what != BONDING_STATE_CHANGE && msg.what != SSP_REQUEST &&
16011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                   msg.what != PIN_REQUEST) {
16111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                 deferMessage(msg);
16211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                 return true;
16311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth             }
16411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
16511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CREATE_BOND:
169db681f3973bd8a088a878fd6f41d4330cdbc5522Andre Eisenbach                    result = createBond(dev, msg.arg1, false);
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case REMOVE_BOND:
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = removeBond(dev, false);
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case CANCEL_BOND:
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    result = cancelBond(dev);
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case BONDING_STATE_CHANGE:
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    int newState = msg.arg1;
179ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan                    int reason = getUnbondReasonFromHALCode(msg.arg2);
180ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan                    sendIntent(dev, newState, reason);
181aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    if(newState != BluetoothDevice.BOND_BONDING )
182986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                    {
183986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        /* this is either none/bonded, remove and transition */
184986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        result = !mDevices.remove(dev);
185986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        if (mDevices.isEmpty()) {
186c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // Whenever mDevices is empty, then we need to
187c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // set result=false. Else, we will end up adding
188c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // the device to the list again. This prevents us
189c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            // from pairing with a device that we just unpaired
190c181b8b49f5ad5b49b33334a9ba8f342ddb3545cKausik Sinnaswamy                            result = false;
191986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                            transitionTo(mStableState);
192986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                        }
1934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        if (newState == BluetoothDevice.BOND_NONE)
1944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        {
195fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee                            mAdapterService.setPhonebookAccessPermission(dev,
196fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee                                    BluetoothDevice.ACCESS_UNKNOWN);
197fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee                            mAdapterService.setMessageAccessPermission(dev,
198fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee                                    BluetoothDevice.ACCESS_UNKNOWN);
1994f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                            // Set the profile Priorities to undefined
2004f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                            clearProfilePriorty(dev);
2014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        }
2024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        else if (newState == BluetoothDevice.BOND_BONDED)
2034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        {
20434409f35db6e9ca74f727e3fe92141388ae5b069Ganesh Ganapathi Batta                           // Do not set profile priority
20534409f35db6e9ca74f727e3fe92141388ae5b069Ganesh Ganapathi Batta                           // Profile priority should be set after SDP completion
20634409f35db6e9ca74f727e3fe92141388ae5b069Ganesh Ganapathi Batta
2074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                           // Restore the profile priorty settings
20834409f35db6e9ca74f727e3fe92141388ae5b069Ganesh Ganapathi Batta                           //setProfilePriorty(dev);
2094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                        }
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    }
211aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                    else if(!mDevices.contains(dev))
212aa90f0cbb860434c5310ae6bfa16987834f582f0Priti Aghera                        result=true;
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
21411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                case SSP_REQUEST:
21511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    int passkey = msg.arg1;
21611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    int variant = msg.arg2;
21711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    sendDisplayPinIntent(devProp.getAddress(), passkey, variant);
21811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    break;
21911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                case PIN_REQUEST:
22011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    BluetoothClass btClass = dev.getBluetoothClass();
22111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    int btDeviceClass = btClass.getDeviceClass();
22211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    if (btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD ||
22311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                         btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING) {
22411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        // Its a keyboard. Follow the HID spec recommendation of creating the
22511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        // passkey and displaying it to the user. If the keyboard doesn't follow
22611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        // the spec recommendation, check if the keyboard has a fixed PIN zero
22711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        // and pair.
22811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        //TODO: Maintain list of devices that have fixed pin
22911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        // Generate a variable 6-digit PIN in range of 100000-999999
23011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        // This is not truly random but good enough.
23111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        int pin = 100000 + (int)Math.floor((Math.random() * (999999 - 100000)));
23211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        sendDisplayPinIntent(devProp.getAddress(), pin,
23311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                                 BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN);
23411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                        break;
23511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    }
23611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    //In PIN_REQUEST, there is no passkey to display.So do not send the
23711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    //EXTRA_PAIRING_KEY type in the intent( 0 in SendDisplayPinIntent() )
23811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    sendDisplayPinIntent(devProp.getAddress(), 0,
23911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                                          BluetoothDevice.PAIRING_VARIANT_PIN);
24011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
24111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                    break;
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    Log.e(TAG, "Received unhandled event:" + msg.what);
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (result) mDevices.add(dev);
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean cancelBond(BluetoothDevice dev) {
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDING) {
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.cancelBondNative(addr)) {
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while cancelling bond:");
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private boolean removeBond(BluetoothDevice dev, boolean transition) {
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_BONDED) {
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (!mAdapterService.removeBondNative(addr)) {
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               Log.e(TAG, "Unexpected error while removing bond:");
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                if (transition) transitionTo(mPendingCommandState);
271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return true;
272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
277ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
278db681f3973bd8a088a878fd6f41d4330cdbc5522Andre Eisenbach    private boolean createBond(BluetoothDevice dev, int transport, boolean transition) {
279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Bond address is:" + dev);
281ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
282db681f3973bd8a088a878fd6f41d4330cdbc5522Andre Eisenbach            if (!mAdapterService.createBondNative(addr, transport)) {
283ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan                sendIntent(dev, BluetoothDevice.BOND_NONE,
284ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan                           BluetoothDevice.UNBOND_REASON_REMOVED);
285986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan                return false;
286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else if (transition) {
287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                transitionTo(mPendingCommandState);
288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
289ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
291ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return false;
292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
293ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
29411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    private void sendDisplayPinIntent(byte[] address, int pin, int variant) {
29511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
29611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevices.getDevice(address));
29711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        if (pin != 0) {
29811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pin);
29911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        }
30011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, variant);
301a51c13ae7e6ce56922316a979aef570abafc9f3fAriel Gertzenstein        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
30211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
30311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    }
30411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
305ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan    private void sendIntent(BluetoothDevice device, int newState, int reason) {
306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
307179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        int oldState = BluetoothDevice.BOND_NONE;
308179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        if (devProp != null) {
309179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            oldState = devProp.getBondState();
310179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        }
311ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (oldState == newState) return;
312179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy        mAdapterProperties.onBondStateChanged(device, newState);
3132f9a79b2d545e1a8b50a0018456892a9934db99aRavi Nagarajan
314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
318ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        if (newState == BluetoothDevice.BOND_NONE)
319ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan            intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
320bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu        mAdapterService.sendBroadcastAsUser(intent, UserHandle.ALL,
321bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu                AdapterService.BLUETOOTH_PERM);
322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("Bond State Change Intent:" + device + " OldState: " + oldState
323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " NewState: " + newState);
324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void bondStateChangeCallback(int status, byte[] address, int newState) {
327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        BluetoothDevice device = mRemoteDevices.getDevice(address);
328ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (device == null) {
330179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            infoLog("No record of the device:" + device);
331179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            // This device will be added as part of the BONDING_STATE_CHANGE intent processing
332179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            // in sendIntent above
333179fd2512d1a93bbd2a1a3803f5764cb417fe4c9Kausik Sinnaswamy            device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device
337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                + " newState: " + newState);
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Message msg = obtainMessage(BONDING_STATE_CHANGE);
340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        msg.obj = device;
341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
342986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        if (newState == BOND_STATE_BONDED)
343986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDED;
344986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else if (newState == BOND_STATE_BONDING)
345986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_BONDING;
346986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan        else
347986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan            msg.arg1 = BluetoothDevice.BOND_NONE;
348ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        msg.arg2 = status;
349986b5b03a378385bfea6c5cc6b6c1d7f0424e0a5Ravi Nagarajan
350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        sendMessage(msg);
351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
35311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    void sspRequestCallback(byte[] address, byte[] name, int cod, int pairingVariant,
35411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            int passkey) {
35511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        //TODO(BT): Get wakelock and update name and cod
35611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        BluetoothDevice bdDevice = mRemoteDevices.getDevice(address);
35711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        if (bdDevice == null) {
35811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            mRemoteDevices.addDeviceProperties(address);
35911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        }
36011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        infoLog("sspRequestCallback: " + address + " name: " + name + " cod: " +
36111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                cod + " pairingVariant " + pairingVariant + " passkey: " + passkey);
36211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        int variant;
36311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        boolean displayPasskey = false;
36411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        switch(pairingVariant) {
36511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
36611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            case AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION :
36711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                variant = BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION;
36811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                displayPasskey = true;
36911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            break;
37011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
37111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            case AbstractionLayer.BT_SSP_VARIANT_CONSENT :
37211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                variant = BluetoothDevice.PAIRING_VARIANT_CONSENT;
37311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            break;
37411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
37511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            case AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY :
37611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                variant = BluetoothDevice.PAIRING_VARIANT_PASSKEY;
37711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            break;
37811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
37911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            case AbstractionLayer.BT_SSP_VARIANT_PASSKEY_NOTIFICATION :
38011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                variant = BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY;
38111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                displayPasskey = true;
38211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            break;
38311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
38411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            default:
38511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                errorLog("SSP Pairing variant not present");
38611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                return;
38711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        }
38811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        BluetoothDevice device = mRemoteDevices.getDevice(address);
38911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        if (device == null) {
39011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth           warnLog("Device is not known for:" + Utils.getAddressStringFromByte(address));
39111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth           mRemoteDevices.addDeviceProperties(address);
39211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth           device = mRemoteDevices.getDevice(address);
39311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        }
39411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
39511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        Message msg = obtainMessage(SSP_REQUEST);
39611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        msg.obj = device;
39711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        if(displayPasskey)
39811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            msg.arg1 = passkey;
39911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        msg.arg2 = variant;
40011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        sendMessage(msg);
40111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    }
40211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
40311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    void pinRequestCallback(byte[] address, byte[] name, int cod) {
40411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        //TODO(BT): Get wakelock and update name and cod
40511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        BluetoothDevice bdDevice = mRemoteDevices.getDevice(address);
40611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        if (bdDevice == null) {
40711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth            mRemoteDevices.addDeviceProperties(address);
40811b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        }
40911b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        infoLog("pinRequestCallback: " + address + " name:" + name + " cod:" +
41011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth                cod);
41111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
41211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        Message msg = obtainMessage(PIN_REQUEST);
41311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        msg.obj = bdDevice;
41411b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
41511b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        sendMessage(msg);
41611b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    }
41711b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
4184f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private void setProfilePriorty (BluetoothDevice device){
4194f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HidService hidService = HidService.getHidService();
4204f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        A2dpService a2dpService = A2dpService.getA2dpService();
4214f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HeadsetService headsetService = HeadsetService.getHeadsetService();
4224f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
4234f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((hidService != null) &&
4244f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){
4254f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            hidService.setPriority(device,BluetoothProfile.PRIORITY_ON);
4264f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
4274f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
4284f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((a2dpService != null) &&
4294f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){
4304f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON);
4314f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
4324f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
4334f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((headsetService != null) &&
4344f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){
4354f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON);
4364f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
4374f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
4384f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
4394f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private void clearProfilePriorty (BluetoothDevice device){
4404f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HidService hidService = HidService.getHidService();
4414f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        A2dpService a2dpService = A2dpService.getA2dpService();
4424f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HeadsetService headsetService = HeadsetService.getHeadsetService();
4434f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
4444f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (hidService != null)
4454f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            hidService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED);
4464f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if(a2dpService != null)
4474f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            a2dpService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED);
4484f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if(headsetService != null)
4494f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            headsetService.setPriority(device,BluetoothProfile.PRIORITY_UNDEFINED);
4504f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
4514f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
452ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
453ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.i(TAG, msg);
454ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
455ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
456ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
457ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
458ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
45915d36984a79d6e35c659edb0efdf929f0b526bd5Fred
46011b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    private void warnLog(String msg) {
46111b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth        Log.w(TAG, msg);
46211b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth    }
46311b41d8123241ba8e693e21c4db308bacff23f57Mudumba Ananth
464ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan    private int getUnbondReasonFromHALCode (int reason) {
465ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        if (reason == AbstractionLayer.BT_STATUS_SUCCESS)
466ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan            return BluetoothDevice.BOND_SUCCESS;
467ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        else if (reason == AbstractionLayer.BT_STATUS_RMT_DEV_DOWN)
468ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan            return BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN;
469ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        else if (reason == AbstractionLayer.BT_STATUS_AUTH_FAILURE)
470ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan            return BluetoothDevice.UNBOND_REASON_AUTH_FAILED;
47103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        else if (reason == AbstractionLayer.BT_STATUS_AUTH_REJECTED)
47203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            return BluetoothDevice.UNBOND_REASON_AUTH_REJECTED;
47303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        else if (reason == AbstractionLayer.BT_STATUS_AUTH_TIMEOUT)
47403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            return BluetoothDevice.UNBOND_REASON_AUTH_TIMEOUT;
475ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan
476ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        /* default */
477ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan        return BluetoothDevice.UNBOND_REASON_REMOVED;
478ef39cada04683dd7ef7b68c89a8722f2ce635c28Ravi Nagarajan    }
479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
480