19a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby/*
29a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * Copyright (C) 2010 The Android Open Source Project
39a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby *
49a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * Licensed under the Apache License, Version 2.0 (the "License");
59a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * you may not use this file except in compliance with the License.
69a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * You may obtain a copy of the License at
79a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby *
89a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby *      http://www.apache.org/licenses/LICENSE-2.0
99a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby *
109a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * Unless required by applicable law or agreed to in writing, software
119a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * distributed under the License is distributed on an "AS IS" BASIS,
129a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * See the License for the specific language governing permissions and
149a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * limitations under the License.
159a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby */
169a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
179a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambypackage android.server;
189a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
199a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport android.bluetooth.BluetoothAdapter;
209a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport android.bluetooth.BluetoothDevice;
21abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xieimport android.bluetooth.BluetoothProfile;
22abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xieimport android.bluetooth.BluetoothA2dp;
23abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xieimport android.bluetooth.BluetoothHeadset;
24d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganeshimport android.content.BroadcastReceiver;
25d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganeshimport android.content.ContentResolver;
269a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport android.content.Context;
279a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport android.content.Intent;
28d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganeshimport android.content.IntentFilter;
29d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganeshimport android.content.SharedPreferences;
30d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganeshimport android.provider.Settings;
319a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport android.util.Log;
329a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
339a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.BufferedReader;
349a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.BufferedWriter;
359a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.DataInputStream;
369a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.File;
379a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.FileInputStream;
389a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.FileNotFoundException;
399a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.FileOutputStream;
409a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.FileWriter;
419a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.IOException;
429a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.io.InputStreamReader;
439a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.util.ArrayList;
449a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.util.Arrays;
459a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.util.HashMap;
469a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyimport java.util.Map;
479a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
489a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby/**
499a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * Local cache of bonding state.
509a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * We keep our own state to track the intermediate state BONDING, which
519a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * bluez does not track.
529a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby * All addresses must be passed in upper case.
539a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby */
549a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hambyclass BluetoothBondState {
559a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private static final String TAG = "BluetoothBondState";
569a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private static final boolean DBG =  true;
579a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
589a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
599a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
609a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
619a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private static final String AUTO_PAIRING_BLACKLIST =
629a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        "/etc/bluetooth/auto_pairing.conf";
639a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private static final String DYNAMIC_AUTO_PAIRING_BLACKLIST =
649a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        "/data/misc/bluetooth/dynamic_auto_pairing.conf";
659a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private ArrayList<String> mAutoPairingAddressBlacklist;
669a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private ArrayList<String> mAutoPairingExactNameBlacklist;
679a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private ArrayList<String> mAutoPairingPartialNameBlacklist;
689a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private ArrayList<String> mAutoPairingFixedPinZerosKeyboardList;
699a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    // Addresses added to blacklist dynamically based on usage.
709a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
719a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
729a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    // If this is an outgoing connection, store the address.
739a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    // There can be only 1 pending outgoing connection at a time,
749a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private String mPendingOutgoingBonding;
759a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
769a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private final Context mContext;
779a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private final BluetoothService mService;
789a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private final BluetoothInputProfileHandler mBluetoothInputProfileHandler;
79abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    private BluetoothA2dp mA2dpProxy;
80abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    private BluetoothHeadset mHeadsetProxy;
819a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
82d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh    private ArrayList<String> mPairingRequestRcvd = new ArrayList<String>();
83d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh
849a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    BluetoothBondState(Context context, BluetoothService service) {
859a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mContext = context;
869a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mService = service;
879a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mBluetoothInputProfileHandler =
889a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            BluetoothInputProfileHandler.getInstance(mContext, mService);
89d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh
90d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        IntentFilter filter = new IntentFilter();
91d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
92d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        mContext.registerReceiver(mReceiver, filter);
938594394aadeaaa3f834d33d7b198fb071e0f31feMatthew Xie        readAutoPairingData();
949a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
959a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
969a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    synchronized void setPendingOutgoingBonding(String address) {
979a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mPendingOutgoingBonding = address;
989a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
999a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1009a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized String getPendingOutgoingBonding() {
1019a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return mPendingOutgoingBonding;
1029a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
1039a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
104c73dd732c962238330cc2e5538a88bffbbb40fe8Jaikumar Ganesh    public synchronized void initBondState() {
105c73dd732c962238330cc2e5538a88bffbbb40fe8Jaikumar Ganesh        getProfileProxy();
106c73dd732c962238330cc2e5538a88bffbbb40fe8Jaikumar Ganesh        loadBondState();
107c73dd732c962238330cc2e5538a88bffbbb40fe8Jaikumar Ganesh    }
108c73dd732c962238330cc2e5538a88bffbbb40fe8Jaikumar Ganesh
109c73dd732c962238330cc2e5538a88bffbbb40fe8Jaikumar Ganesh    private void loadBondState() {
1109a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mService.getBluetoothStateInternal() !=
1119a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                BluetoothAdapter.STATE_TURNING_ON) {
1129a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            return;
1139a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1149a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        String val = mService.getAdapterProperties().getProperty("Devices");
1159a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (val == null) {
1169a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            return;
1179a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1189a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        String[] bonds = val.split(",");
1199a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (bonds == null) {
1209a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            return;
1219a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1229a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mState.clear();
1239a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (DBG) Log.d(TAG, "found " + bonds.length + " bonded devices");
1249a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        for (String device : bonds) {
1259a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            mState.put(mService.getAddressFromObjectPath(device).toUpperCase(),
1269a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    BluetoothDevice.BOND_BONDED);
1279a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1289a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
1299a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1309a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized void setBondState(String address, int state) {
1319a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        setBondState(address, state, 0);
1329a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
1339a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1349a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    /** reason is ignored unless state == BOND_NOT_BONDED */
1359a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized void setBondState(String address, int state, int reason) {
136a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        if (DBG) Log.d(TAG, "setBondState " + "address" + " " + state + "reason: " + reason);
137a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie
1389a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        int oldState = getBondState(address);
1399a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (oldState == state) {
1409a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            return;
1419a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1429a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1439a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        // Check if this was an pending outgoing bonding.
1449a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        // If yes, reset the state.
1459a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (oldState == BluetoothDevice.BOND_BONDING) {
1469a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (address.equals(mPendingOutgoingBonding)) {
1479a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                mPendingOutgoingBonding = null;
1489a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
1499a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1509a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1519a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (state == BluetoothDevice.BOND_BONDED) {
152d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            boolean setTrust = false;
153d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            if (mPairingRequestRcvd.contains(address)) setTrust = true;
154d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh
155d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            mService.addProfileState(address, setTrust);
156d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            mPairingRequestRcvd.remove(address);
157d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh
158a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        } else if (state == BluetoothDevice.BOND_BONDING) {
159a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            if (mA2dpProxy == null || mHeadsetProxy == null) {
160a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                getProfileProxy();
161a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            }
162d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        } else if (state == BluetoothDevice.BOND_NONE) {
163d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            mPairingRequestRcvd.remove(address);
1649a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1659a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
166abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        setProfilePriorities(address, state);
1679a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1689a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (DBG) {
1699a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.d(TAG, address + " bond state " + oldState + " -> " + state
1709a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                + " (" + reason + ")");
1719a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1729a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
1739a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mService.getRemoteDevice(address));
1749a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, state);
1759a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
1769a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (state == BluetoothDevice.BOND_NONE) {
1779a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (reason <= 0) {
1789a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                Log.w(TAG, "setBondState() called to unbond device, but reason code is " +
1799a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                      "invalid. Overriding reason code with BOND_RESULT_REMOVED");
1809a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                reason = BluetoothDevice.UNBOND_REASON_REMOVED;
1819a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
1829a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
1839a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            mState.remove(address);
1849a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } else {
1859a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            mState.put(address, state);
1869a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1879a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1889a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
1899a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
1909a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1919a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public boolean isAutoPairingBlacklisted(String address) {
1929a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mAutoPairingAddressBlacklist != null) {
1939a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            for (String blacklistAddress : mAutoPairingAddressBlacklist) {
1949a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                if (address.startsWith(blacklistAddress)) return true;
1959a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
1969a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
1979a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
1989a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mAutoPairingDynamicAddressBlacklist != null) {
1999a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            for (String blacklistAddress: mAutoPairingDynamicAddressBlacklist) {
2009a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                if (address.equals(blacklistAddress)) return true;
2019a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
2029a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2039a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2049a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        String name = mService.getRemoteName(address);
2059a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (name != null) {
2069a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (mAutoPairingExactNameBlacklist != null) {
2079a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                for (String blacklistName : mAutoPairingExactNameBlacklist) {
2089a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    if (name.equals(blacklistName)) return true;
2099a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                }
2109a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
2119a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2129a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (mAutoPairingPartialNameBlacklist != null) {
2139a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                for (String blacklistName : mAutoPairingPartialNameBlacklist) {
2149a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    if (name.startsWith(blacklistName)) return true;
2159a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                }
2169a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
2179a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2189a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return false;
2199a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2209a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2219a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public boolean isFixedPinZerosAutoPairKeyboard(String address) {
2229a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        // Note: the meaning of blacklist is reversed in this case.
2239a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        // If its in the list, we can go ahead and auto pair since
2249a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        // by default keyboard should have a variable PIN that we don't
2259a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        // auto pair using 0000.
2269a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mAutoPairingFixedPinZerosKeyboardList != null) {
2279a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            for (String blacklistAddress : mAutoPairingFixedPinZerosKeyboardList) {
2289a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                if (address.startsWith(blacklistAddress)) return true;
2299a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
2309a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2319a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return false;
2329a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2339a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2349a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized int getBondState(String address) {
2359a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        Integer state = mState.get(address);
2369a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (state == null) {
2379a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            return BluetoothDevice.BOND_NONE;
2389a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2399a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return state.intValue();
2409a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2419a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2429a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    /*package*/ synchronized String[] listInState(int state) {
2439a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        ArrayList<String> result = new ArrayList<String>(mState.size());
2449a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        for (Map.Entry<String, Integer> e : mState.entrySet()) {
2459a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (e.getValue().intValue() == state) {
2469a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                result.add(e.getKey());
2479a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
2489a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2499a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return result.toArray(new String[result.size()]);
2509a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2519a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2529a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized void addAutoPairingFailure(String address) {
2539a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mAutoPairingDynamicAddressBlacklist == null) {
2549a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            mAutoPairingDynamicAddressBlacklist = new ArrayList<String>();
2559a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2569a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2579a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        updateAutoPairingData(address);
2589a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mAutoPairingDynamicAddressBlacklist.add(address);
2599a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2609a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2619a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
2629a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return getAttempt(address) != 0;
2639a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2649a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2659a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized void clearPinAttempts(String address) {
266a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        if (DBG) Log.d(TAG, "clearPinAttempts: " + address);
267a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie
2689a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mPinAttempt.remove(address);
2699a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2709a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2719a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized boolean hasAutoPairingFailed(String address) {
2729a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mAutoPairingDynamicAddressBlacklist == null) return false;
2739a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2749a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return mAutoPairingDynamicAddressBlacklist.contains(address);
2759a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2769a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2779a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized int getAttempt(String address) {
2789a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        Integer attempt = mPinAttempt.get(address);
2799a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (attempt == null) {
2809a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            return 0;
2819a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
2829a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        return attempt.intValue();
2839a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2849a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
2859a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    public synchronized void attempt(String address) {
2869a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        Integer attempt = mPinAttempt.get(address);
2879a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        int newAttempt;
2889a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (attempt == null) {
2899a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            newAttempt = 1;
2909a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } else {
2919a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            newAttempt = attempt.intValue() + 1;
2929a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
293a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        if (DBG) Log.d(TAG, "attemp newAttempt: " + newAttempt);
294a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie
2959a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        mPinAttempt.put(address, new Integer(newAttempt));
2969a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
2979a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
298abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    private void getProfileProxy() {
299abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
300abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
301abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        if (mA2dpProxy == null) {
302abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
303abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                                             BluetoothProfile.A2DP);
304abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
305abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
306abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        if (mHeadsetProxy == null) {
307abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
308abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                                             BluetoothProfile.HEADSET);
309abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
310abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    }
311abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
312abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    private void closeProfileProxy() {
313abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
314abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
315abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        if (mA2dpProxy != null) {
316abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mA2dpProxy);
317abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
318abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
319abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        if (mHeadsetProxy != null) {
320abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetProxy);
321abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
322abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    }
323abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
324abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    private BluetoothProfile.ServiceListener mProfileServiceListener =
325abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        new BluetoothProfile.ServiceListener() {
326abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
327abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        public void onServiceConnected(int profile, BluetoothProfile proxy) {
328abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            if (profile == BluetoothProfile.A2DP) {
329abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                mA2dpProxy = (BluetoothA2dp) proxy;
330abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            } else if (profile == BluetoothProfile.HEADSET) {
331abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                mHeadsetProxy = (BluetoothHeadset) proxy;
332abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            }
333abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
334abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
335abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        public void onServiceDisconnected(int profile) {
336abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            if (profile == BluetoothProfile.A2DP) {
337abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                mA2dpProxy = null;
338abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            } else if (profile == BluetoothProfile.HEADSET) {
339abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                mHeadsetProxy = null;
340abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            }
341abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
342abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    };
343abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
3449a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private void copyAutoPairingData() {
3459a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        FileInputStream in = null;
3469a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        FileOutputStream out = null;
3479a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        try {
3489a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            File file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
3499a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (file.exists()) return;
3509a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
3519a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
3529a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
3539a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
3549a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            byte[] buf = new byte[1024];
3559a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            int len;
3569a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            while ((len = in.read(buf)) > 0) {
3579a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                out.write(buf, 0, len);
3589a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
3599a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } catch (FileNotFoundException e) {
3609a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.e(TAG, "FileNotFoundException: copyAutoPairingData " + e);
3619a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } catch (IOException e) {
3629a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.e(TAG, "IOException: copyAutoPairingData " + e);
3639a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } finally {
3649a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby             try {
3659a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                 if (in != null) in.close();
3669a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                 if (out != null) out.close();
3679a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby             } catch (IOException e) {}
3689a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
3699a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
3709a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
3719a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    synchronized public void readAutoPairingData() {
3729a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        if (mAutoPairingAddressBlacklist != null) return;
3739a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        copyAutoPairingData();
3749a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        FileInputStream fstream = null;
3759a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        try {
3769a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            fstream = new FileInputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
3779a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            DataInputStream in = new DataInputStream(fstream);
3789a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            BufferedReader file = new BufferedReader(new InputStreamReader(in));
3799a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            String line;
3809a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            while((line = file.readLine()) != null) {
3819a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                line = line.trim();
3829a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                if (line.length() == 0 || line.startsWith("//")) continue;
3839a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                String[] value = line.split("=");
3849a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                if (value != null && value.length == 2) {
3859a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    String[] val = value[1].split(",");
3869a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    if (value[0].equalsIgnoreCase("AddressBlacklist")) {
3879a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                        mAutoPairingAddressBlacklist =
3889a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                            new ArrayList<String>(Arrays.asList(val));
3899a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    } else if (value[0].equalsIgnoreCase("ExactNameBlacklist")) {
3909a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                        mAutoPairingExactNameBlacklist =
3919a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                            new ArrayList<String>(Arrays.asList(val));
3929a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
3939a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                        mAutoPairingPartialNameBlacklist =
3949a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                            new ArrayList<String>(Arrays.asList(val));
3959a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    } else if (value[0].equalsIgnoreCase("FixedPinZerosKeyboardBlacklist")) {
3969a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                        mAutoPairingFixedPinZerosKeyboardList =
3979a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                            new ArrayList<String>(Arrays.asList(val));
3989a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
3999a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                        mAutoPairingDynamicAddressBlacklist =
4009a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                            new ArrayList<String>(Arrays.asList(val));
4019a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    } else {
4029a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                        Log.e(TAG, "Error parsing Auto pairing blacklist file");
4039a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    }
4049a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                }
4059a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
4069a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } catch (FileNotFoundException e) {
4079a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.e(TAG, "FileNotFoundException: readAutoPairingData " + e);
4089a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } catch (IOException e) {
4099a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.e(TAG, "IOException: readAutoPairingData " + e);
4109a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } finally {
4119a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (fstream != null) {
4129a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                try {
4139a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    fstream.close();
4149a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                } catch (IOException e) {
4159a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    // Ignore
4169a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                }
4179a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
4189a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
4199a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
4209a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby
4219a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    // This function adds a bluetooth address to the auto pairing blacklist
4229a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    // file. These addresses are added to DynamicAddressBlacklistSection
4239a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    private void updateAutoPairingData(String address) {
4249a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        BufferedWriter out = null;
4259a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        try {
4269a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            out = new BufferedWriter(new FileWriter(DYNAMIC_AUTO_PAIRING_BLACKLIST, true));
4279a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            StringBuilder str = new StringBuilder();
4289a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (mAutoPairingDynamicAddressBlacklist.size() == 0) {
4299a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                str.append("DynamicAddressBlacklist=");
4309a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
4319a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            str.append(address);
4329a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            str.append(",");
4339a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            out.write(str.toString());
4349a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } catch (FileNotFoundException e) {
4359a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.e(TAG, "FileNotFoundException: updateAutoPairingData " + e);
4369a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } catch (IOException e) {
4379a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            Log.e(TAG, "IOException: updateAutoPairingData " + e);
4389a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        } finally {
4399a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            if (out != null) {
4409a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                try {
4419a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    out.close();
4429a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                } catch (IOException e) {
4439a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                    // Ignore
4449a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby                }
4459a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby            }
4469a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby        }
4479a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby    }
448abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
449abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    // Set service priority of Hid, A2DP and Headset profiles depending on
450abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    // the bond state change
451abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    private void setProfilePriorities(String address, int state) {
452abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        BluetoothDevice remoteDevice = mService.getRemoteDevice(address);
453abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        // HID is handled by BluetoothService
454abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        mBluetoothInputProfileHandler.setInitialInputDevicePriority(remoteDevice, state);
455abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
456abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        // Set service priority of A2DP and Headset
457abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        // We used to do the priority change in the 2 services after the broadcast
458abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        //   intent reach them. But that left a small time gap that could reject
459abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        //   incoming connection due to undefined priorities.
460abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        if (state == BluetoothDevice.BOND_BONDED) {
46189d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            if (mA2dpProxy != null &&
46289d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh                  mA2dpProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
463abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
464abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            }
465abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
46689d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            if (mHeadsetProxy != null &&
46789d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh                  mHeadsetProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
468abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie                mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
469abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie            }
470abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        } else if (state == BluetoothDevice.BOND_NONE) {
47189d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            if (mA2dpProxy != null) {
47289d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh                mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
47389d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            }
47489d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            if (mHeadsetProxy != null) {
47589d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh                mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
47689d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            }
47789d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh        }
47889d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh
47989d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh        if (mA2dpProxy == null || mHeadsetProxy == null) {
48089d55ad781c6f1eba77342c89136dce41a7de72aJaikumar Ganesh            Log.e(TAG, "Proxy is null:" + mA2dpProxy + ":" + mHeadsetProxy);
481abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie        }
482abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie    }
483abc3642d6c72051b8a5aadebcb39d4da2ea1bb42Matthew Xie
484d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
485d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        @Override
486d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        public void onReceive(Context context, Intent intent) {
487d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            if (intent == null) return;
488d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh
489d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            String action = intent.getAction();
490d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
491d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh                BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
492d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh                String address = dev.getAddress();
493d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh                mPairingRequestRcvd.add(address);
494d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh            }
495d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh        }
496d3728cb32fbd0a85bc77f4bcbdfea386ede2c75fJaikumar Ganesh    };
4979a62c9cd6585656f4e29ba971b1f88a510d674bdJake Hamby}
498