19f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li/* 2f04335f899f2cce69f843692a3cb9cec229683c2tturney * Copyright (C) 2017 The Android Open Source Project 39f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 4f04335f899f2cce69f843692a3cb9cec229683c2tturney * Licensed under the Apache License, Version 2.0 (the "License"); 5f04335f899f2cce69f843692a3cb9cec229683c2tturney * you may not use this file except in compliance with the License. 6f04335f899f2cce69f843692a3cb9cec229683c2tturney * You may obtain a copy of the License at 79f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 8f04335f899f2cce69f843692a3cb9cec229683c2tturney * http://www.apache.org/licenses/LICENSE-2.0 99f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Unless required by applicable law or agreed to in writing, software 11f04335f899f2cce69f843692a3cb9cec229683c2tturney * distributed under the License is distributed on an "AS IS" BASIS, 12f04335f899f2cce69f843692a3cb9cec229683c2tturney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f04335f899f2cce69f843692a3cb9cec229683c2tturney * See the License for the specific language governing permissions and 14f04335f899f2cce69f843692a3cb9cec229683c2tturney * limitations under the License. 159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */ 169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Lipackage com.googlecode.android_scripting.facade.bluetooth; 189f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 199f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.app.Service; 209f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.bluetooth.BluetoothA2dp; 217b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwalimport android.bluetooth.BluetoothA2dpSink; 229f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.bluetooth.BluetoothAdapter; 239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.bluetooth.BluetoothDevice; 249f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.bluetooth.BluetoothHeadset; 257b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwalimport android.bluetooth.BluetoothHeadsetClient; 2609d1d71d52031355d43ac30885025ef3bd36043aHansong Zhangimport android.bluetooth.BluetoothHidDevice; 2716f89b8cb5f2322ea354e18abbe0289db648a882Hansong Zhangimport android.bluetooth.BluetoothHidHost; 2809d1d71d52031355d43ac30885025ef3bd36043aHansong Zhangimport android.bluetooth.BluetoothManager; 29fc6e4af002e75301e13ddf524c0317e3a52be858tturneyimport android.bluetooth.BluetoothMap; 3075dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzoimport android.bluetooth.BluetoothMapClient; 3109d1d71d52031355d43ac30885025ef3bd36043aHansong Zhangimport android.bluetooth.BluetoothPan; 3248e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwalimport android.bluetooth.BluetoothPbapClient; 3348e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwalimport android.bluetooth.BluetoothProfile; 349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.bluetooth.BluetoothUuid; 359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.BroadcastReceiver; 369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.Context; 379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.Intent; 389f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.IntentFilter; 399f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.os.Bundle; 409f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.os.ParcelUuid; 419f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 429f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.Log; 439f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.facade.EventFacade; 449f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.facade.FacadeManager; 459f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.jsonrpc.RpcReceiver; 469f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.rpc.Rpc; 47f0a094f3709187319222e64d8434f168ad8ffac9Jack Heimport com.googlecode.android_scripting.rpc.RpcDefault; 48f0a094f3709187319222e64d8434f168ad8ffac9Jack Heimport com.googlecode.android_scripting.rpc.RpcOptional; 4909d1d71d52031355d43ac30885025ef3bd36043aHansong Zhangimport com.googlecode.android_scripting.rpc.RpcParameter; 509f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 51d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadiimport org.json.JSONArray; 52d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadiimport org.json.JSONException; 53d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 54e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singhimport java.util.ArrayList; 55e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singhimport java.util.Arrays; 56e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singhimport java.util.Collections; 57e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singhimport java.util.HashMap; 58e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singhimport java.util.List; 59e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singhimport java.util.Map; 60e76a08babeec457d3ec28d24d91c833fbd223ba5Ashutosh Singh 619f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Lipublic class BluetoothConnectionFacade extends RpcReceiver { 629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final Service mService; 6455b68b3c0456f5e96edf37845785efb4d9a9848ctturney private final Context mContext; 659f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final BluetoothAdapter mBluetoothAdapter; 6655b68b3c0456f5e96edf37845785efb4d9a9848ctturney private final BluetoothManager mBluetoothManager; 679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final BluetoothPairingHelper mPairingHelper; 689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final Map<String, BroadcastReceiver> listeningDevices; 699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final EventFacade mEventFacade; 709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final IntentFilter mDiscoverConnectFilter; 729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final IntentFilter mPairingFilter; 739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final IntentFilter mBondFilter; 749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final IntentFilter mA2dpStateChangeFilter; 757b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal private final IntentFilter mA2dpSinkStateChangeFilter; 769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final IntentFilter mHidStateChangeFilter; 7709d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang private final IntentFilter mHidDeviceStateChangeFilter; 789f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final IntentFilter mHspStateChangeFilter; 797b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal private final IntentFilter mHfpClientStateChangeFilter; 8048e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal private final IntentFilter mPbapClientStateChangeFilter; 81f855841b2fe6ed4a5835bc7c7cb7e79bbccfec71Sanket Agarwal private final IntentFilter mPanStateChangeFilter; 8275dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo private final IntentFilter mMapClientStateChangeFilter; 83fc6e4af002e75301e13ddf524c0317e3a52be858tturney private final IntentFilter mMapStateChangeFilter; 849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final Bundle mGoodNews; 869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final Bundle mBadNews; 879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private BluetoothA2dpFacade mA2dpProfile; 897b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal private BluetoothA2dpSinkFacade mA2dpSinkProfile; 909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private BluetoothHidFacade mHidProfile; 9109d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang private BluetoothHidDeviceFacade mHidDeviceProfile; 929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private BluetoothHspFacade mHspProfile; 937b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal private BluetoothHfpClientFacade mHfpClientProfile; 9448e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal private BluetoothPbapClientFacade mPbapClientProfile; 95f855841b2fe6ed4a5835bc7c7cb7e79bbccfec71Sanket Agarwal private BluetoothPanFacade mPanProfile; 9675dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo private BluetoothMapClientFacade mMapClientProfile; 97fc6e4af002e75301e13ddf524c0317e3a52be858tturney private BluetoothMapFacade mMapProfile; 98fc6e4af002e75301e13ddf524c0317e3a52be858tturney private ArrayList<String> mDeviceMonitorList; 999f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public BluetoothConnectionFacade(FacadeManager manager) { 1019f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li super(manager); 1029f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService = manager.getService(); 10355b68b3c0456f5e96edf37845785efb4d9a9848ctturney mContext = mService.getApplicationContext(); 1049f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 10555b68b3c0456f5e96edf37845785efb4d9a9848ctturney mBluetoothManager = (BluetoothManager) mContext.getSystemService( 10655b68b3c0456f5e96edf37845785efb4d9a9848ctturney Service.BLUETOOTH_SERVICE); 107fc6e4af002e75301e13ddf524c0317e3a52be858tturney mDeviceMonitorList = new ArrayList<String>(); 1089f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li // Use a synchronized map to avoid racing problems 1099f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li listeningDevices = Collections.synchronizedMap(new HashMap<String, BroadcastReceiver>()); 1109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1119f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mEventFacade = manager.getReceiver(EventFacade.class); 11281c9640b1c3fa42892c2de6a18cc65aec8de2c4etturney mPairingHelper = new BluetoothPairingHelper(mEventFacade); 1139f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mA2dpProfile = manager.getReceiver(BluetoothA2dpFacade.class); 1147b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mA2dpSinkProfile = manager.getReceiver(BluetoothA2dpSinkFacade.class); 1159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mHidProfile = manager.getReceiver(BluetoothHidFacade.class); 11609d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang mHidDeviceProfile = manager.getReceiver(BluetoothHidDeviceFacade.class); 1179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mHspProfile = manager.getReceiver(BluetoothHspFacade.class); 1187b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mHfpClientProfile = manager.getReceiver(BluetoothHfpClientFacade.class); 11948e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal mPbapClientProfile = manager.getReceiver(BluetoothPbapClientFacade.class); 120f855841b2fe6ed4a5835bc7c7cb7e79bbccfec71Sanket Agarwal mPanProfile = manager.getReceiver(BluetoothPanFacade.class); 12175dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo mMapClientProfile = manager.getReceiver(BluetoothMapClientFacade.class); 122fc6e4af002e75301e13ddf524c0317e3a52be858tturney mMapProfile = manager.getReceiver(BluetoothMapFacade.class); 1239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1249f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDiscoverConnectFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 1259f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDiscoverConnectFilter.addAction(BluetoothDevice.ACTION_UUID); 1269f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDiscoverConnectFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 1279f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mPairingFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST); 1299f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mPairingFilter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); 13042ef337b1976d1cbd7b71d531d8cc4365df29471tturney mPairingFilter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); 1319f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mPairingFilter.setPriority(999); 1329f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1339f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBondFilter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 1349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBondFilter.addAction(BluetoothDevice.ACTION_FOUND); 1359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBondFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 1369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mA2dpStateChangeFilter = new IntentFilter(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); 1387b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mA2dpSinkStateChangeFilter = 1397b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal new IntentFilter(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED); 1407b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mHidStateChangeFilter = 14116f89b8cb5f2322ea354e18abbe0289db648a882Hansong Zhang new IntentFilter(BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED); 14209d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang mHidDeviceStateChangeFilter = 14309d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang new IntentFilter(BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED); 1449f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mHspStateChangeFilter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); 1457b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mHfpClientStateChangeFilter = 1467b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal new IntentFilter(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); 14748e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal mPbapClientStateChangeFilter = 14848e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal new IntentFilter(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED); 149f855841b2fe6ed4a5835bc7c7cb7e79bbccfec71Sanket Agarwal mPanStateChangeFilter = 150f855841b2fe6ed4a5835bc7c7cb7e79bbccfec71Sanket Agarwal new IntentFilter(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); 15175dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo mMapClientStateChangeFilter = 15275dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo new IntentFilter(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED); 153fc6e4af002e75301e13ddf524c0317e3a52be858tturney mMapStateChangeFilter = 154fc6e4af002e75301e13ddf524c0317e3a52be858tturney new IntentFilter(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED); 1559f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1569f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mGoodNews = new Bundle(); 1579f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mGoodNews.putBoolean("Status", true); 1589f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBadNews = new Bundle(); 1599f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBadNews.putBoolean("Status", false); 1609f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1619f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private void unregisterCachedListener(String listenerId) { 1639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BroadcastReceiver listener = listeningDevices.remove(listenerId); 1649f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (listener != null) { 1659f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.unregisterReceiver(listener); 1669f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li /** 1709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Connect to a specific device upon its discovery 1719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */ 1729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public class DiscoverConnectReceiver extends BroadcastReceiver { 1739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final String mDeviceID; 1749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private BluetoothDevice mDevice; 1759f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li /** 1779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Constructor 1789f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 1799f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * @param deviceID Either the device alias name or mac address. 180d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param bond If true, bond the device only. 1819f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */ 1829f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public DiscoverConnectReceiver(String deviceID) { 1839f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li super(); 1849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDeviceID = deviceID; 1859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onReceive(Context context, Intent intent) { 1899f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li String action = intent.getAction(); 1909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li // The specified device is found. 1919f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (action.equals(BluetoothDevice.ACTION_FOUND)) { 1929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 1939f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothFacade.deviceMatch(device, mDeviceID)) { 1949f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Found device " + device.getAliasName() + " for connection."); 1959f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBluetoothAdapter.cancelDiscovery(); 1969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDevice = device; 1979f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 198d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi // After discovery stops. 1999f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { 2009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (mDevice == null) { 2019f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Device " + mDeviceID + " not discovered."); 2029f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mEventFacade.postEvent("Bond" + mDeviceID, mBadNews); 2039f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return; 2049f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2059f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li boolean status = mDevice.fetchUuidsWithSdp(); 2069f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Initiated ACL connection: " + status); 2079f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } else if (action.equals(BluetoothDevice.ACTION_UUID)) { 2089f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 2099f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothFacade.deviceMatch(device, mDeviceID)) { 2109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Initiating connections."); 2119f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li connectProfile(device, mDeviceID); 2129f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.unregisterReceiver(listeningDevices.remove("Connect" + mDeviceID)); 2139f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2149f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2189f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li /** 2199f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Connect to a specific device upon its discovery 2209f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */ 2219f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public class DiscoverBondReceiver extends BroadcastReceiver { 2229f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final String mDeviceID; 2239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private BluetoothDevice mDevice = null; 2249f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private boolean started = false; 2259f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2269f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li /** 2279f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Constructor 2289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 2299f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * @param deviceID Either the device alias name or Mac address. 2309f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */ 2319f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public DiscoverBondReceiver(String deviceID) { 2329f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li super(); 2339f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDeviceID = deviceID; 2349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 2379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onReceive(Context context, Intent intent) { 2389f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li String action = intent.getAction(); 2399f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li // The specified device is found. 2409f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (action.equals(BluetoothDevice.ACTION_FOUND)) { 2419f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 2429f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothFacade.deviceMatch(device, mDeviceID)) { 2439f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Found device " + device.getAliasName() + " for connection."); 2449f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBluetoothAdapter.cancelDiscovery(); 2459f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDevice = device; 2469f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 247d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi // After discovery stops. 2489f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { 2499f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (mDevice == null) { 2509f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Device " + mDeviceID + " was not discovered."); 2519f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mEventFacade.postEvent("Bond", mBadNews); 2529f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return; 2539f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2549f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li // Attempt to initiate bonding. 2559f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (!started) { 2569f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Bond with " + mDevice.getAliasName()); 2579f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (mDevice.createBond()) { 2589f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li started = true; 2599f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Bonding started."); 2609f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } else { 2619f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.e("Failed to bond with " + mDevice.getAliasName()); 2629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mEventFacade.postEvent("Bond", mBadNews); 2639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.unregisterReceiver(listeningDevices.remove("Bond" + mDeviceID)); 2649f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2659f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2669f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { 2679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Bond state changing."); 2689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 2699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothFacade.deviceMatch(device, mDeviceID)) { 2709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); 2719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("New state is " + state); 2729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (state == BluetoothDevice.BOND_BONDED) { 2739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Bonding with " + mDeviceID + " successful."); 2749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mEventFacade.postEvent("Bond" + mDeviceID, mGoodNews); 2759f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.unregisterReceiver(listeningDevices.remove("Bond" + mDeviceID)); 2769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2789f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2799f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2809f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2819f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2829f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public class ConnectStateChangeReceiver extends BroadcastReceiver { 2839f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final String mDeviceID; 2849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public ConnectStateChangeReceiver(String deviceID) { 2869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mDeviceID = deviceID; 2879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2899f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 2909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onReceive(Context context, Intent intent) { 291fc6e4af002e75301e13ddf524c0317e3a52be858tturney // no matter what the action, just push it... 2929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li String action = intent.getAction(); 2935ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal Log.d("Action received: " + action); 2945ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal 2959f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 2969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li // Check if received the specified device 2979f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (!BluetoothFacade.deviceMatch(device, mDeviceID)) { 2985ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal Log.e("Action devices does match act: " + device + " exp " + mDeviceID); 2999f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return; 3009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 301d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi // Find the state. 302d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); 303d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi if (state == -1) { 304d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi Log.e("Action does not have a state."); 305d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi return; 306d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 307d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 3085ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal int profile = -1; 3095ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal switch (action) { 3105ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: 3115ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal profile = BluetoothProfile.A2DP; 3125ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 31316f89b8cb5f2322ea354e18abbe0289db648a882Hansong Zhang case BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED: 31416f89b8cb5f2322ea354e18abbe0289db648a882Hansong Zhang profile = BluetoothProfile.HID_HOST; 3155ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 3165ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: 3175ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal profile = BluetoothProfile.HEADSET; 3185ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 3195ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED: 3205ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal profile = BluetoothProfile.PAN; 3215ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 3225ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED: 3235ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal profile = BluetoothProfile.HEADSET_CLIENT; 3245ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 3255ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED: 3265ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal profile = BluetoothProfile.A2DP_SINK; 3275ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 3285ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED: 3295ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal profile = BluetoothProfile.PBAP_CLIENT; 3305ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal break; 33175dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED: 33275dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo profile = BluetoothProfile.MAP_CLIENT; 33375dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo break; 3345ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal } 3355ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal 3365ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal if (profile == -1) { 3375ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal Log.e("Action does not match any given profiles " + action); 3385ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal } 3395ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal 3405ecdad6eafb5085b4527e56a4916d624cbeb84f0Sanket Agarwal // Post an event to Facade. 341fc6e4af002e75301e13ddf524c0317e3a52be858tturney Bundle news = new Bundle(); 342fc6e4af002e75301e13ddf524c0317e3a52be858tturney news.putInt("profile", profile); 343fc6e4af002e75301e13ddf524c0317e3a52be858tturney news.putInt("state", state); 344fc6e4af002e75301e13ddf524c0317e3a52be858tturney news.putString("addr", device.getAddress()); 345fc6e4af002e75301e13ddf524c0317e3a52be858tturney news.putString("action", action); 346fc6e4af002e75301e13ddf524c0317e3a52be858tturney mEventFacade.postEvent("BluetoothProfileConnectionStateChanged", news); 3479f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 3489f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 3499f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 350d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi /** 351d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * Converts a given JSONArray to an ArrayList of Integers 352d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * 353d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param jsonArray the JSONArray to be converted 354d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @return <code>List<Integer></></code> the converted list of Integers 355d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi */ 356d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi private List<Integer> jsonArrayToIntegerList(JSONArray jsonArray) throws JSONException { 357d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi if (jsonArray == null) { 358d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi return null; 359d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 360d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi List<Integer> intArray = new ArrayList<Integer>(); 361d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi for (int i = 0; i < jsonArray.length(); i++) { 362d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi intArray.add(jsonArray.getInt(i)); 363d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 364d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi return intArray; 365d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 366d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 367d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 368fc6e4af002e75301e13ddf524c0317e3a52be858tturney @Rpc(description = "Start monitoring state changes for input device.") 369fc6e4af002e75301e13ddf524c0317e3a52be858tturney public void bluetoothStartConnectionStateChangeMonitor( 370fc6e4af002e75301e13ddf524c0317e3a52be858tturney @RpcParameter(name = "deviceID", 371fc6e4af002e75301e13ddf524c0317e3a52be858tturney description = "Name or MAC address of a bluetooth device.") 372fc6e4af002e75301e13ddf524c0317e3a52be858tturney String deviceID) { 373fc6e4af002e75301e13ddf524c0317e3a52be858tturney if (!mDeviceMonitorList.contains(deviceID)) { 374fc6e4af002e75301e13ddf524c0317e3a52be858tturney ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID); 375fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mA2dpStateChangeFilter); 376fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mA2dpSinkStateChangeFilter); 377fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mHidStateChangeFilter); 378fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mHspStateChangeFilter); 379fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mHfpClientStateChangeFilter); 380fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mPbapClientStateChangeFilter); 381fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mPanStateChangeFilter); 382fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mMapClientStateChangeFilter); 383fc6e4af002e75301e13ddf524c0317e3a52be858tturney mService.registerReceiver(receiver, mMapStateChangeFilter); 384fc6e4af002e75301e13ddf524c0317e3a52be858tturney listeningDevices.put("StateChangeListener:" + deviceID, receiver); 385fc6e4af002e75301e13ddf524c0317e3a52be858tturney } 386d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 387d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 388d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi /** 389d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * Connect on all the profiles to the given Bluetooth device 390d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * 391d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param device The <code>BluetoothDevice</code> to connect to 392d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param deviceID Name (String) of the device to connect to 393d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi */ 3949f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private void connectProfile(BluetoothDevice device, String deviceID) { 3959f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.registerReceiver(mPairingHelper, mPairingFilter); 3969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ParcelUuid[] deviceUuids = device.getUuids(); 39775dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo Log.d("Device uuid is " + Arrays.toString(deviceUuids)); 3989f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (deviceUuids == null) { 3997b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mEventFacade.postEvent("BluetoothProfileConnectionEvent", mBadNews); 4009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 4017b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal Log.d("Connecting to " + device.getAliasName()); 4029f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothUuid.containsAnyUuid(BluetoothA2dpFacade.SINK_UUIDS, deviceUuids)) { 403fc6e4af002e75301e13ddf524c0317e3a52be858tturney mA2dpProfile.a2dpConnect(device); 4049f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 4057b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal if (BluetoothUuid.containsAnyUuid(BluetoothA2dpSinkFacade.SOURCE_UUIDS, deviceUuids)) { 406fc6e4af002e75301e13ddf524c0317e3a52be858tturney mA2dpSinkProfile.a2dpSinkConnect(device); 4077b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal } 4089f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothUuid.containsAnyUuid(BluetoothHidFacade.UUIDS, deviceUuids)) { 409fc6e4af002e75301e13ddf524c0317e3a52be858tturney mHidProfile.hidConnect(device); 4109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 4119f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothUuid.containsAnyUuid(BluetoothHspFacade.UUIDS, deviceUuids)) { 412fc6e4af002e75301e13ddf524c0317e3a52be858tturney mHspProfile.hspConnect(device); 4139f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 4147b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal if (BluetoothUuid.containsAnyUuid(BluetoothHfpClientFacade.UUIDS, deviceUuids)) { 415fc6e4af002e75301e13ddf524c0317e3a52be858tturney mHfpClientProfile.hfpClientConnect(device); 416fc6e4af002e75301e13ddf524c0317e3a52be858tturney } 417fc6e4af002e75301e13ddf524c0317e3a52be858tturney if (BluetoothUuid.containsAnyUuid(BluetoothMapClientFacade.MAP_UUIDS, deviceUuids)) { 418fc6e4af002e75301e13ddf524c0317e3a52be858tturney mMapClientProfile.mapClientConnect(device); 4197b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal } 42002e949859dc20c9ab6d0a79688eff87beae68d61tturney if (BluetoothUuid.containsAnyUuid(BluetoothPanFacade.UUIDS, deviceUuids)) { 421fc6e4af002e75301e13ddf524c0317e3a52be858tturney mPanProfile.panConnect(device); 422bb50bfa1e057c027dda0027a08372c91b529177eSanket Agarwal } 42348e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal if (BluetoothUuid.containsAnyUuid(BluetoothPbapClientFacade.UUIDS, deviceUuids)) { 424fc6e4af002e75301e13ddf524c0317e3a52be858tturney mPbapClientProfile.pbapClientConnect(device); 42575dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo } 4269f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.unregisterReceiver(mPairingHelper); 4279f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 4289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 429d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi /** 430d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * Disconnect on all available profiles from the given device 431d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * 432d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param device The <code>BluetoothDevice</code> to disconnect from 433d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param deviceID Name (String) of the device to disconnect from 434d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi */ 4357b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal private void disconnectProfiles(BluetoothDevice device, String deviceID) { 4367b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal Log.d("Disconnecting device " + device); 4377b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal // Blindly disconnect all profiles. We may not have some of them connected so that will be a 4387b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal // null op. 4397b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mA2dpProfile.a2dpDisconnect(device); 4407b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mA2dpSinkProfile.a2dpSinkDisconnect(device); 4417b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mHidProfile.hidDisconnect(device); 44209d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang mHidDeviceProfile.hidDeviceDisconnect(device); 4437b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mHspProfile.hspDisconnect(device); 4447b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal mHfpClientProfile.hfpClientDisconnect(device); 44548e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal mPbapClientProfile.pbapClientDisconnect(device); 446f855841b2fe6ed4a5835bc7c7cb7e79bbccfec71Sanket Agarwal mPanProfile.panDisconnect(device); 44775dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo mMapClientProfile.mapClientDisconnect(device); 4487b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal } 4497b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal 450d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi /** 451d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * Disconnect from specific profiles provided in the given List of profiles. 452d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * 453d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param device The {@link BluetoothDevice} to disconnect from 454d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param deviceID Name/BDADDR (String) of the device to disconnect from 455d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi * @param profileIds The list of profiles we want to disconnect on. 456d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi */ 457d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi private void disconnectProfiles(BluetoothDevice device, String deviceID, 458d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi List<Integer> profileIds) { 459d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi boolean result; 460d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi for (int profileId : profileIds) { 461d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi switch (profileId) { 462d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi case BluetoothProfile.A2DP_SINK: 463fc6e4af002e75301e13ddf524c0317e3a52be858tturney mA2dpSinkProfile.a2dpSinkDisconnect(device); 464d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi break; 465d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi case BluetoothProfile.A2DP: 466fc6e4af002e75301e13ddf524c0317e3a52be858tturney mA2dpProfile.a2dpDisconnect(device); 467d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi break; 46816f89b8cb5f2322ea354e18abbe0289db648a882Hansong Zhang case BluetoothProfile.HID_HOST: 469fc6e4af002e75301e13ddf524c0317e3a52be858tturney mHidProfile.hidDisconnect(device); 470d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi break; 47109d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang case BluetoothProfile.HID_DEVICE: 47209d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang mHidDeviceProfile.hidDeviceDisconnect(device); 47309d1d71d52031355d43ac30885025ef3bd36043aHansong Zhang break; 474d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi case BluetoothProfile.HEADSET: 475fc6e4af002e75301e13ddf524c0317e3a52be858tturney mHspProfile.hspDisconnect(device); 476d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi break; 477d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi case BluetoothProfile.HEADSET_CLIENT: 478fc6e4af002e75301e13ddf524c0317e3a52be858tturney mHfpClientProfile.hfpClientDisconnect(device); 479fc6e4af002e75301e13ddf524c0317e3a52be858tturney break; 480fc6e4af002e75301e13ddf524c0317e3a52be858tturney case BluetoothProfile.PAN: 481fc6e4af002e75301e13ddf524c0317e3a52be858tturney mPanProfile.panDisconnect(device); 482d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi break; 483d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi case BluetoothProfile.PBAP_CLIENT: 484fc6e4af002e75301e13ddf524c0317e3a52be858tturney mPbapClientProfile.pbapClientDisconnect(device); 485d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi break; 48675dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo case BluetoothProfile.MAP_CLIENT: 487fc6e4af002e75301e13ddf524c0317e3a52be858tturney mMapClientProfile.mapDisconnect(device); 48875dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo break; 489d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi default: 490d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi Log.d("Unknown Profile Id to disconnect from. Quitting"); 491d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi return; // returns on the first unknown profile it encounters. 492d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 493d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 494d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 495d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 4969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Start intercepting all bluetooth connection pop-ups.") 497f0a094f3709187319222e64d8434f168ad8ffac9Jack He public void bluetoothStartPairingHelper( 498f0a094f3709187319222e64d8434f168ad8ffac9Jack He @RpcParameter(name = "autoConfirm", 499f0a094f3709187319222e64d8434f168ad8ffac9Jack He description = "Whether connection should be auto confirmed") 500f0a094f3709187319222e64d8434f168ad8ffac9Jack He @RpcDefault("true") @RpcOptional 501f0a094f3709187319222e64d8434f168ad8ffac9Jack He Boolean autoConfirm) { 502f0a094f3709187319222e64d8434f168ad8ffac9Jack He Log.d("Staring pairing helper"); 503f0a094f3709187319222e64d8434f168ad8ffac9Jack He mPairingHelper.setAutoConfirm(autoConfirm); 5049f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.registerReceiver(mPairingHelper, mPairingFilter); 5059f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5069f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 5079f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Return a list of devices connected through bluetooth") 5089f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public List<BluetoothDevice> bluetoothGetConnectedDevices() { 5099f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ArrayList<BluetoothDevice> results = new ArrayList<BluetoothDevice>(); 5109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) { 5119f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (bd.isConnected()) { 5129f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li results.add(bd); 5139f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5149f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return results; 5169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 51855b68b3c0456f5e96edf37845785efb4d9a9848ctturney @Rpc(description = "Return a list of devices connected through bluetooth LE") 51955b68b3c0456f5e96edf37845785efb4d9a9848ctturney public List<BluetoothDevice> bluetoothGetConnectedLeDevices(Integer profile) { 52055b68b3c0456f5e96edf37845785efb4d9a9848ctturney return mBluetoothManager.getConnectedDevices(profile); 52155b68b3c0456f5e96edf37845785efb4d9a9848ctturney } 52255b68b3c0456f5e96edf37845785efb4d9a9848ctturney 523b6ccc67c1081ff6bb4f3a5fc9b32af79b058e058tturney @Rpc(description = "Bluetooth init Bond by Mac Address") 524b6ccc67c1081ff6bb4f3a5fc9b32af79b058e058tturney public boolean bluetoothBond(@RpcParameter(name = "macAddress") String macAddress) { 525b6ccc67c1081ff6bb4f3a5fc9b32af79b058e058tturney return mBluetoothAdapter.getRemoteDevice(macAddress).createBond(); 526b6ccc67c1081ff6bb4f3a5fc9b32af79b058e058tturney } 527b6ccc67c1081ff6bb4f3a5fc9b32af79b058e058tturney 5289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Return true if a bluetooth device is connected.") 5299f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public Boolean bluetoothIsDeviceConnected(String deviceID) { 5309f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) { 5319f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothFacade.deviceMatch(bd, deviceID)) { 5329f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return bd.isConnected(); 5339f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return false; 5369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 53848e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal @Rpc(description = "Return list of connected bluetooth devices over a profile", 539d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi returns = "List of devices connected over the profile") 54048e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal public List<BluetoothDevice> bluetoothGetConnectedDevicesOnProfile( 54148e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal @RpcParameter(name = "profileId", 542d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "profileId same as BluetoothProfile") 543d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi Integer profileId) { 54448e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal BluetoothProfile profile = null; 54548e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal switch (profileId) { 54648e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal case BluetoothProfile.A2DP_SINK: 54748e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal return mA2dpSinkProfile.bluetoothA2dpSinkGetConnectedDevices(); 54848e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal case BluetoothProfile.HEADSET_CLIENT: 54948e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal return mHfpClientProfile.bluetoothHfpClientGetConnectedDevices(); 55048e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal case BluetoothProfile.PBAP_CLIENT: 55148e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal return mPbapClientProfile.bluetoothPbapClientGetConnectedDevices(); 55275dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo case BluetoothProfile.MAP_CLIENT: 55375dc79a06c15dae01b07f09cfda374c828b45b4bJoseph Pirozzo return mMapClientProfile.bluetoothMapClientGetConnectedDevices(); 55448e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal default: 55548e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal Log.w("Profile id " + profileId + " is not yet supported."); 55648e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal return new ArrayList<BluetoothDevice>(); 55748e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal } 55848e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal } 55948e46479b58eff2b6cf67b459f68f918375b5567Sanket Agarwal 5609f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Connect to a specified device once it's discovered.", 561d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi returns = "Whether discovery started successfully.") 5629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public Boolean bluetoothDiscoverAndConnect( 5639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @RpcParameter(name = "deviceID", 564d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 565d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID) { 5669f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBluetoothAdapter.cancelDiscovery(); 5679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (listeningDevices.containsKey(deviceID)) { 5689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("This device is already in the process of discovery and connecting."); 5699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return true; 5709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li DiscoverConnectReceiver receiver = new DiscoverConnectReceiver(deviceID); 5729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li listeningDevices.put("Connect" + deviceID, receiver); 5739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.registerReceiver(receiver, mDiscoverConnectFilter); 5749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return mBluetoothAdapter.startDiscovery(); 5759f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 5779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Bond to a specified device once it's discovered.", 578d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi returns = "Whether discovery started successfully. ") 5799f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public Boolean bluetoothDiscoverAndBond( 5809f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @RpcParameter(name = "deviceID", 581d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 582d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID) { 5839f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mBluetoothAdapter.cancelDiscovery(); 5849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (listeningDevices.containsKey(deviceID)) { 5859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("This device is already in the process of discovery and bonding."); 5869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return true; 5879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (BluetoothFacade.deviceExists(mBluetoothAdapter.getBondedDevices(), deviceID)) { 5899f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Device " + deviceID + " is already bonded."); 5909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mEventFacade.postEvent("Bond" + deviceID, mGoodNews); 5919f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return true; 5929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5939f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li DiscoverBondReceiver receiver = new DiscoverBondReceiver(deviceID); 5949f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (listeningDevices.containsKey("Bond" + deviceID)) { 5959f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.unregisterReceiver(listeningDevices.remove("Bond" + deviceID)); 5969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 5979f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li listeningDevices.put("Bond" + deviceID, receiver); 5989f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mService.registerReceiver(receiver, mBondFilter); 5999f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.d("Start discovery for bonding."); 6009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return mBluetoothAdapter.startDiscovery(); 6019f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 6029f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 6039f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Unbond a device.", 604d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi returns = "Whether the device was successfully unbonded.") 6059f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public Boolean bluetoothUnbond( 6069f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @RpcParameter(name = "deviceID", 607d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 608d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID) throws Exception { 6099f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), 6109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li deviceID); 6119f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return mDevice.removeBond(); 6129f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 6139f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 6149f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Rpc(description = "Connect to a device that is already bonded.") 6159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void bluetoothConnectBonded( 6169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @RpcParameter(name = "deviceID", 617d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 618d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID) throws Exception { 6199f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), 6209f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li deviceID); 6219f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li connectProfile(mDevice, deviceID); 6229f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 6239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 6247b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal @Rpc(description = "Disconnect from a device that is already connected.") 6257b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal public void bluetoothDisconnectConnected( 6267b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal @RpcParameter(name = "deviceID", 627d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 628d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID) throws Exception { 6297b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), 6307b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal deviceID); 6317b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal disconnectProfiles(mDevice, deviceID); 6327b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal } 6337b8c49f4f5af2182a25f866a279270ccd72f080fSanket Agarwal 634d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi @Rpc(description = "Disconnect on a profile from a device that is already connected.") 635d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi public void bluetoothDisconnectConnectedProfile( 636d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi @RpcParameter(name = "deviceID", 637d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 638d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID, 639d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi @RpcParameter(name = "profileSet", 640d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "List of profiles to disconnect from.") 641d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi JSONArray profileSet 642d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi ) throws Exception { 643d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), 644d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi deviceID); 645d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi disconnectProfiles(mDevice, deviceID, jsonArrayToIntegerList(profileSet)); 646d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 647d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi 64802cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo @Rpc(description = "Change permissions for a profile.") 64902cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo public void bluetoothChangeProfileAccessPermission( 65002cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo @RpcParameter(name = "deviceID", 651d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Name or MAC address of a bluetooth device.") 652d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi String deviceID, 65302cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo @RpcParameter(name = "profileID", 654d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Number of Profile to change access permission") 655d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi Integer profileID, 65602cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo @RpcParameter(name = "access", 657d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi description = "Access level 0 = Unknown, 1 = Allowed, 2 = Rejected") 658d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi Integer access 659d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi ) throws Exception { 66002cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo if (access < 0 || access > 2) { 66102cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo Log.w("Unsupported access level."); 66202cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo return; 66302cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo } 66402cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), 66502cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo deviceID); 666d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi switch (profileID) { 66702cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo case BluetoothProfile.PBAP: 66802cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo mDevice.setPhonebookAccessPermission(access); 66902cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo break; 67002cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo default: 67102cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo Log.w("Unsupported profile access change."); 67202cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo } 67302cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo } 67402cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo 67502cd37e8066812cd73abe71f060e39cfac74f9a7Joseph Pirozzo 6769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 6779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void shutdown() { 678d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi for (BroadcastReceiver receiver : listeningDevices.values()) { 679d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi try { 680d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi mService.unregisterReceiver(receiver); 681d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } catch (IllegalArgumentException ex) { 682d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi Log.e("Failed to unregister " + ex); 683d9a81edc88a6ffdecebaa306279557bc18b71c7dRam Periathiruvadi } 6849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 6859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li listeningDevices.clear(); 68602e949859dc20c9ab6d0a79688eff87beae68d61tturney mService.unregisterReceiver(mPairingHelper); 6879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 6889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li} 689fc6e4af002e75301e13ddf524c0317e3a52be858tturney 690