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 Ganesh/**
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * @hide
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth.btservice;
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.app.Application;
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.app.Service;
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothDevice;
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothProfile;
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.IBluetooth;
294852c5686229f1014e9851f4e9a3a19547581b45fredcimport android.bluetooth.IBluetoothCallback;
309a0efb0ee8c63797280b3b9309782541134e9205fredcimport android.bluetooth.IBluetoothManager;
319a0efb0ee8c63797280b3b9309782541134e9205fredcimport android.bluetooth.IBluetoothManagerCallback;
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.BroadcastReceiver;
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.ContentResolver;
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context;
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent;
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.IntentFilter;
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Binder;
389a0efb0ee8c63797280b3b9309782541134e9205fredcimport android.os.Bundle;
396654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.os.Handler;
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.IBinder;
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message;
42cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xieimport android.os.ParcelFileDescriptor;
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.ParcelUuid;
4437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport android.os.Process;
454852c5686229f1014e9851f4e9a3a19547581b45fredcimport android.os.RemoteCallbackList;
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.RemoteException;
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.provider.Settings;
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log;
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Pair;
506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport com.android.bluetooth.a2dp.A2dpService;
5135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport com.android.bluetooth.hid.HidService;
52676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xieimport com.android.bluetooth.hfp.HeadsetService;
53676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xieimport com.android.bluetooth.hdp.HealthService;
546654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport com.android.bluetooth.pan.PanService;
55a7e8ef3f77ac74449f817f36f570a3545285be85fredcimport com.android.bluetooth.R;
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.Utils;
57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
58cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xieimport java.io.FileDescriptor;
59cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xieimport java.io.IOException;
60a7e8ef3f77ac74449f817f36f570a3545285be85fredcimport java.util.ArrayList;
61ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.HashMap;
62ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.Set;
636654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Map;
646654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Iterator;
656654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Map.Entry;
664f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Battaimport java.util.List;
676654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.content.pm.PackageManager;
689a0efb0ee8c63797280b3b9309782541134e9205fredcimport android.os.ServiceManager;
696654f5c903de510a70f9e72cd5ad7837b615d93ffredc
706654f5c903de510a70f9e72cd5ad7837b615d93ffredcpublic class AdapterService extends Service {
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final String TAG = "BluetoothAdapterService";
72fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie    private static final boolean DBG = false;
7374ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static final boolean TRACE_REF = true;
7474ae04c73312403e89db0f8e9bd9601d403b4783fredc    //For Debugging only
7574ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static int sRefCount=0;
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public static final String ACTION_LOAD_ADAPTER_PROPERTIES="com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES";
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public static final String ACTION_SERVICE_STATE_CHANGED="com.android.bluetooth.btservice.action.STATE_CHANGED";
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public static final String EXTRA_ACTION="action";
804f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public static final int PROFILE_CONN_CONNECTED  = 1;
814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public static final int PROFILE_CONN_REJECTED  = 2;
826654f5c903de510a70f9e72cd5ad7837b615d93ffredc
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final String BLUETOOTH_ADMIN_PERM =
84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        android.Manifest.permission.BLUETOOTH_ADMIN;
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
8731ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY;
8831ba132491053bc86d419a7d51fc04af3299c076fredc
8931ba132491053bc86d419a7d51fc04af3299c076fredc    static {
9031ba132491053bc86d419a7d51fc04af3299c076fredc        classInitNative();
9131ba132491053bc86d419a7d51fc04af3299c076fredc    }
9231ba132491053bc86d419a7d51fc04af3299c076fredc
9331ba132491053bc86d419a7d51fc04af3299c076fredc    private static AdapterService sAdapterService;
9474ae04c73312403e89db0f8e9bd9601d403b4783fredc    public static synchronized AdapterService getAdapterService(){
9574ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (sAdapterService != null && !sAdapterService.mCleaningUp) {
9674ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (DBG) Log.d(TAG, "getAdapterService(): returning " + sAdapterService);
9774ae04c73312403e89db0f8e9bd9601d403b4783fredc            return sAdapterService;
9874ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
9974ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG)  {
10074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (sAdapterService == null) {
10174ae04c73312403e89db0f8e9bd9601d403b4783fredc                Log.d(TAG, "getAdapterService(): service not available");
10274ae04c73312403e89db0f8e9bd9601d403b4783fredc            } else if (sAdapterService.mCleaningUp) {
10374ae04c73312403e89db0f8e9bd9601d403b4783fredc                Log.d(TAG,"getAdapterService(): service is cleaning up");
10474ae04c73312403e89db0f8e9bd9601d403b4783fredc            }
10574ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
10674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return null;
10731ba132491053bc86d419a7d51fc04af3299c076fredc    }
10831ba132491053bc86d419a7d51fc04af3299c076fredc
10974ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static synchronized void setAdapterService(AdapterService instance) {
11074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (instance != null && !instance.mCleaningUp) {
11174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (DBG) Log.d(TAG, "setAdapterService(): set to: " + sAdapterService);
11274ae04c73312403e89db0f8e9bd9601d403b4783fredc            sAdapterService = instance;
11374ae04c73312403e89db0f8e9bd9601d403b4783fredc        } else {
11474ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (DBG)  {
11574ae04c73312403e89db0f8e9bd9601d403b4783fredc                if (sAdapterService == null) {
11674ae04c73312403e89db0f8e9bd9601d403b4783fredc                    Log.d(TAG, "setAdapterService(): service not available");
11774ae04c73312403e89db0f8e9bd9601d403b4783fredc                } else if (sAdapterService.mCleaningUp) {
11874ae04c73312403e89db0f8e9bd9601d403b4783fredc                    Log.d(TAG,"setAdapterService(): service is cleaning up");
11974ae04c73312403e89db0f8e9bd9601d403b4783fredc                }
12074ae04c73312403e89db0f8e9bd9601d403b4783fredc            }
12174ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
12274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
12374ae04c73312403e89db0f8e9bd9601d403b4783fredc
12474ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static synchronized void clearAdapterService() {
12574ae04c73312403e89db0f8e9bd9601d403b4783fredc        sAdapterService = null;
12674ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
12874ae04c73312403e89db0f8e9bd9601d403b4783fredc    private AdapterProperties mAdapterProperties;
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private AdapterState mAdapterStateMachine;
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private BondStateMachine mBondStateMachine;
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private JniCallbacks mJniCallbacks;
1326654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private RemoteDevices mRemoteDevices;
1336654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private boolean mProfilesStarted;
1346654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private boolean mNativeAvailable;
13574ae04c73312403e89db0f8e9bd9601d403b4783fredc    private boolean mCleaningUp;
1366654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private HashMap<String,Integer> mProfileServicesState = new HashMap<String,Integer>();
1374852c5686229f1014e9851f4e9a3a19547581b45fredc    private RemoteCallbackList<IBluetoothCallback> mCallbacks;//Only BluetoothManagerService should be registered
13831ba132491053bc86d419a7d51fc04af3299c076fredc    private int mCurrentRequestId;
139ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta    private boolean mQuietmode = false;
1406654f5c903de510a70f9e72cd5ad7837b615d93ffredc
14174ae04c73312403e89db0f8e9bd9601d403b4783fredc    public AdapterService() {
14274ae04c73312403e89db0f8e9bd9601d403b4783fredc        super();
14374ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (TRACE_REF) {
14474ae04c73312403e89db0f8e9bd9601d403b4783fredc            synchronized (AdapterService.class) {
14574ae04c73312403e89db0f8e9bd9601d403b4783fredc                sRefCount++;
14674ae04c73312403e89db0f8e9bd9601d403b4783fredc                Log.d(TAG, "REFCOUNT: CREATED. INSTANCE_COUNT" + sRefCount);
14774ae04c73312403e89db0f8e9bd9601d403b4783fredc            }
14874ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
14974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
15074ae04c73312403e89db0f8e9bd9601d403b4783fredc
1519a0efb0ee8c63797280b3b9309782541134e9205fredc    public void onProfileConnectionStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) {
1529a0efb0ee8c63797280b3b9309782541134e9205fredc        Message m = mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED);
1539a0efb0ee8c63797280b3b9309782541134e9205fredc        m.obj = device;
1549a0efb0ee8c63797280b3b9309782541134e9205fredc        m.arg1 = profileId;
1559a0efb0ee8c63797280b3b9309782541134e9205fredc        m.arg2 = newState;
1569a0efb0ee8c63797280b3b9309782541134e9205fredc        Bundle b = new Bundle(1);
1579a0efb0ee8c63797280b3b9309782541134e9205fredc        b.putInt("prevState", prevState);
158404743adf7bde44df9c8571f7890bc11f613d7aeKausik Sinnaswamy        m.setData(b);
1599a0efb0ee8c63797280b3b9309782541134e9205fredc        mHandler.sendMessage(m);
1609a0efb0ee8c63797280b3b9309782541134e9205fredc    }
1619a0efb0ee8c63797280b3b9309782541134e9205fredc
1629a0efb0ee8c63797280b3b9309782541134e9205fredc    private void processProfileStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) {
1634f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (((profileId == BluetoothProfile.A2DP) ||(profileId == BluetoothProfile.HEADSET)) &&
1644f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (newState == BluetoothProfile.STATE_CONNECTED)){
1654f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (DBG) debugLog( "Profile connected. Schedule missing profile connection if any");
1664f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            connectOtherProfile(device, PROFILE_CONN_CONNECTED);
1674f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            setProfileAutoConnectionPriority(device, profileId);
1684f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
16974ae04c73312403e89db0f8e9bd9601d403b4783fredc        IBluetooth.Stub binder = mBinder;
17074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (binder != null) {
1719a0efb0ee8c63797280b3b9309782541134e9205fredc            try {
17274ae04c73312403e89db0f8e9bd9601d403b4783fredc                binder.sendConnectionStateChange(device, profileId, newState,prevState);
1739a0efb0ee8c63797280b3b9309782541134e9205fredc            } catch (RemoteException re) {
1749a0efb0ee8c63797280b3b9309782541134e9205fredc                Log.e(TAG, "",re);
1759a0efb0ee8c63797280b3b9309782541134e9205fredc            }
1769a0efb0ee8c63797280b3b9309782541134e9205fredc        }
1779a0efb0ee8c63797280b3b9309782541134e9205fredc    }
1789a0efb0ee8c63797280b3b9309782541134e9205fredc
1796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void onProfileServiceStateChanged(String serviceName, int state) {
1809a0efb0ee8c63797280b3b9309782541134e9205fredc        Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
1819a0efb0ee8c63797280b3b9309782541134e9205fredc        m.obj=serviceName;
1829a0efb0ee8c63797280b3b9309782541134e9205fredc        m.arg1 = state;
1839a0efb0ee8c63797280b3b9309782541134e9205fredc        mHandler.sendMessage(m);
1849a0efb0ee8c63797280b3b9309782541134e9205fredc    }
1859a0efb0ee8c63797280b3b9309782541134e9205fredc
1869a0efb0ee8c63797280b3b9309782541134e9205fredc    private void processProfileServiceStateChanged(String serviceName, int state) {
1876654f5c903de510a70f9e72cd5ad7837b615d93ffredc        boolean doUpdate=false;
18831ba132491053bc86d419a7d51fc04af3299c076fredc        boolean isTurningOn;
18931ba132491053bc86d419a7d51fc04af3299c076fredc        boolean isTurningOff;
19031ba132491053bc86d419a7d51fc04af3299c076fredc
1916654f5c903de510a70f9e72cd5ad7837b615d93ffredc        synchronized (mProfileServicesState) {
1926654f5c903de510a70f9e72cd5ad7837b615d93ffredc            Integer prevState = mProfileServicesState.get(serviceName);
1936654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (prevState != null && prevState != state) {
1946654f5c903de510a70f9e72cd5ad7837b615d93ffredc                mProfileServicesState.put(serviceName,state);
1956654f5c903de510a70f9e72cd5ad7837b615d93ffredc                doUpdate=true;
1966654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
1976654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
19831ba132491053bc86d419a7d51fc04af3299c076fredc        if (DBG) Log.d(TAG,"onProfileServiceStateChange: serviceName=" + serviceName + ", state = " + state +", doUpdate = " + doUpdate);
19931ba132491053bc86d419a7d51fc04af3299c076fredc
2006654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (!doUpdate) {
2016654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return;
2026654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
20331ba132491053bc86d419a7d51fc04af3299c076fredc
20431ba132491053bc86d419a7d51fc04af3299c076fredc        synchronized (mAdapterStateMachine) {
20531ba132491053bc86d419a7d51fc04af3299c076fredc            isTurningOff = mAdapterStateMachine.isTurningOff();
20631ba132491053bc86d419a7d51fc04af3299c076fredc            isTurningOn = mAdapterStateMachine.isTurningOn();
20731ba132491053bc86d419a7d51fc04af3299c076fredc        }
20831ba132491053bc86d419a7d51fc04af3299c076fredc
20931ba132491053bc86d419a7d51fc04af3299c076fredc        if (isTurningOff) {
2106654f5c903de510a70f9e72cd5ad7837b615d93ffredc            //Process stop or disable pending
2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc            //Check if all services are stopped if so, do cleanup
212b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            //if (DBG) Log.d(TAG,"Checking if all profiles are stopped...");
2136654f5c903de510a70f9e72cd5ad7837b615d93ffredc            synchronized (mProfileServicesState) {
2146654f5c903de510a70f9e72cd5ad7837b615d93ffredc                Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator();
2156654f5c903de510a70f9e72cd5ad7837b615d93ffredc                while (i.hasNext()) {
2166654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    Map.Entry<String,Integer> entry = i.next();
2176654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    if (BluetoothAdapter.STATE_OFF != entry.getValue()) {
21831ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.d(TAG, "Profile still running: " + entry.getKey());
2196654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        return;
2206654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    }
2216654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
2226654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
2236654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (DBG) Log.d(TAG, "All profile services stopped...");
22474ae04c73312403e89db0f8e9bd9601d403b4783fredc            //Send message to state machine
22574ae04c73312403e89db0f8e9bd9601d403b4783fredc            mProfilesStarted=false;
22674ae04c73312403e89db0f8e9bd9601d403b4783fredc            mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STOPPED));
22731ba132491053bc86d419a7d51fc04af3299c076fredc        } else if (isTurningOn) {
2286654f5c903de510a70f9e72cd5ad7837b615d93ffredc            //Process start pending
2296654f5c903de510a70f9e72cd5ad7837b615d93ffredc            //Check if all services are started if so, update state
230b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            //if (DBG) Log.d(TAG,"Checking if all profiles are running...");
2316654f5c903de510a70f9e72cd5ad7837b615d93ffredc            synchronized (mProfileServicesState) {
2326654f5c903de510a70f9e72cd5ad7837b615d93ffredc                Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator();
2336654f5c903de510a70f9e72cd5ad7837b615d93ffredc                while (i.hasNext()) {
2346654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    Map.Entry<String,Integer> entry = i.next();
2356654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    if (BluetoothAdapter.STATE_ON != entry.getValue()) {
23631ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.d(TAG, "Profile still not running:" + entry.getKey());
2376654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        return;
2386654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    }
2396654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
2406654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
2416654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (DBG) Log.d(TAG, "All profile services started.");
24274ae04c73312403e89db0f8e9bd9601d403b4783fredc            mProfilesStarted=true;
24374ae04c73312403e89db0f8e9bd9601d403b4783fredc            //Send message to state machine
24474ae04c73312403e89db0f8e9bd9601d403b4783fredc            mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED));
2456654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    @Override
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    public void onCreate() {
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super.onCreate();
25131ba132491053bc86d419a7d51fc04af3299c076fredc        if (DBG) debugLog("onCreate");
25274ae04c73312403e89db0f8e9bd9601d403b4783fredc        mBinder = new AdapterServiceBinder(this);
25374ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterProperties = new AdapterProperties(this);
2546893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        mAdapterStateMachine =  AdapterState.make(this, mAdapterProperties);
25574ae04c73312403e89db0f8e9bd9601d403b4783fredc        mJniCallbacks =  new JniCallbacks(mAdapterStateMachine, mAdapterProperties);
2566654f5c903de510a70f9e72cd5ad7837b615d93ffredc        initNative();
2576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mNativeAvailable=true;
2584852c5686229f1014e9851f4e9a3a19547581b45fredc        mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
2596654f5c903de510a70f9e72cd5ad7837b615d93ffredc        //Load the name and address
2606654f5c903de510a70f9e72cd5ad7837b615d93ffredc        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
2616654f5c903de510a70f9e72cd5ad7837b615d93ffredc        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
26274ae04c73312403e89db0f8e9bd9601d403b4783fredc
2636654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
2656654f5c903de510a70f9e72cd5ad7837b615d93ffredc    @Override
2666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public IBinder onBind(Intent intent) {
26731ba132491053bc86d419a7d51fc04af3299c076fredc        if (DBG) debugLog("onBind");
2686654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return mBinder;
2696654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2706654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public boolean onUnbind(Intent intent) {
2711c03c84f90991f6c9c740d72d91716d4b6a933e4zzy        if (DBG) debugLog("onUnbind, calling cleanup");
2721c03c84f90991f6c9c740d72d91716d4b6a933e4zzy        cleanup();
2736654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return super.onUnbind(intent);
2746654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2756654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2766654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void onDestroy() {
27731ba132491053bc86d419a7d51fc04af3299c076fredc        debugLog("****onDestroy()********");
2786654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2796654f5c903de510a70f9e72cd5ad7837b615d93ffredc
28031ba132491053bc86d419a7d51fc04af3299c076fredc    void processStart() {
28131ba132491053bc86d419a7d51fc04af3299c076fredc        if (DBG) debugLog("processStart()");
28257a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie        Class[] supportedProfileServices = Config.getSupportedProfiles();
28331ba132491053bc86d419a7d51fc04af3299c076fredc        //Initialize data objects
28457a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie        for (int i=0; i < supportedProfileServices.length;i++) {
28557a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie            mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF);
28631ba132491053bc86d419a7d51fc04af3299c076fredc        }
28774ae04c73312403e89db0f8e9bd9601d403b4783fredc        mRemoteDevices = new RemoteDevices(this);
28831ba132491053bc86d419a7d51fc04af3299c076fredc        mAdapterProperties.init(mRemoteDevices);
289b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
2906893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        if (DBG) {debugLog("processStart(): Make Bond State Machine");}
2916893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
2926893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville
2936893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        mJniCallbacks.init(mBondStateMachine,mRemoteDevices);
29431ba132491053bc86d419a7d51fc04af3299c076fredc
29574ae04c73312403e89db0f8e9bd9601d403b4783fredc        //FIXME: Set static instance here???
29674ae04c73312403e89db0f8e9bd9601d403b4783fredc        setAdapterService(this);
29774ae04c73312403e89db0f8e9bd9601d403b4783fredc
2986654f5c903de510a70f9e72cd5ad7837b615d93ffredc        //Start profile services
29957a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie        if (!mProfilesStarted && supportedProfileServices.length >0) {
30031ba132491053bc86d419a7d51fc04af3299c076fredc            //Startup all profile services
30157a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie            setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
30274ae04c73312403e89db0f8e9bd9601d403b4783fredc        }else {
30374ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (DBG) {debugLog("processStart(): Profile Services alreay started");}
30474ae04c73312403e89db0f8e9bd9601d403b4783fredc            mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED));
3056654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
30831ba132491053bc86d419a7d51fc04af3299c076fredc    void startBluetoothDisable() {
30974ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BEGIN_DISABLE));
310b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
311b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
31231ba132491053bc86d419a7d51fc04af3299c076fredc    boolean stopProfileServices() {
31357a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie        Class[] supportedProfileServices = Config.getSupportedProfiles();
31457a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie        if (mProfilesStarted && supportedProfileServices.length>0) {
31557a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie            setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_OFF);
31674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return true;
31774ae04c73312403e89db0f8e9bd9601d403b4783fredc        } else {
31874ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (DBG) {debugLog("stopProfileServices(): No profiles services to stop or already stopped.");}
31931ba132491053bc86d419a7d51fc04af3299c076fredc            return false;
320b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
321b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
322b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
3234852c5686229f1014e9851f4e9a3a19547581b45fredc     void updateAdapterState(int prevState, int newState){
3244852c5686229f1014e9851f4e9a3a19547581b45fredc        if (mCallbacks !=null) {
3254852c5686229f1014e9851f4e9a3a19547581b45fredc            int n=mCallbacks.beginBroadcast();
3264852c5686229f1014e9851f4e9a3a19547581b45fredc            Log.d(TAG,"Broadcasting updateAdapterState() to " + n + " receivers.");
3274852c5686229f1014e9851f4e9a3a19547581b45fredc            for (int i=0; i <n;i++) {
3284852c5686229f1014e9851f4e9a3a19547581b45fredc                try {
3294852c5686229f1014e9851f4e9a3a19547581b45fredc                    mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState);
3304852c5686229f1014e9851f4e9a3a19547581b45fredc                }  catch (RemoteException e) {
3314852c5686229f1014e9851f4e9a3a19547581b45fredc                    Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
3324852c5686229f1014e9851f4e9a3a19547581b45fredc                }
3334852c5686229f1014e9851f4e9a3a19547581b45fredc            }
3344852c5686229f1014e9851f4e9a3a19547581b45fredc            mCallbacks.finishBroadcast();
3354852c5686229f1014e9851f4e9a3a19547581b45fredc        }
3364852c5686229f1014e9851f4e9a3a19547581b45fredc    }
3374852c5686229f1014e9851f4e9a3a19547581b45fredc
33831ba132491053bc86d419a7d51fc04af3299c076fredc    void cleanup () {
33931ba132491053bc86d419a7d51fc04af3299c076fredc        if (DBG)debugLog("cleanup()");
34074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mCleaningUp) {
34174ae04c73312403e89db0f8e9bd9601d403b4783fredc            Log.w(TAG,"*************service already starting to cleanup... Ignoring cleanup request.........");
34274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return;
343b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
344b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
34574ae04c73312403e89db0f8e9bd9601d403b4783fredc        mCleaningUp = true;
34674ae04c73312403e89db0f8e9bd9601d403b4783fredc
34731ba132491053bc86d419a7d51fc04af3299c076fredc        if (mAdapterStateMachine != null) {
34815d36984a79d6e35c659edb0efdf929f0b526bd5Fred            mAdapterStateMachine.doQuit();
34931ba132491053bc86d419a7d51fc04af3299c076fredc            mAdapterStateMachine.cleanup();
35031ba132491053bc86d419a7d51fc04af3299c076fredc        }
35131ba132491053bc86d419a7d51fc04af3299c076fredc
35274ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mBondStateMachine != null) {
35315d36984a79d6e35c659edb0efdf929f0b526bd5Fred            mBondStateMachine.doQuit();
35474ae04c73312403e89db0f8e9bd9601d403b4783fredc            mBondStateMachine.cleanup();
35574ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
35674ae04c73312403e89db0f8e9bd9601d403b4783fredc
35731ba132491053bc86d419a7d51fc04af3299c076fredc        if (mRemoteDevices != null) {
35831ba132491053bc86d419a7d51fc04af3299c076fredc            mRemoteDevices.cleanup();
35931ba132491053bc86d419a7d51fc04af3299c076fredc        }
36031ba132491053bc86d419a7d51fc04af3299c076fredc
36174ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mNativeAvailable) {
36274ae04c73312403e89db0f8e9bd9601d403b4783fredc            Log.d(TAG, "Cleaning up adapter native....");
36374ae04c73312403e89db0f8e9bd9601d403b4783fredc            cleanupNative();
36474ae04c73312403e89db0f8e9bd9601d403b4783fredc            Log.d(TAG, "Done cleaning up adapter native....");
36574ae04c73312403e89db0f8e9bd9601d403b4783fredc            mNativeAvailable=false;
36674ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
36774ae04c73312403e89db0f8e9bd9601d403b4783fredc
36831ba132491053bc86d419a7d51fc04af3299c076fredc        if (mAdapterProperties != null) {
36931ba132491053bc86d419a7d51fc04af3299c076fredc            mAdapterProperties.cleanup();
37031ba132491053bc86d419a7d51fc04af3299c076fredc        }
37131ba132491053bc86d419a7d51fc04af3299c076fredc
37274ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mJniCallbacks != null) {
37374ae04c73312403e89db0f8e9bd9601d403b4783fredc            mJniCallbacks.cleanup();
37474ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
3756654f5c903de510a70f9e72cd5ad7837b615d93ffredc
37674ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mProfileServicesState != null) {
37774ae04c73312403e89db0f8e9bd9601d403b4783fredc            mProfileServicesState.clear();
37874ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
37931ba132491053bc86d419a7d51fc04af3299c076fredc
38074ae04c73312403e89db0f8e9bd9601d403b4783fredc        clearAdapterService();
38174ae04c73312403e89db0f8e9bd9601d403b4783fredc
38274ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mBinder != null) {
38374ae04c73312403e89db0f8e9bd9601d403b4783fredc            mBinder.cleanup();
38415d36984a79d6e35c659edb0efdf929f0b526bd5Fred            mBinder = null;  //Do not remove. Otherwise Binder leak!
38574ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
3864852c5686229f1014e9851f4e9a3a19547581b45fredc
3874852c5686229f1014e9851f4e9a3a19547581b45fredc        if (mCallbacks !=null) {
3884852c5686229f1014e9851f4e9a3a19547581b45fredc            mCallbacks.kill();
3894852c5686229f1014e9851f4e9a3a19547581b45fredc        }
3904852c5686229f1014e9851f4e9a3a19547581b45fredc
39174ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG)debugLog("cleanup() done");
39274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
39331ba132491053bc86d419a7d51fc04af3299c076fredc
3949a0efb0ee8c63797280b3b9309782541134e9205fredc    private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED =1;
395b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20;
3964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private static final int MESSAGE_CONNECT_OTHER_PROFILES = 30;
3974f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000;
3989a0efb0ee8c63797280b3b9309782541134e9205fredc
3996654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private final Handler mHandler = new Handler() {
4006654f5c903de510a70f9e72cd5ad7837b615d93ffredc        @Override
4016654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public void handleMessage(Message msg) {
40231ba132491053bc86d419a7d51fc04af3299c076fredc            if (DBG) debugLog("Message: " + msg.what);
4036654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4046654f5c903de510a70f9e72cd5ad7837b615d93ffredc            switch (msg.what) {
4059a0efb0ee8c63797280b3b9309782541134e9205fredc                case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: {
40631ba132491053bc86d419a7d51fc04af3299c076fredc                    if(DBG) debugLog("MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
4079a0efb0ee8c63797280b3b9309782541134e9205fredc                    processProfileServiceStateChanged((String) msg.obj, msg.arg1);
4086654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
409b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                    break;
4109a0efb0ee8c63797280b3b9309782541134e9205fredc                case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: {
41131ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) debugLog( "MESSAGE_PROFILE_CONNECTION_STATE_CHANGED");
4129a0efb0ee8c63797280b3b9309782541134e9205fredc                    processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR));
4136654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
414b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                    break;
4154f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                case MESSAGE_CONNECT_OTHER_PROFILES: {
4164f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                    if (DBG) debugLog( "MESSAGE_CONNECT_OTHER_PROFILES");
4174f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                    processConnectOtherProfiles((BluetoothDevice) msg.obj,msg.arg1);
4184f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                }
4194f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                    break;
4206654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
421ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
4226654f5c903de510a70f9e72cd5ad7837b615d93ffredc    };
4236654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4246654f5c903de510a70f9e72cd5ad7837b615d93ffredc    @SuppressWarnings("rawtypes")
42531ba132491053bc86d419a7d51fc04af3299c076fredc    private void setProfileServiceState(Class[] services, int state) {
42631ba132491053bc86d419a7d51fc04af3299c076fredc        if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
42731ba132491053bc86d419a7d51fc04af3299c076fredc            Log.w(TAG,"setProfileServiceState(): invalid state...Leaving...");
4286654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return;
4296654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
4306654f5c903de510a70f9e72cd5ad7837b615d93ffredc
43131ba132491053bc86d419a7d51fc04af3299c076fredc        int expectedCurrentState= BluetoothAdapter.STATE_OFF;
43231ba132491053bc86d419a7d51fc04af3299c076fredc        int pendingState = BluetoothAdapter.STATE_TURNING_ON;
43331ba132491053bc86d419a7d51fc04af3299c076fredc        if (state == BluetoothAdapter.STATE_OFF) {
43431ba132491053bc86d419a7d51fc04af3299c076fredc            expectedCurrentState= BluetoothAdapter.STATE_ON;
43531ba132491053bc86d419a7d51fc04af3299c076fredc            pendingState = BluetoothAdapter.STATE_TURNING_OFF;
43631ba132491053bc86d419a7d51fc04af3299c076fredc        }
4376654f5c903de510a70f9e72cd5ad7837b615d93ffredc
43831ba132491053bc86d419a7d51fc04af3299c076fredc        for (int i=0; i <services.length;i++) {
43931ba132491053bc86d419a7d51fc04af3299c076fredc            String serviceName = services[i].getName();
44031ba132491053bc86d419a7d51fc04af3299c076fredc            Integer serviceState = mProfileServicesState.get(serviceName);
44131ba132491053bc86d419a7d51fc04af3299c076fredc            if(serviceState != null && serviceState != expectedCurrentState) {
44231ba132491053bc86d419a7d51fc04af3299c076fredc                Log.w(TAG, "Unable to " + (state == BluetoothAdapter.STATE_OFF? "start" : "stop" ) +" service " +
44331ba132491053bc86d419a7d51fc04af3299c076fredc                        serviceName+". Invalid state: " + serviceState);
44431ba132491053bc86d419a7d51fc04af3299c076fredc                continue;
44531ba132491053bc86d419a7d51fc04af3299c076fredc            }
44631ba132491053bc86d419a7d51fc04af3299c076fredc
44731ba132491053bc86d419a7d51fc04af3299c076fredc            if (DBG) {
44831ba132491053bc86d419a7d51fc04af3299c076fredc                Log.w(TAG, (state == BluetoothAdapter.STATE_OFF? "Stopping" : "Starting" ) +" service " +
44931ba132491053bc86d419a7d51fc04af3299c076fredc                        serviceName);
45031ba132491053bc86d419a7d51fc04af3299c076fredc            }
45131ba132491053bc86d419a7d51fc04af3299c076fredc
45231ba132491053bc86d419a7d51fc04af3299c076fredc            mProfileServicesState.put(serviceName,pendingState);
45331ba132491053bc86d419a7d51fc04af3299c076fredc            Intent intent = new Intent(this,services[i]);
45431ba132491053bc86d419a7d51fc04af3299c076fredc            intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
45531ba132491053bc86d419a7d51fc04af3299c076fredc            intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);
45631ba132491053bc86d419a7d51fc04af3299c076fredc            startService(intent);
4576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
458ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
459ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
46074ae04c73312403e89db0f8e9bd9601d403b4783fredc    private boolean isAvailable() {
46174ae04c73312403e89db0f8e9bd9601d403b4783fredc        return !mCleaningUp;
46274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
46374ae04c73312403e89db0f8e9bd9601d403b4783fredc
464ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /**
465ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh     * Handlers for incoming service calls
466ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh     */
46774ae04c73312403e89db0f8e9bd9601d403b4783fredc    private AdapterServiceBinder mBinder;
46874ae04c73312403e89db0f8e9bd9601d403b4783fredc
46974ae04c73312403e89db0f8e9bd9601d403b4783fredc    /**
47074ae04c73312403e89db0f8e9bd9601d403b4783fredc     * The Binder implementation must be declared to be a static class, with
47174ae04c73312403e89db0f8e9bd9601d403b4783fredc     * the AdapterService instance passed in the constructor. Furthermore,
47274ae04c73312403e89db0f8e9bd9601d403b4783fredc     * when the AdapterService shuts down, the reference to the AdapterService
47374ae04c73312403e89db0f8e9bd9601d403b4783fredc     * must be explicitly removed.
47474ae04c73312403e89db0f8e9bd9601d403b4783fredc     *
47574ae04c73312403e89db0f8e9bd9601d403b4783fredc     * Otherwise, a memory leak can occur from repeated starting/stopping the
47674ae04c73312403e89db0f8e9bd9601d403b4783fredc     * service...Please refer to android.os.Binder for further details on
47774ae04c73312403e89db0f8e9bd9601d403b4783fredc     * why an inner instance class should be avoided.
47874ae04c73312403e89db0f8e9bd9601d403b4783fredc     *
47974ae04c73312403e89db0f8e9bd9601d403b4783fredc     */
48074ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static class AdapterServiceBinder extends IBluetooth.Stub {
48174ae04c73312403e89db0f8e9bd9601d403b4783fredc        private AdapterService mService;
48274ae04c73312403e89db0f8e9bd9601d403b4783fredc
48374ae04c73312403e89db0f8e9bd9601d403b4783fredc        public AdapterServiceBinder(AdapterService svc) {
48474ae04c73312403e89db0f8e9bd9601d403b4783fredc            mService = svc;
48574ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
48674ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean cleanup() {
48774ae04c73312403e89db0f8e9bd9601d403b4783fredc            mService = null;
48874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return true;
48974ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
49074ae04c73312403e89db0f8e9bd9601d403b4783fredc
49174ae04c73312403e89db0f8e9bd9601d403b4783fredc        public AdapterService getService() {
49274ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (mService  != null && mService.isAvailable()) {
49374ae04c73312403e89db0f8e9bd9601d403b4783fredc                return mService;
49474ae04c73312403e89db0f8e9bd9601d403b4783fredc            }
49574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return null;
49674ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
497ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean isEnabled() {
498bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu            // don't check caller, may be called from system UI
49974ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
50074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
50174ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.isEnabled();
502ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
503ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
504ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getState() {
505bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu            // don't check caller, may be called from system UI
50674ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
50774ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return  BluetoothAdapter.STATE_OFF;
50874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getState();
509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean enable() {
51237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
51337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                (!Utils.checkCaller())) {
51437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"enable(): not allowed for non-active user and non system user");
51537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
51637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu	    }
51737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
51874ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
51974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
52074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.enable();
521ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
522ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
523e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        public boolean enableNoAutoConnect() {
52437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
52537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                (!Utils.checkCaller())) {
52637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"enableNoAuto(): not allowed for non-active user and non system user");
52737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
52837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu	    }
52937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
530ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta            AdapterService service = getService();
531ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta            if (service == null) return false;
532ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta            return service.enableNoAutoConnect();
533e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        }
534e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie
53557a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie        public boolean disable() {
53637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
53737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                (!Utils.checkCaller())) {
53837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"disable(): not allowed for non-active user and non system user");
53937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
54037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu	    }
54137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
54274ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
54374ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
54457a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie            return service.disable();
545ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
546ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
547ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public String getAddress() {
54837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
54937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                (!Utils.checkCaller())) {
55037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getAddress(): not allowed for non-active user and non system user");
55137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
55237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu	    }
55337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
55474ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
55574ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return null;
55674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getAddress();
557ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
558ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
559ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public ParcelUuid[] getUuids() {
56037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
56137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getUuids(): not allowed for non-active user");
56237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return new ParcelUuid[0];
56337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
56437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
56574ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
56674ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return new ParcelUuid[0];
56774ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getUuids();
568ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
569ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
570ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public String getName() {
57137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
57237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                (!Utils.checkCaller())) {
57337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getName(): not allowed for non-active user and non system user");
57437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
57537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu	    }
57637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
57774ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
57874ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return null;
57974ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getName();
580ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
581ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
582ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setName(String name) {
58337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
58437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setName(): not allowed for non-active user");
58537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
58637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
58737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
58874ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
58974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
59074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setName(name);
591ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
592ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
593ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getScanMode() {
59437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
59537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getScanMode(): not allowed for non-active user");
59637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return BluetoothAdapter.SCAN_MODE_NONE;
59737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
59837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
59974ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
60074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothAdapter.SCAN_MODE_NONE;
60174ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getScanMode();
602ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
603ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
604ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setScanMode(int mode, int duration) {
60537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
60637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setScanMode(): not allowed for non-active user");
60737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
60837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
60937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
61074ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
61174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
61274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setScanMode(mode,duration);
613ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
614ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
615ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getDiscoverableTimeout() {
61637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
61737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getDiscoverableTimeout(): not allowed for non-active user");
61837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return 0;
61937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
62037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
62174ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
62274ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return 0;
62374ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getDiscoverableTimeout();
624ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
625ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
626ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setDiscoverableTimeout(int timeout) {
62737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
62837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setDiscoverableTimeout(): not allowed for non-active user");
62937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
63037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
63137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
63274ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
63374ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
63474ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setDiscoverableTimeout(timeout);
635ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
636ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean startDiscovery() {
63837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
63937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"startDiscovery(): not allowed for non-active user");
64037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
64137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
64237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
64374ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
64474ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
64574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.startDiscovery();
646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean cancelDiscovery() {
64937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
65037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"cancelDiscovery(): not allowed for non-active user");
65137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
65237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
65337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
65474ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
65574ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
65674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.cancelDiscovery();
657ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
658ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean isDiscovering() {
65937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
66037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"isDiscovering(): not allowed for non-active user");
66137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
66237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
66337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
66474ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
66574ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
66674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.isDiscovering();
667ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
668ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
669ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public BluetoothDevice[] getBondedDevices() {
670bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu            // don't check caller, may be called from system UI
67174ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
67274ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return new BluetoothDevice[0];
67374ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getBondedDevices();
674ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
675ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
676ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getAdapterConnectionState() {
677bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu            // don't check caller, may be called from system UI
67874ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
67974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothAdapter.STATE_DISCONNECTED;
68074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getAdapterConnectionState();
681ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
682ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
683ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getProfileConnectionState(int profile) {
68437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
68537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getProfileConnectionState: not allowed for non-active user");
68637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return BluetoothProfile.STATE_DISCONNECTED;
68737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
68837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
68974ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
69074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothProfile.STATE_DISCONNECTED;
69174ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getProfileConnectionState(profile);
692ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
693ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
694ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean createBond(BluetoothDevice device) {
69537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
69637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"createBond(): not allowed for non-active user");
69737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
69837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
69937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
70074ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
70174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
70274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.createBond(device);
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
705ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean cancelBondProcess(BluetoothDevice device) {
70637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
70737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"cancelBondProcess(): not allowed for non-active user");
70837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
70937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
71037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
71174ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
71274ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
71374ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.cancelBondProcess(device);
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
715ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
716ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean removeBond(BluetoothDevice device) {
71737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
71837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"removeBond(): not allowed for non-active user");
71937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
72037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
72137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
72274ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
72374ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
72474ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.removeBond(device);
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
726ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getBondState(BluetoothDevice device) {
728bd704c741b8c523ad747214f6f0520ac3e2caf8fZhihai Xu            // don't check caller, may be called from system UI
72974ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
73074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothDevice.BOND_NONE;
73174ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getBondState(device);
732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
733ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public String getRemoteName(BluetoothDevice device) {
73537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
73637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getRemoteName(): not allowed for non-active user");
73737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
73837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
73937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
74074ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
74174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return null;
74274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getRemoteName(device);
743ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
745ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public String getRemoteAlias(BluetoothDevice device) {
74637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
74737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getRemoteAlias(): not allowed for non-active user");
74837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
74937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
75037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
75174ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
75274ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return null;
75374ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getRemoteAlias(device);
754ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
755ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setRemoteAlias(BluetoothDevice device, String name) {
75737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
75837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setRemoteAlias(): not allowed for non-active user");
75937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
76037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
76137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
76274ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
76374ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
76474ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setRemoteAlias(device, name);
765ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
766ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
767ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public int getRemoteClass(BluetoothDevice device) {
76837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
76937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getRemoteClass(): not allowed for non-active user");
77037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return 0;
77137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
77237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
77374ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
77474ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return 0;
77574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getRemoteClass(device);
776ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
777ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
778ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
77937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
78037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"getRemoteUuids(): not allowed for non-active user");
78137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return new ParcelUuid[0];
78237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
78337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
78474ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
78537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (service == null) return new ParcelUuid[0];
78674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getRemoteUuids(device);
787ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
788ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
789ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean fetchRemoteUuids(BluetoothDevice device) {
79037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
79137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"fetchRemoteUuids(): not allowed for non-active user");
79237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
79337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
79437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
79574ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
79674ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
79774ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.fetchRemoteUuids(device);
798ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
799ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
800ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) {
80137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
80237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setPin(): not allowed for non-active user");
80337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
80437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
80537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
80674ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
80774ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
80874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setPin(device, accept, len, pinCode);
809ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
810ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
811ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) {
81237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
81337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setPasskey(): not allowed for non-active user");
81437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
81537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
81637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
81774ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
81874ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
81974ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setPasskey(device, accept, len, passkey);
820ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
821ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
822ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) {
82337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
82437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"setPairingConfirmation(): not allowed for non-active user");
82537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return false;
82637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
82737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
82874ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
82974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
83074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setPairingConfirmation(device, accept);
831ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
832ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
833ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void sendConnectionStateChange(BluetoothDevice
834ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                device, int profile, int state, int prevState) {
83574ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
83674ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return;
83774ae04c73312403e89db0f8e9bd9601d403b4783fredc            service.sendConnectionStateChange(device, profile, state, prevState);
838ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
839ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
840cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type,
841cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                                  ParcelUuid uuid, int port, int flag) {
84237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
84337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"connectSocket(): not allowed for non-active user");
84437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
84537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
84637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
84774ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
84874ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return null;
84974ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.connectSocket(device, type, uuid, port, flag);
850cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        }
851cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
852cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        public ParcelFileDescriptor createSocketChannel(int type, String serviceName,
853cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                                        ParcelUuid uuid, int port, int flag) {
85437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
85537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"createSocketChannel(): not allowed for non-active user");
85637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
85737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
85837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
85974ae04c73312403e89db0f8e9bd9601d403b4783fredc            AdapterService service = getService();
86074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return null;
86174ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.createSocketChannel(type, serviceName, uuid, port, flag);
862cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        }
8634852c5686229f1014e9851f4e9a3a19547581b45fredc
8644852c5686229f1014e9851f4e9a3a19547581b45fredc        public void registerCallback(IBluetoothCallback cb) {
8654852c5686229f1014e9851f4e9a3a19547581b45fredc            AdapterService service = getService();
8664852c5686229f1014e9851f4e9a3a19547581b45fredc            if (service == null) return ;
8674852c5686229f1014e9851f4e9a3a19547581b45fredc            service.registerCallback(cb);
8684852c5686229f1014e9851f4e9a3a19547581b45fredc         }
8694852c5686229f1014e9851f4e9a3a19547581b45fredc
8704852c5686229f1014e9851f4e9a3a19547581b45fredc         public void unregisterCallback(IBluetoothCallback cb) {
8714852c5686229f1014e9851f4e9a3a19547581b45fredc             AdapterService service = getService();
8724852c5686229f1014e9851f4e9a3a19547581b45fredc             if (service == null) return ;
8734852c5686229f1014e9851f4e9a3a19547581b45fredc             service.unregisterCallback(cb);
8744852c5686229f1014e9851f4e9a3a19547581b45fredc         }
875ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    };
876ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
87774ae04c73312403e89db0f8e9bd9601d403b4783fredc
87874ae04c73312403e89db0f8e9bd9601d403b4783fredc    //----API Methods--------
87974ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean isEnabled() {
88074ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
88137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
88274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON;
88374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
88474ae04c73312403e89db0f8e9bd9601d403b4783fredc
88574ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getState() {
88674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
88737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
8884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (mAdapterProperties == null){
8894f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return  BluetoothAdapter.STATE_OFF;
8904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
8914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        else {
8924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            debugLog("getState(): mAdapterProperties: " + mAdapterProperties);
8934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return mAdapterProperties.getState();
8944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
89574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
89674ae04c73312403e89db0f8e9bd9601d403b4783fredc
89774ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean enable() {
898ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta        return enable (false);
89974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
90074ae04c73312403e89db0f8e9bd9601d403b4783fredc
901ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta      public boolean enableNoAutoConnect() {
902ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         return enable (true);
903ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta     }
904ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta
905ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta     public synchronized boolean enable(boolean quietMode) {
906ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
907ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta                 "Need BLUETOOTH ADMIN permission");
908ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         if (DBG)debugLog("Enable called with quiet mode status =  " + mQuietmode);
909ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         mQuietmode  = quietMode;
910ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         Message m =
911ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta                 mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
912ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         mAdapterStateMachine.sendMessage(m);
913ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         return true;
914ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta     }
915ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta
91657a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie     boolean disable() {
91774ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
91874ae04c73312403e89db0f8e9bd9601d403b4783fredc                "Need BLUETOOTH ADMIN permission");
91937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
92074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG) debugLog("disable() called...");
92174ae04c73312403e89db0f8e9bd9601d403b4783fredc        Message m =
92274ae04c73312403e89db0f8e9bd9601d403b4783fredc                mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF);
92374ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterStateMachine.sendMessage(m);
92474ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
92574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
92674ae04c73312403e89db0f8e9bd9601d403b4783fredc
92774ae04c73312403e89db0f8e9bd9601d403b4783fredc     String getAddress() {
92874ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
92937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
93074ae04c73312403e89db0f8e9bd9601d403b4783fredc        String addrString = null;
93174ae04c73312403e89db0f8e9bd9601d403b4783fredc        byte[] address = mAdapterProperties.getAddress();
93274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return Utils.getAddressStringFromByte(address);
93374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
93474ae04c73312403e89db0f8e9bd9601d403b4783fredc
93574ae04c73312403e89db0f8e9bd9601d403b4783fredc     ParcelUuid[] getUuids() {
93674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
93737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
93874ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getUuids();
93974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
94074ae04c73312403e89db0f8e9bd9601d403b4783fredc
94174ae04c73312403e89db0f8e9bd9601d403b4783fredc     String getName() {
94274ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM,
94374ae04c73312403e89db0f8e9bd9601d403b4783fredc                "Need BLUETOOTH permission");
94437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
94574ae04c73312403e89db0f8e9bd9601d403b4783fredc        try {
94674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return mAdapterProperties.getName();
94774ae04c73312403e89db0f8e9bd9601d403b4783fredc        } catch (Throwable t) {
94874ae04c73312403e89db0f8e9bd9601d403b4783fredc            Log.d(TAG, "Unexpected exception while calling getName()",t);
94974ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
95074ae04c73312403e89db0f8e9bd9601d403b4783fredc        return null;
95174ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
95274ae04c73312403e89db0f8e9bd9601d403b4783fredc
95374ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setName(String name) {
95474ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
95574ae04c73312403e89db0f8e9bd9601d403b4783fredc                "Need BLUETOOTH ADMIN permission");
95637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
95774ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.setName(name);
95874ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
95974ae04c73312403e89db0f8e9bd9601d403b4783fredc
96074ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getScanMode() {
96174ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
96237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
96374ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getScanMode();
96474ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
96574ae04c73312403e89db0f8e9bd9601d403b4783fredc
96674ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setScanMode(int mode, int duration) {
96774ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
96837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
96974ae04c73312403e89db0f8e9bd9601d403b4783fredc        setDiscoverableTimeout(duration);
97074ae04c73312403e89db0f8e9bd9601d403b4783fredc
97174ae04c73312403e89db0f8e9bd9601d403b4783fredc        int newMode = convertScanModeToHal(mode);
97274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.setScanMode(newMode);
97374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
97474ae04c73312403e89db0f8e9bd9601d403b4783fredc
97574ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getDiscoverableTimeout() {
97674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
97737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
97874ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getDiscoverableTimeout();
97974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
98074ae04c73312403e89db0f8e9bd9601d403b4783fredc
98174ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setDiscoverableTimeout(int timeout) {
98274ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
98337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
98474ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.setDiscoverableTimeout(timeout);
98574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
98674ae04c73312403e89db0f8e9bd9601d403b4783fredc
98774ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean startDiscovery() {
98874ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
98974ae04c73312403e89db0f8e9bd9601d403b4783fredc                "Need BLUETOOTH ADMIN permission");
99037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
99174ae04c73312403e89db0f8e9bd9601d403b4783fredc        return startDiscoveryNative();
99274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
99374ae04c73312403e89db0f8e9bd9601d403b4783fredc
99474ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean cancelDiscovery() {
99574ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
99674ae04c73312403e89db0f8e9bd9601d403b4783fredc                "Need BLUETOOTH ADMIN permission");
99737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
99874ae04c73312403e89db0f8e9bd9601d403b4783fredc        return cancelDiscoveryNative();
99974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
100074ae04c73312403e89db0f8e9bd9601d403b4783fredc
100174ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean isDiscovering() {
100274ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
100337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
100474ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.isDiscovering();
100574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
100674ae04c73312403e89db0f8e9bd9601d403b4783fredc
100774ae04c73312403e89db0f8e9bd9601d403b4783fredc     BluetoothDevice[] getBondedDevices() {
100874ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
100974ae04c73312403e89db0f8e9bd9601d403b4783fredc        debugLog("Get Bonded Devices being called");
101074ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getBondedDevices();
101174ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
101274ae04c73312403e89db0f8e9bd9601d403b4783fredc
101374ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getAdapterConnectionState() {
101474ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
101537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
101674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getConnectionState();
101774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
101874ae04c73312403e89db0f8e9bd9601d403b4783fredc
101974ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getProfileConnectionState(int profile) {
102074ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
102137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
102274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mAdapterProperties.getProfileConnectionState(profile);
102374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
102474ae04c73312403e89db0f8e9bd9601d403b4783fredc
102574ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean createBond(BluetoothDevice device) {
102674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
102774ae04c73312403e89db0f8e9bd9601d403b4783fredc            "Need BLUETOOTH ADMIN permission");
102874ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
102974ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
103074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
103174ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
103274ae04c73312403e89db0f8e9bd9601d403b4783fredc
103374ae04c73312403e89db0f8e9bd9601d403b4783fredc        Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
103474ae04c73312403e89db0f8e9bd9601d403b4783fredc        msg.obj = device;
103574ae04c73312403e89db0f8e9bd9601d403b4783fredc        mBondStateMachine.sendMessage(msg);
103674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
103774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
103874ae04c73312403e89db0f8e9bd9601d403b4783fredc
1039ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta      public boolean isQuietModeEnabled() {
1040ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta          if (DBG) debugLog("Quiet mode Enabled = " + mQuietmode);
1041ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta          return mQuietmode;
1042ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta     }
1043ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta
10444f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta     public void autoConnect(){
10454f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (getState() != BluetoothAdapter.STATE_ON){
10464f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             errorLog("BT is not ON. Exiting autoConnect");
10474f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             return;
10484f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta         }
1049ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         if (isQuietModeEnabled() == false) {
1050ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta            if (DBG) debugLog( "Initiate auto connection on BT on...");
1051ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta             autoConnectHeadset();
1052ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta             autoConnectA2dp();
1053ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         }
1054ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         else {
1055ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta             if (DBG) debugLog( "BT is in Quiet mode. Not initiating  auto connections");
1056ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta         }
10574f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
10584f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
10594f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta     private void autoConnectHeadset(){
10604f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HeadsetService  hsService = HeadsetService.getHeadsetService();
10614f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
10624f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        BluetoothDevice bondedDevices[] = getBondedDevices();
10634f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((bondedDevices == null) ||(hsService == null)) {
10644f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return;
10654f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
10664f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        for (BluetoothDevice device : bondedDevices) {
10674f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){
10684f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                Log.d(TAG,"Auto Connecting Headset Profile with device " + device.toString());
10694f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                hsService.connect(device);
10704f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                }
10714f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
10724f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
10734f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
10744f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta     private void autoConnectA2dp(){
10754f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        A2dpService a2dpSservice = A2dpService.getA2dpService();
10764f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        BluetoothDevice bondedDevices[] = getBondedDevices();
10774f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((bondedDevices == null) ||(a2dpSservice == null)) {
10784f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return;
10794f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
10804f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        for (BluetoothDevice device : bondedDevices) {
10814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){
10824f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                Log.d(TAG,"Auto Connecting A2DP Profile with device " + device.toString());
10834f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                a2dpSservice.connect(device);
10844f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                }
10854f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
10864f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
10874f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
10884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta     public void connectOtherProfile(BluetoothDevice device, int firstProfileStatus){
1089ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta        if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) &&
1090ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta            (isQuietModeEnabled()== false)){
10914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES);
10924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            m.obj = device;
10934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            m.arg1 = (int)firstProfileStatus;
10944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            mHandler.sendMessageDelayed(m,CONNECT_OTHER_PROFILES_TIMEOUT);
10954f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
10964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
10974f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
10984f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta     private void processConnectOtherProfiles (BluetoothDevice device, int firstProfileStatus){
10994f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (getState()!= BluetoothAdapter.STATE_ON){
11004f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return;
11014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
11024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        HeadsetService  hsService = HeadsetService.getHeadsetService();
11034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        A2dpService a2dpService = A2dpService.getA2dpService();
11044f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        // if any of the profile service is  null, second profile connection not required
11054f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if ((hsService == null) ||(a2dpService == null )){
11064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return;
11074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
11084f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        List<BluetoothDevice> a2dpConnDevList= a2dpService.getConnectedDevices();
11094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        List<BluetoothDevice> hfConnDevList= hsService.getConnectedDevices();
11104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        // Check if the device is in disconnected state and if so return
11114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        // We ned to connect other profile only if one of the profile is still in connected state
11124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        // This is required to avoide a race condition in which profiles would
11134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        // automaticlly connect if the disconnection is initiated within 6 seconds of connection
11144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        //First profile connection being rejected is an exception
11154f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if((hfConnDevList.isEmpty() && a2dpConnDevList.isEmpty())&&
11164f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (PROFILE_CONN_CONNECTED  == firstProfileStatus)){
11174f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return;
11184f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
11194f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if((hfConnDevList.isEmpty()) &&
11204f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){
11214f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            hsService.connect(device);
11224f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
11234f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        else if((a2dpConnDevList.isEmpty()) &&
11244f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){
11254f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            a2dpService.connect(device);
11264f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
11274f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
11284f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
11299eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan     private void adjustOtherHeadsetPriorities(HeadsetService  hsService,
11309eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan                                                    BluetoothDevice connectedDevice) {
11319eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan        for (BluetoothDevice device : getBondedDevices()) {
11329eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan           if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT &&
11339eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan               !device.equals(connectedDevice)) {
11349eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan               hsService.setPriority(device, BluetoothProfile.PRIORITY_ON);
11359eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan           }
11369eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan        }
11379eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan     }
11389eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan
11399eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan     private void adjustOtherSinkPriorities(A2dpService a2dpService,
11409eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan                                                BluetoothDevice connectedDevice) {
11419eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan         for (BluetoothDevice device : getBondedDevices()) {
11429eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan             if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT &&
11439eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan                 !device.equals(connectedDevice)) {
11449eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan                 a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON);
11459eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan             }
11469eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan         }
11479eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan     }
11489eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan
11494f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta     void setProfileAutoConnectionPriority (BluetoothDevice device, int profileId){
11504f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta         if (profileId == BluetoothProfile.HEADSET) {
11514f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             HeadsetService  hsService = HeadsetService.getHeadsetService();
11524f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             if ((hsService != null) &&
11534f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                (BluetoothProfile.PRIORITY_AUTO_CONNECT != hsService.getPriority(device))){
11549eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan                 adjustOtherHeadsetPriorities(hsService, device);
11554f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                 hsService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT);
11564f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             }
11574f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta         }
11584f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta         else if (profileId ==  BluetoothProfile.A2DP) {
11594f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             A2dpService a2dpService = A2dpService.getA2dpService();
11604f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             if ((a2dpService != null) &&
11614f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                (BluetoothProfile.PRIORITY_AUTO_CONNECT != a2dpService.getPriority(device))){
11629eb4a84924718019c35fc5b32e59a6750ecf4116Ravi Nagarajan                 adjustOtherSinkPriorities(a2dpService, device);
11634f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT);
11644f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta             }
11654f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta         }
11664f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
11674f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
116874ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean cancelBondProcess(BluetoothDevice device) {
116974ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
117074ae04c73312403e89db0f8e9bd9601d403b4783fredc        byte[] addr = Utils.getBytesFromAddress(device.getAddress());
117174ae04c73312403e89db0f8e9bd9601d403b4783fredc        return cancelBondNative(addr);
117274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
117374ae04c73312403e89db0f8e9bd9601d403b4783fredc
117474ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean removeBond(BluetoothDevice device) {
117574ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
117674ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
117774ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) {
117874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
117974ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
118074ae04c73312403e89db0f8e9bd9601d403b4783fredc        Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND);
118174ae04c73312403e89db0f8e9bd9601d403b4783fredc        msg.obj = device;
118274ae04c73312403e89db0f8e9bd9601d403b4783fredc        mBondStateMachine.sendMessage(msg);
118374ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
118474ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
118574ae04c73312403e89db0f8e9bd9601d403b4783fredc
118674ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getBondState(BluetoothDevice device) {
118774ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
118874ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
118974ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null) {
119074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return BluetoothDevice.BOND_NONE;
119174ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
119274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return deviceProp.getBondState();
119374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
119474ae04c73312403e89db0f8e9bd9601d403b4783fredc
119574ae04c73312403e89db0f8e9bd9601d403b4783fredc     String getRemoteName(BluetoothDevice device) {
119674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
119774ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
119874ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null) return null;
119974ae04c73312403e89db0f8e9bd9601d403b4783fredc        return deviceProp.getName();
120074ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
120174ae04c73312403e89db0f8e9bd9601d403b4783fredc
120274ae04c73312403e89db0f8e9bd9601d403b4783fredc     String getRemoteAlias(BluetoothDevice device) {
120374ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
120474ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
120574ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null) return null;
120674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return deviceProp.getAlias();
120774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
120874ae04c73312403e89db0f8e9bd9601d403b4783fredc
120974ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setRemoteAlias(BluetoothDevice device, String name) {
121074ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
121174ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
121274ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null) return false;
121374ae04c73312403e89db0f8e9bd9601d403b4783fredc        deviceProp.setAlias(name);
121474ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
121574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
121674ae04c73312403e89db0f8e9bd9601d403b4783fredc
121774ae04c73312403e89db0f8e9bd9601d403b4783fredc     int getRemoteClass(BluetoothDevice device) {
121874ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
121974ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
122074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null) return 0;
122174ae04c73312403e89db0f8e9bd9601d403b4783fredc
122274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return deviceProp.getBluetoothClass();
122374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
122474ae04c73312403e89db0f8e9bd9601d403b4783fredc
122574ae04c73312403e89db0f8e9bd9601d403b4783fredc     ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
122674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
122774ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
122874ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null) return null;
122974ae04c73312403e89db0f8e9bd9601d403b4783fredc        return deviceProp.getUuids();
123074ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
123174ae04c73312403e89db0f8e9bd9601d403b4783fredc
123274ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean fetchRemoteUuids(BluetoothDevice device) {
123374ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
123474ae04c73312403e89db0f8e9bd9601d403b4783fredc        mRemoteDevices.fetchUuids(device);
123574ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
123674ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
123774ae04c73312403e89db0f8e9bd9601d403b4783fredc
123874ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) {
123974ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
124074ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
124174ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
124274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
124374ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
124474ae04c73312403e89db0f8e9bd9601d403b4783fredc
124574ae04c73312403e89db0f8e9bd9601d403b4783fredc        byte[] addr = Utils.getBytesFromAddress(device.getAddress());
124674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return pinReplyNative(addr, accept, len, pinCode);
124774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
124874ae04c73312403e89db0f8e9bd9601d403b4783fredc
124974ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) {
125074ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
125174ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
125274ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
125374ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
125474ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
125574ae04c73312403e89db0f8e9bd9601d403b4783fredc
125674ae04c73312403e89db0f8e9bd9601d403b4783fredc        byte[] addr = Utils.getBytesFromAddress(device.getAddress());
125774ae04c73312403e89db0f8e9bd9601d403b4783fredc        return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept,
125874ae04c73312403e89db0f8e9bd9601d403b4783fredc                Utils.byteArrayToInt(passkey));
125974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
126074ae04c73312403e89db0f8e9bd9601d403b4783fredc
126174ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean setPairingConfirmation(BluetoothDevice device, boolean accept) {
126274ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
126374ae04c73312403e89db0f8e9bd9601d403b4783fredc        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
126474ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
126574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
126674ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
126774ae04c73312403e89db0f8e9bd9601d403b4783fredc
126874ae04c73312403e89db0f8e9bd9601d403b4783fredc        byte[] addr = Utils.getBytesFromAddress(device.getAddress());
126974ae04c73312403e89db0f8e9bd9601d403b4783fredc        return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
127074ae04c73312403e89db0f8e9bd9601d403b4783fredc                accept, 0);
127174ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
127274ae04c73312403e89db0f8e9bd9601d403b4783fredc
127374ae04c73312403e89db0f8e9bd9601d403b4783fredc     void sendConnectionStateChange(BluetoothDevice
127474ae04c73312403e89db0f8e9bd9601d403b4783fredc            device, int profile, int state, int prevState) {
127574ae04c73312403e89db0f8e9bd9601d403b4783fredc        // TODO(BT) permission check?
127674ae04c73312403e89db0f8e9bd9601d403b4783fredc        // Since this is a binder call check if Bluetooth is on still
127774ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (getState() == BluetoothAdapter.STATE_OFF) return;
127874ae04c73312403e89db0f8e9bd9601d403b4783fredc
127974ae04c73312403e89db0f8e9bd9601d403b4783fredc        mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState);
128074ae04c73312403e89db0f8e9bd9601d403b4783fredc
128174ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
128274ae04c73312403e89db0f8e9bd9601d403b4783fredc
128374ae04c73312403e89db0f8e9bd9601d403b4783fredc     ParcelFileDescriptor connectSocket(BluetoothDevice device, int type,
128474ae04c73312403e89db0f8e9bd9601d403b4783fredc                                              ParcelUuid uuid, int port, int flag) {
128574ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
128674ae04c73312403e89db0f8e9bd9601d403b4783fredc        int fd = connectSocketNative(Utils.getBytesFromAddress(device.getAddress()),
128774ae04c73312403e89db0f8e9bd9601d403b4783fredc                   type, Utils.uuidToByteArray(uuid), port, flag);
128874ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (fd < 0) {
128974ae04c73312403e89db0f8e9bd9601d403b4783fredc            errorLog("Failed to connect socket");
129074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return null;
129174ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
129274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return ParcelFileDescriptor.adoptFd(fd);
129374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
129474ae04c73312403e89db0f8e9bd9601d403b4783fredc
129574ae04c73312403e89db0f8e9bd9601d403b4783fredc     ParcelFileDescriptor createSocketChannel(int type, String serviceName,
129674ae04c73312403e89db0f8e9bd9601d403b4783fredc                                                    ParcelUuid uuid, int port, int flag) {
129774ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
129874ae04c73312403e89db0f8e9bd9601d403b4783fredc        int fd =  createSocketChannelNative(type, serviceName,
129974ae04c73312403e89db0f8e9bd9601d403b4783fredc                                 Utils.uuidToByteArray(uuid), port, flag);
130074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (fd < 0) {
130174ae04c73312403e89db0f8e9bd9601d403b4783fredc            errorLog("Failed to create socket channel");
130274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return null;
130374ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
130474ae04c73312403e89db0f8e9bd9601d403b4783fredc        return ParcelFileDescriptor.adoptFd(fd);
130574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
130674ae04c73312403e89db0f8e9bd9601d403b4783fredc
13074852c5686229f1014e9851f4e9a3a19547581b45fredc     void registerCallback(IBluetoothCallback cb) {
13084852c5686229f1014e9851f4e9a3a19547581b45fredc         mCallbacks.register(cb);
13094852c5686229f1014e9851f4e9a3a19547581b45fredc      }
13104852c5686229f1014e9851f4e9a3a19547581b45fredc
13114852c5686229f1014e9851f4e9a3a19547581b45fredc      void unregisterCallback(IBluetoothCallback cb) {
13124852c5686229f1014e9851f4e9a3a19547581b45fredc         mCallbacks.unregister(cb);
13134852c5686229f1014e9851f4e9a3a19547581b45fredc      }
13144852c5686229f1014e9851f4e9a3a19547581b45fredc
131574ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static int convertScanModeToHal(int mode) {
1316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        switch (mode) {
1317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            case BluetoothAdapter.SCAN_MODE_NONE:
1318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return AbstractionLayer.BT_SCAN_MODE_NONE;
1319ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
1320ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE;
1321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
1322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
1323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
132474ae04c73312403e89db0f8e9bd9601d403b4783fredc       // errorLog("Incorrect scan mode in convertScanModeToHal");
1325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return -1;
1326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
1327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
132874ae04c73312403e89db0f8e9bd9601d403b4783fredc    static int convertScanModeFromHal(int mode) {
1329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        switch (mode) {
1330ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            case AbstractionLayer.BT_SCAN_MODE_NONE:
1331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return BluetoothAdapter.SCAN_MODE_NONE;
1332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE:
1333ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
1334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
1335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
1336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
133774ae04c73312403e89db0f8e9bd9601d403b4783fredc        //errorLog("Incorrect scan mode in convertScanModeFromHal");
1338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return -1;
1339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
1340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
134131ba132491053bc86d419a7d51fc04af3299c076fredc    private void debugLog(String msg) {
134231ba132491053bc86d419a7d51fc04af3299c076fredc        Log.d(TAG +"(" +hashCode()+")", msg);
1343ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
1344ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
134531ba132491053bc86d419a7d51fc04af3299c076fredc    private void errorLog(String msg) {
134631ba132491053bc86d419a7d51fc04af3299c076fredc        Log.e(TAG +"(" +hashCode()+")", msg);
1347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
1348ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private native static void classInitNative();
1350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private native boolean initNative();
1351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private native void cleanupNative();
1352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean enableNative();
1353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean disableNative();
1354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean setAdapterPropertyNative(int type, byte[] val);
1355ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean getAdapterPropertiesNative();
1356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean getAdapterPropertyNative(int type);
1357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean setAdapterPropertyNative(int type);
1358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean
1359ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        setDevicePropertyNative(byte[] address, int type, byte[] val);
1360ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean getDevicePropertyNative(byte[] address, int type);
1361ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1362ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean createBondNative(byte[] address);
1363ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean removeBondNative(byte[] address);
1364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    /*package*/ native boolean cancelBondNative(byte[] address);
1365ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1366ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private native boolean startDiscoveryNative();
1367ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private native boolean cancelDiscoveryNative();
1368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1369ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin);
1370581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    private native boolean sspReplyNative(byte[] address, int type, boolean
1371581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh            accept, int passkey);
1372c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1373c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    /*package*/ native boolean getRemoteServicesNative(byte[] address);
1374c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1375cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    // TODO(BT) move this to ../btsock dir
1376cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    private native int connectSocketNative(byte[] address, int type,
1377cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                           byte[] uuid, int port, int flag);
1378cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    private native int createSocketChannelNative(int type, String serviceName,
1379cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                                 byte[] uuid, int port, int flag);
138074ae04c73312403e89db0f8e9bd9601d403b4783fredc
138174ae04c73312403e89db0f8e9bd9601d403b4783fredc    protected void finalize() {
138274ae04c73312403e89db0f8e9bd9601d403b4783fredc        cleanup();
138374ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (TRACE_REF) {
138474ae04c73312403e89db0f8e9bd9601d403b4783fredc            synchronized (AdapterService.class) {
138574ae04c73312403e89db0f8e9bd9601d403b4783fredc                sRefCount--;
138674ae04c73312403e89db0f8e9bd9601d403b4783fredc                Log.d(TAG, "REFCOUNT: FINALIZED. INSTANCE_COUNT= " + sRefCount);
138774ae04c73312403e89db0f8e9bd9601d403b4783fredc            }
138874ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
138974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
1390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1391