135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie/* 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. 1535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie */ 1635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 1735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiepackage com.android.bluetooth.hid; 1835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 1935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.bluetooth.BluetoothDevice; 2035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.bluetooth.BluetoothInputDevice; 2135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.bluetooth.BluetoothProfile; 2235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.bluetooth.IBluetooth; 2335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.bluetooth.IBluetoothInputDevice; 2435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.content.Intent; 2537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport android.content.pm.PackageManager; 2657addccaa75691f8eb6f35204d608a63695a9705Priti Agheraimport android.os.Bundle; 2735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.os.IBinder; 2835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.os.Handler; 2935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.os.Message; 3035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.os.RemoteException; 3135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.os.ServiceManager; 3235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.provider.Settings; 3335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport android.util.Log; 3437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.btservice.AdapterService; 3537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.btservice.ProfileService; 3637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.Utils; 3735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport java.util.ArrayList; 3835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport java.util.Collections; 3935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport java.util.HashMap; 4035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport java.util.List; 4135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieimport java.util.Map; 4237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 4335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 4435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie/** 45522003462124b08ef9345a6778df4089d202d6faHarish Paryani * Provides Bluetooth Hid Host profile, as a service in 4635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie * the Bluetooth application. 4735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie * @hide 4835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie */ 49b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpublic class HidService extends ProfileService { 50fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie private static final boolean DBG = false; 51b5cc776c9353a203cdde97e62b25f05d9633d14cfredc private static final String TAG = "HidService"; 5274ae04c73312403e89db0f8e9bd9601d403b4783fredc 5335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private Map<BluetoothDevice, Integer> mInputDevices; 5474ae04c73312403e89db0f8e9bd9601d403b4783fredc private boolean mNativeAvailable; 554f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static HidService sHidService; 56ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta private BluetoothDevice mTargetDevice = null; 5735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 5835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private static final int MESSAGE_CONNECT = 1; 5935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private static final int MESSAGE_DISCONNECT = 2; 6035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private static final int MESSAGE_CONNECT_STATE_CHANGED = 3; 6157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_GET_PROTOCOL_MODE = 4; 6257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_VIRTUAL_UNPLUG = 5; 6357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_ON_GET_PROTOCOL_MODE = 6; 6457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_SET_PROTOCOL_MODE = 7; 6557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_GET_REPORT = 8; 6657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_ON_GET_REPORT = 9; 6757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_SET_REPORT = 10; 6857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_SEND_DATA = 11; 6957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12; 703a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen private static final int MESSAGE_ON_HANDSHAKE = 13; 7135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 7235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie static { 7335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie classInitNative(); 7435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 7535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 76b5cc776c9353a203cdde97e62b25f05d9633d14cfredc public String getName() { 77b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return TAG; 7835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 7935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 8074ae04c73312403e89db0f8e9bd9601d403b4783fredc public IProfileServiceBinder initBinder() { 8174ae04c73312403e89db0f8e9bd9601d403b4783fredc return new BluetoothInputDeviceBinder(this); 8235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 8335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 84b5cc776c9353a203cdde97e62b25f05d9633d14cfredc protected boolean start() { 856654f5c903de510a70f9e72cd5ad7837b615d93ffredc mInputDevices = Collections.synchronizedMap(new HashMap<BluetoothDevice, Integer>()); 866654f5c903de510a70f9e72cd5ad7837b615d93ffredc initializeNative(); 8774ae04c73312403e89db0f8e9bd9601d403b4783fredc mNativeAvailable=true; 884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta setHidService(this); 89b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return true; 906654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 916654f5c903de510a70f9e72cd5ad7837b615d93ffredc 92b5cc776c9353a203cdde97e62b25f05d9633d14cfredc protected boolean stop() { 9335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie if (DBG) log("Stopping Bluetooth HidService"); 9474ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 9574ae04c73312403e89db0f8e9bd9601d403b4783fredc } 9674ae04c73312403e89db0f8e9bd9601d403b4783fredc 9774ae04c73312403e89db0f8e9bd9601d403b4783fredc protected boolean cleanup() { 9874ae04c73312403e89db0f8e9bd9601d403b4783fredc if (mNativeAvailable) { 9974ae04c73312403e89db0f8e9bd9601d403b4783fredc cleanupNative(); 10074ae04c73312403e89db0f8e9bd9601d403b4783fredc mNativeAvailable=false; 10174ae04c73312403e89db0f8e9bd9601d403b4783fredc } 1026654f5c903de510a70f9e72cd5ad7837b615d93ffredc 103b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if(mInputDevices != null) { 104b5cc776c9353a203cdde97e62b25f05d9633d14cfredc mInputDevices.clear(); 1056654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta clearHidService(); 107b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return true; 10835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 10935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 1104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public static synchronized HidService getHidService(){ 1114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sHidService != null && sHidService.isAvailable()) { 1124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "getHidService(): returning " + sHidService); 1134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta return sHidService; 1144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1154f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) { 1164f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sHidService == null) { 1174f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG, "getHidService(): service is NULL"); 1184f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else if (!(sHidService.isAvailable())) { 1194f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG,"getHidService(): service is not available"); 1204f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1214f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1224f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta return null; 1234f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1244f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1254f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static synchronized void setHidService(HidService instance) { 1264f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (instance != null && instance.isAvailable()) { 1274f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "setHidService(): set to: " + sHidService); 1284f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta sHidService = instance; 1294f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else { 1304f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) { 1314f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sHidService == null) { 1324f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG, "setHidService(): service not available"); 1334f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else if (!sHidService.isAvailable()) { 1344f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG,"setHidService(): service is cleaning up"); 1354f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1364f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1374f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1384f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1394f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1404f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static synchronized void clearHidService() { 1414f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta sHidService = null; 1424f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1434f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1444f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 14535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private final Handler mHandler = new Handler() { 14635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 14735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie @Override 14835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public void handleMessage(Message msg) { 14935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie switch (msg.what) { 15035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case MESSAGE_CONNECT: 15135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie { 15235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie BluetoothDevice device = (BluetoothDevice) msg.obj; 15374ae04c73312403e89db0f8e9bd9601d403b4783fredc if (!connectHidNative(Utils.getByteAddress(device)) ) { 15435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING); 15535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED); 15635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie break; 15735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 158ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta mTargetDevice = device; 15935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 16035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie break; 16135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case MESSAGE_DISCONNECT: 16235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie { 16335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie BluetoothDevice device = (BluetoothDevice) msg.obj; 16474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (!disconnectHidNative(Utils.getByteAddress(device)) ) { 16535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING); 16635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED); 16735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie break; 16835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 16935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 17035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie break; 17135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case MESSAGE_CONNECT_STATE_CHANGED: 17235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie { 17335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie BluetoothDevice device = getDevice((byte[]) msg.obj); 17435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie int halState = msg.arg1; 17599a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M Integer prevStateInteger = mInputDevices.get(device); 17699a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M int prevState = (prevStateInteger == null) ? 17799a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M BluetoothInputDevice.STATE_DISCONNECTED :prevStateInteger; 17899a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M if(DBG) Log.d(TAG, "MESSAGE_CONNECT_STATE_CHANGED newState:"+ 17999a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M convertHalState(halState)+", prevState:"+prevState); 180ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta if(halState == CONN_STATE_CONNECTED && 181ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta prevState == BluetoothInputDevice.STATE_DISCONNECTED && 182ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta (!okToConnect(device))) { 1830f4ef70f0bc246b224f7b6da524128db89fcc8a7Matthew Xie if (DBG) Log.d(TAG,"Incoming HID connection rejected"); 18499a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M disconnectHidNative(Utils.getByteAddress(device)); 18599a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M } else { 18699a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M broadcastConnectionState(device, convertHalState(halState)); 18799a6ee18f09cf8e7ddff91d68267db21867b3cdfSyed Ibrahim M } 188fe19c7f20ca3abc252965be60727e8a198cc6ff3Matthew Xie if (halState == CONN_STATE_CONNECTED && 189fe19c7f20ca3abc252965be60727e8a198cc6ff3Matthew Xie (mTargetDevice != null && mTargetDevice.equals(device))) { 190ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta mTargetDevice = null; 191fe19c7f20ca3abc252965be60727e8a198cc6ff3Matthew Xie // local device originated connection to hid device, move out 192fe19c7f20ca3abc252965be60727e8a198cc6ff3Matthew Xie // of quiet mode 193fe19c7f20ca3abc252965be60727e8a198cc6ff3Matthew Xie AdapterService adapterService = AdapterService.getAdapterService(); 194fe19c7f20ca3abc252965be60727e8a198cc6ff3Matthew Xie adapterService.enable(false); 195ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta } 19635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 19735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie break; 19857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_GET_PROTOCOL_MODE: 19957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 20057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = (BluetoothDevice) msg.obj; 20174ae04c73312403e89db0f8e9bd9601d403b4783fredc if(!getProtocolModeNative(Utils.getByteAddress(device)) ) { 20257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Log.e(TAG, "Error: get protocol mode native returns false"); 20357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 20457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 20557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 20657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 20757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_ON_GET_PROTOCOL_MODE: 20857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 20957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = getDevice((byte[]) msg.obj); 21057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera int protocolMode = msg.arg1; 21157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera broadcastProtocolMode(device, protocolMode); 21257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 21357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 21457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_VIRTUAL_UNPLUG: 21557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 21657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = (BluetoothDevice) msg.obj; 21774ae04c73312403e89db0f8e9bd9601d403b4783fredc if(!virtualUnPlugNative(Utils.getByteAddress(device))) { 21857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Log.e(TAG, "Error: virtual unplug native returns false"); 21957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 22057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 22157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 22257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_SET_PROTOCOL_MODE: 22357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 22457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = (BluetoothDevice) msg.obj; 22557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera byte protocolMode = (byte) msg.arg1; 22657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera log("sending set protocol mode(" + protocolMode + ")"); 22774ae04c73312403e89db0f8e9bd9601d403b4783fredc if(!setProtocolModeNative(Utils.getByteAddress(device), protocolMode)) { 22857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Log.e(TAG, "Error: set protocol mode native returns false"); 22957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 23057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 23157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 23257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_GET_REPORT: 23357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 23457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = (BluetoothDevice) msg.obj; 23557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Bundle data = msg.getData(); 23657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera byte reportType = data.getByte(BluetoothInputDevice.EXTRA_REPORT_TYPE); 23757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera byte reportId = data.getByte(BluetoothInputDevice.EXTRA_REPORT_ID); 23857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera int bufferSize = data.getInt(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE); 23974ae04c73312403e89db0f8e9bd9601d403b4783fredc if(!getReportNative(Utils.getByteAddress(device), reportType, reportId, bufferSize)) { 24057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Log.e(TAG, "Error: get report native returns false"); 24157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 24257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 24357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 244b8e4250de151551d5dacca895e62761355839d7dMike J. Chen case MESSAGE_ON_GET_REPORT: 245b8e4250de151551d5dacca895e62761355839d7dMike J. Chen { 246b8e4250de151551d5dacca895e62761355839d7dMike J. Chen BluetoothDevice device = getDevice((byte[])msg.obj); 247b8e4250de151551d5dacca895e62761355839d7dMike J. Chen Bundle data = msg.getData(); 248b8e4250de151551d5dacca895e62761355839d7dMike J. Chen byte[] report = data.getByteArray(BluetoothInputDevice.EXTRA_REPORT); 249b8e4250de151551d5dacca895e62761355839d7dMike J. Chen int bufferSize = data.getInt(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE); 250b8e4250de151551d5dacca895e62761355839d7dMike J. Chen broadcastReport(device, report, bufferSize); 251b8e4250de151551d5dacca895e62761355839d7dMike J. Chen } 252b8e4250de151551d5dacca895e62761355839d7dMike J. Chen break; 2533a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen case MESSAGE_ON_HANDSHAKE: 2543a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen { 2553a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen BluetoothDevice device = getDevice((byte[])msg.obj); 2563a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen int status = msg.arg1; 2573a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen broadcastHandshake(device, status); 2583a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen } 2593a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen break; 26057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_SET_REPORT: 26157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 26257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = (BluetoothDevice) msg.obj; 26357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Bundle data = msg.getData(); 26457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera byte reportType = data.getByte(BluetoothInputDevice.EXTRA_REPORT_TYPE); 26557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera String report = data.getString(BluetoothInputDevice.EXTRA_REPORT); 26674ae04c73312403e89db0f8e9bd9601d403b4783fredc if(!setReportNative(Utils.getByteAddress(device), reportType, report)) { 26757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Log.e(TAG, "Error: set report native returns false"); 26857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 26957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 27057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 27157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_SEND_DATA: 27257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 27357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = (BluetoothDevice) msg.obj; 27457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Bundle data = msg.getData(); 27557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera String report = data.getString(BluetoothInputDevice.EXTRA_REPORT); 27674ae04c73312403e89db0f8e9bd9601d403b4783fredc if(!sendDataNative(Utils.getByteAddress(device), report)) { 27757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Log.e(TAG, "Error: send data native returns false"); 27857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 27957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 28057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 28157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera case MESSAGE_ON_VIRTUAL_UNPLUG: 28257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera { 28357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera BluetoothDevice device = getDevice((byte[]) msg.obj); 28457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera int status = msg.arg1; 28557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera broadcastVirtualUnplugStatus(device, status); 28657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 28757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera break; 28835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 28935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 29035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie }; 29135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 29235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie /** 29335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie * Handlers for incoming service calls 29435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie */ 29574ae04c73312403e89db0f8e9bd9601d403b4783fredc private static class BluetoothInputDeviceBinder extends IBluetoothInputDevice.Stub implements IProfileServiceBinder{ 29674ae04c73312403e89db0f8e9bd9601d403b4783fredc private HidService mService; 29774ae04c73312403e89db0f8e9bd9601d403b4783fredc public BluetoothInputDeviceBinder(HidService svc) { 29874ae04c73312403e89db0f8e9bd9601d403b4783fredc mService = svc; 29974ae04c73312403e89db0f8e9bd9601d403b4783fredc } 30035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 30174ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean cleanup() { 30274ae04c73312403e89db0f8e9bd9601d403b4783fredc mService = null; 30335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return true; 30435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 30535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 30674ae04c73312403e89db0f8e9bd9601d403b4783fredc private HidService getService() { 30737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 30837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"InputDevice call not allowed for non-active user"); 30937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return null; 31037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 31137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 31274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (mService != null && mService.isAvailable()) { 31374ae04c73312403e89db0f8e9bd9601d403b4783fredc return mService; 31474ae04c73312403e89db0f8e9bd9601d403b4783fredc } 31574ae04c73312403e89db0f8e9bd9601d403b4783fredc return null; 31674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 31774ae04c73312403e89db0f8e9bd9601d403b4783fredc 31874ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean connect(BluetoothDevice device) { 31974ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 32074ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 32174ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.connect(device); 32274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 32374ae04c73312403e89db0f8e9bd9601d403b4783fredc 32435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public boolean disconnect(BluetoothDevice device) { 32574ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 32674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 32774ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.disconnect(device); 32835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 32935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 33035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public int getConnectionState(BluetoothDevice device) { 33174ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 33274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return BluetoothInputDevice.STATE_DISCONNECTED; 33374ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getConnectionState(device); 33435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 33535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 33635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public List<BluetoothDevice> getConnectedDevices() { 33774ae04c73312403e89db0f8e9bd9601d403b4783fredc return getDevicesMatchingConnectionStates( 33835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie new int[] {BluetoothProfile.STATE_CONNECTED}); 33935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 34035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 34135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 34274ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 34374ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return new ArrayList<BluetoothDevice>(0); 34474ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getDevicesMatchingConnectionStates(states); 34535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 34635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 34735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public boolean setPriority(BluetoothDevice device, int priority) { 34874ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 34974ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 35074ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.setPriority(device, priority); 35135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 35235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 35335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie public int getPriority(BluetoothDevice device) { 35474ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 35574ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED; 35674ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getPriority(device); 35735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 35874ae04c73312403e89db0f8e9bd9601d403b4783fredc 3591404ab28fd296373a98b766b0b01193985446eabHarish Paryani /* The following APIs regarding test app for compliance */ 36057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera public boolean getProtocolMode(BluetoothDevice device) { 36174ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 36274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 36374ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getProtocolMode(device); 36457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 36557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 36657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera public boolean virtualUnplug(BluetoothDevice device) { 36774ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 36874ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 36974ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.virtualUnplug(device); 37057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 37157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 37257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera public boolean setProtocolMode(BluetoothDevice device, int protocolMode) { 37374ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 37474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 37574ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.setProtocolMode(device, protocolMode); 37657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 37774ae04c73312403e89db0f8e9bd9601d403b4783fredc 37857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) { 37974ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 38074ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 38174ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getReport(device, reportType, reportId, bufferSize) ; 38257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 38357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 38457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera public boolean setReport(BluetoothDevice device, byte reportType, String report) { 38574ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 38674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 38774ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.setReport(device, reportType, report); 38857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 38957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 39057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera public boolean sendData(BluetoothDevice device, String report) { 39174ae04c73312403e89db0f8e9bd9601d403b4783fredc HidService service = getService(); 39274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 39374ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.sendData(device, report); 39474ae04c73312403e89db0f8e9bd9601d403b4783fredc } 39574ae04c73312403e89db0f8e9bd9601d403b4783fredc }; 39674ae04c73312403e89db0f8e9bd9601d403b4783fredc 39774ae04c73312403e89db0f8e9bd9601d403b4783fredc //APIs 39874ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean connect(BluetoothDevice device) { 39974ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 40074ae04c73312403e89db0f8e9bd9601d403b4783fredc if (getConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED) { 40174ae04c73312403e89db0f8e9bd9601d403b4783fredc Log.e(TAG, "Hid Device not disconnected: " + device); 40274ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 40374ae04c73312403e89db0f8e9bd9601d403b4783fredc } 40474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (getPriority(device) == BluetoothInputDevice.PRIORITY_OFF) { 40574ae04c73312403e89db0f8e9bd9601d403b4783fredc Log.e(TAG, "Hid Device PRIORITY_OFF: " + device); 40674ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 40774ae04c73312403e89db0f8e9bd9601d403b4783fredc } 40874ae04c73312403e89db0f8e9bd9601d403b4783fredc 40974ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_CONNECT, device); 41074ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 41174ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 41274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 41374ae04c73312403e89db0f8e9bd9601d403b4783fredc 41474ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean disconnect(BluetoothDevice device) { 41574ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 41674ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_DISCONNECT,device); 41774ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 41874ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 41974ae04c73312403e89db0f8e9bd9601d403b4783fredc } 42074ae04c73312403e89db0f8e9bd9601d403b4783fredc 42174ae04c73312403e89db0f8e9bd9601d403b4783fredc int getConnectionState(BluetoothDevice device) { 42274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (mInputDevices.get(device) == null) { 42374ae04c73312403e89db0f8e9bd9601d403b4783fredc return BluetoothInputDevice.STATE_DISCONNECTED; 42474ae04c73312403e89db0f8e9bd9601d403b4783fredc } 42574ae04c73312403e89db0f8e9bd9601d403b4783fredc return mInputDevices.get(device); 42674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 42774ae04c73312403e89db0f8e9bd9601d403b4783fredc 42874ae04c73312403e89db0f8e9bd9601d403b4783fredc List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 42974ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 43074ae04c73312403e89db0f8e9bd9601d403b4783fredc List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>(); 43174ae04c73312403e89db0f8e9bd9601d403b4783fredc 43274ae04c73312403e89db0f8e9bd9601d403b4783fredc for (BluetoothDevice device: mInputDevices.keySet()) { 43374ae04c73312403e89db0f8e9bd9601d403b4783fredc int inputDeviceState = getConnectionState(device); 43474ae04c73312403e89db0f8e9bd9601d403b4783fredc for (int state : states) { 43574ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state == inputDeviceState) { 43674ae04c73312403e89db0f8e9bd9601d403b4783fredc inputDevices.add(device); 43774ae04c73312403e89db0f8e9bd9601d403b4783fredc break; 43874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 43957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 44074ae04c73312403e89db0f8e9bd9601d403b4783fredc } 44174ae04c73312403e89db0f8e9bd9601d403b4783fredc return inputDevices; 44274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 44357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 4444f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public boolean setPriority(BluetoothDevice device, int priority) { 44574ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 44674ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 447c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.putInt(getContentResolver(), 448c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.getBluetoothInputDevicePriorityKey(device.getAddress()), 44974ae04c73312403e89db0f8e9bd9601d403b4783fredc priority); 45074ae04c73312403e89db0f8e9bd9601d403b4783fredc if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority); 45174ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 45274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 45374ae04c73312403e89db0f8e9bd9601d403b4783fredc 4544f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public int getPriority(BluetoothDevice device) { 45574ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 45674ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 457c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey int priority = Settings.Global.getInt(getContentResolver(), 458c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.getBluetoothInputDevicePriorityKey(device.getAddress()), 45974ae04c73312403e89db0f8e9bd9601d403b4783fredc BluetoothProfile.PRIORITY_UNDEFINED); 46074ae04c73312403e89db0f8e9bd9601d403b4783fredc return priority; 46174ae04c73312403e89db0f8e9bd9601d403b4783fredc } 46274ae04c73312403e89db0f8e9bd9601d403b4783fredc 46374ae04c73312403e89db0f8e9bd9601d403b4783fredc /* The following APIs regarding test app for compliance */ 46474ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean getProtocolMode(BluetoothDevice device) { 46574ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 46674ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 46774ae04c73312403e89db0f8e9bd9601d403b4783fredc int state = this.getConnectionState(device); 46874ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state != BluetoothInputDevice.STATE_CONNECTED) { 46974ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 47057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 47174ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_GET_PROTOCOL_MODE,device); 47274ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 47374ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 47474ae04c73312403e89db0f8e9bd9601d403b4783fredc /* String objectPath = getObjectPathFromAddress(device.getAddress()); 47574ae04c73312403e89db0f8e9bd9601d403b4783fredc return getProtocolModeInputDeviceNative(objectPath);*/ 47674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 47735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 47874ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean virtualUnplug(BluetoothDevice device) { 47974ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 48074ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 48174ae04c73312403e89db0f8e9bd9601d403b4783fredc int state = this.getConnectionState(device); 48274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state != BluetoothInputDevice.STATE_CONNECTED) { 48374ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 48474ae04c73312403e89db0f8e9bd9601d403b4783fredc } 48574ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_VIRTUAL_UNPLUG,device); 48674ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 48774ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 48874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 48974ae04c73312403e89db0f8e9bd9601d403b4783fredc 49074ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean setProtocolMode(BluetoothDevice device, int protocolMode) { 49174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 49274ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 49374ae04c73312403e89db0f8e9bd9601d403b4783fredc int state = this.getConnectionState(device); 49474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state != BluetoothInputDevice.STATE_CONNECTED) { 49574ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 49674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 49774ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_SET_PROTOCOL_MODE); 49874ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.obj = device; 49974ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.arg1 = protocolMode; 50074ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 50174ae04c73312403e89db0f8e9bd9601d403b4783fredc return true ; 50274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 50374ae04c73312403e89db0f8e9bd9601d403b4783fredc 50474ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) { 50574ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 50674ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 50774ae04c73312403e89db0f8e9bd9601d403b4783fredc int state = this.getConnectionState(device); 50874ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state != BluetoothInputDevice.STATE_CONNECTED) { 50974ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 51074ae04c73312403e89db0f8e9bd9601d403b4783fredc } 51174ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_GET_REPORT); 51274ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.obj = device; 51374ae04c73312403e89db0f8e9bd9601d403b4783fredc Bundle data = new Bundle(); 51474ae04c73312403e89db0f8e9bd9601d403b4783fredc data.putByte(BluetoothInputDevice.EXTRA_REPORT_TYPE, reportType); 51574ae04c73312403e89db0f8e9bd9601d403b4783fredc data.putByte(BluetoothInputDevice.EXTRA_REPORT_ID, reportId); 51674ae04c73312403e89db0f8e9bd9601d403b4783fredc data.putInt(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE, bufferSize); 51774ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.setData(data); 51874ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 51974ae04c73312403e89db0f8e9bd9601d403b4783fredc return true ; 52074ae04c73312403e89db0f8e9bd9601d403b4783fredc } 52174ae04c73312403e89db0f8e9bd9601d403b4783fredc 52274ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean setReport(BluetoothDevice device, byte reportType, String report) { 52374ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 52474ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 52574ae04c73312403e89db0f8e9bd9601d403b4783fredc int state = this.getConnectionState(device); 52674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state != BluetoothInputDevice.STATE_CONNECTED) { 52774ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 52874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 52974ae04c73312403e89db0f8e9bd9601d403b4783fredc Message msg = mHandler.obtainMessage(MESSAGE_SET_REPORT); 53074ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.obj = device; 53174ae04c73312403e89db0f8e9bd9601d403b4783fredc Bundle data = new Bundle(); 53274ae04c73312403e89db0f8e9bd9601d403b4783fredc data.putByte(BluetoothInputDevice.EXTRA_REPORT_TYPE, reportType); 53374ae04c73312403e89db0f8e9bd9601d403b4783fredc data.putString(BluetoothInputDevice.EXTRA_REPORT, report); 53474ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.setData(data); 53574ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 53674ae04c73312403e89db0f8e9bd9601d403b4783fredc return true ; 53774ae04c73312403e89db0f8e9bd9601d403b4783fredc 53874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 53974ae04c73312403e89db0f8e9bd9601d403b4783fredc 54074ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean sendData(BluetoothDevice device, String report) { 54174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 54274ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 54374ae04c73312403e89db0f8e9bd9601d403b4783fredc int state = this.getConnectionState(device); 54474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (state != BluetoothInputDevice.STATE_CONNECTED) { 54574ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 54674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 54774ae04c73312403e89db0f8e9bd9601d403b4783fredc 54874ae04c73312403e89db0f8e9bd9601d403b4783fredc return sendDataNative(Utils.getByteAddress(device), report); 54974ae04c73312403e89db0f8e9bd9601d403b4783fredc /*Message msg = mHandler.obtainMessage(MESSAGE_SEND_DATA); 55074ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.obj = device; 55174ae04c73312403e89db0f8e9bd9601d403b4783fredc Bundle data = new Bundle(); 55274ae04c73312403e89db0f8e9bd9601d403b4783fredc data.putString(BluetoothInputDevice.EXTRA_REPORT, report); 55374ae04c73312403e89db0f8e9bd9601d403b4783fredc msg.setData(data); 55474ae04c73312403e89db0f8e9bd9601d403b4783fredc mHandler.sendMessage(msg); 55574ae04c73312403e89db0f8e9bd9601d403b4783fredc return true ;*/ 55674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 55774ae04c73312403e89db0f8e9bd9601d403b4783fredc 55857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private void onGetProtocolMode(byte[] address, int mode) { 55957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE); 56057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera msg.obj = address; 56157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera msg.arg1 = mode; 56257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera mHandler.sendMessage(msg); 56357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 56457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 565b8e4250de151551d5dacca895e62761355839d7dMike J. Chen private void onGetReport(byte[] address, byte[] report, int rpt_size) { 566b8e4250de151551d5dacca895e62761355839d7dMike J. Chen Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_REPORT); 567b8e4250de151551d5dacca895e62761355839d7dMike J. Chen msg.obj = address; 568b8e4250de151551d5dacca895e62761355839d7dMike J. Chen Bundle data = new Bundle(); 569b8e4250de151551d5dacca895e62761355839d7dMike J. Chen data.putByteArray(BluetoothInputDevice.EXTRA_REPORT, report); 570b8e4250de151551d5dacca895e62761355839d7dMike J. Chen data.putInt(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE, rpt_size); 571b8e4250de151551d5dacca895e62761355839d7dMike J. Chen msg.setData(data); 572b8e4250de151551d5dacca895e62761355839d7dMike J. Chen mHandler.sendMessage(msg); 573b8e4250de151551d5dacca895e62761355839d7dMike J. Chen } 574b8e4250de151551d5dacca895e62761355839d7dMike J. Chen 5753a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen private void onHandshake(byte[] address, int status) { 5763a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen Message msg = mHandler.obtainMessage(MESSAGE_ON_HANDSHAKE); 5773a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen msg.obj = address; 5783a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen msg.arg1 = status; 5793a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen mHandler.sendMessage(msg); 5803a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen } 5813a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen 58257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private void onVirtualUnplug(byte[] address, int status) { 58357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Message msg = mHandler.obtainMessage(MESSAGE_ON_VIRTUAL_UNPLUG); 58457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera msg.obj = address; 58557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera msg.arg1 = status; 58657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera mHandler.sendMessage(msg); 58757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 58857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 58935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private void onConnectStateChanged(byte[] address, int state) { 59035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_STATE_CHANGED); 59135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie msg.obj = address; 59235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie msg.arg1 = state; 59335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie mHandler.sendMessage(msg); 59435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 59535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 59635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie // This method does not check for error conditon (newState == prevState) 59735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private void broadcastConnectionState(BluetoothDevice device, int newState) { 59835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie Integer prevStateInteger = mInputDevices.get(device); 59935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie int prevState = (prevStateInteger == null) ? BluetoothInputDevice.STATE_DISCONNECTED : 60035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie prevStateInteger; 60135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie if (prevState == newState) { 60235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie Log.w(TAG, "no state change: " + newState); 60335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return; 60435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 60535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie mInputDevices.put(device, newState); 60635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 607a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T /* Notifying the connection state change of the profile before sending the intent for 608a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T connection state change, as it was causing a race condition, with the UI not being 609a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T updated with the correct connection state. */ 610fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie log("Connection state " + device + ": " + prevState + "->" + newState); 611a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T notifyProfileConnectionStateChanged(device, BluetoothProfile.INPUT_DEVICE, 612a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T newState, prevState); 61335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); 61435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 61535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 61635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 61735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 61835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie sendBroadcast(intent, BLUETOOTH_PERM); 61935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 62035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 6213a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen private void broadcastHandshake(BluetoothDevice device, int status) { 6223a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen Intent intent = new Intent(BluetoothInputDevice.ACTION_HANDSHAKE); 6233a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 6243a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen intent.putExtra(BluetoothInputDevice.EXTRA_STATUS, status); 6253a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 6263a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen sendBroadcast(intent, BLUETOOTH_PERM); 6273a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen } 6283a04c35ba5f723ee4a6e1f1c37514691ebd1447dMike J. Chen 62957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private void broadcastProtocolMode(BluetoothDevice device, int protocolMode) { 63057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Intent intent = new Intent(BluetoothInputDevice.ACTION_PROTOCOL_MODE_CHANGED); 63157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 63257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera intent.putExtra(BluetoothInputDevice.EXTRA_PROTOCOL_MODE, protocolMode); 63357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 63457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera sendBroadcast(intent, BLUETOOTH_PERM); 63557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera if (DBG) log("Protocol Mode (" + device + "): " + protocolMode); 63657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 63757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 638b8e4250de151551d5dacca895e62761355839d7dMike J. Chen private void broadcastReport(BluetoothDevice device, byte[] report, int rpt_size) { 639b8e4250de151551d5dacca895e62761355839d7dMike J. Chen Intent intent = new Intent(BluetoothInputDevice.ACTION_REPORT); 640b8e4250de151551d5dacca895e62761355839d7dMike J. Chen intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 641b8e4250de151551d5dacca895e62761355839d7dMike J. Chen intent.putExtra(BluetoothInputDevice.EXTRA_REPORT, report); 642b8e4250de151551d5dacca895e62761355839d7dMike J. Chen intent.putExtra(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE, rpt_size); 643b8e4250de151551d5dacca895e62761355839d7dMike J. Chen intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 644b8e4250de151551d5dacca895e62761355839d7dMike J. Chen sendBroadcast(intent, BLUETOOTH_PERM); 645b8e4250de151551d5dacca895e62761355839d7dMike J. Chen } 646b8e4250de151551d5dacca895e62761355839d7dMike J. Chen 64757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private void broadcastVirtualUnplugStatus(BluetoothDevice device, int status) { 64857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera Intent intent = new Intent(BluetoothInputDevice.ACTION_VIRTUAL_UNPLUG_STATUS); 64957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 65057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera intent.putExtra(BluetoothInputDevice.EXTRA_VIRTUAL_UNPLUG_STATUS, status); 65157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 65257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera sendBroadcast(intent, BLUETOOTH_PERM); 65357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera } 65457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera 655ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta private boolean okToConnect(BluetoothDevice device) { 656ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta AdapterService adapterService = AdapterService.getAdapterService(); 657ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta //check if it is inbound connection in Quiet mode, priority and Bond status 658ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta //to decide if its ok to allow this connection 659ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta if((adapterService == null)|| 660ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta ((adapterService.isQuietModeEnabled()) &&(mTargetDevice == null)) || 661ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta (BluetoothProfile.PRIORITY_OFF == getPriority(device)) || 662ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta (device.getBondState() == BluetoothDevice.BOND_NONE)) 663ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta return false; 664ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta 665ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta return true; 666ca6110d57998fee7c7b572ca29061ee99a82ba37Ganesh Ganapathi Batta } 66774ae04c73312403e89db0f8e9bd9601d403b4783fredc private static int convertHalState(int halState) { 66835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie switch (halState) { 66935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case CONN_STATE_CONNECTED: 67035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return BluetoothProfile.STATE_CONNECTED; 67135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case CONN_STATE_CONNECTING: 67235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return BluetoothProfile.STATE_CONNECTING; 67335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case CONN_STATE_DISCONNECTED: 67435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return BluetoothProfile.STATE_DISCONNECTED; 67535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie case CONN_STATE_DISCONNECTING: 67635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return BluetoothProfile.STATE_DISCONNECTING; 67735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie default: 67835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie Log.e(TAG, "bad hid connection state: " + halState); 67935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return BluetoothProfile.STATE_DISCONNECTED; 68035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 68135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 68235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 68335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie // Constants matching Hal header file bt_hh.h 68435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie // bthh_connection_state_t 68535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private final static int CONN_STATE_CONNECTED = 0; 68635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private final static int CONN_STATE_CONNECTING = 1; 68735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private final static int CONN_STATE_DISCONNECTED = 2; 68835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private final static int CONN_STATE_DISCONNECTING = 3; 68935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 69035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private native static void classInitNative(); 6916654f5c903de510a70f9e72cd5ad7837b615d93ffredc private native void initializeNative(); 6926654f5c903de510a70f9e72cd5ad7837b615d93ffredc private native void cleanupNative(); 69335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private native boolean connectHidNative(byte[] btAddress); 69435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie private native boolean disconnectHidNative(byte[] btAddress); 69557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private native boolean getProtocolModeNative(byte[] btAddress); 69657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private native boolean virtualUnPlugNative(byte[] btAddress); 69757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private native boolean setProtocolModeNative(byte[] btAddress, byte protocolMode); 69857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private native boolean getReportNative(byte[]btAddress, byte reportType, byte reportId, int bufferSize); 69957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private native boolean setReportNative(byte[] btAddress, byte reportType, String report); 70057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera private native boolean sendDataNative(byte[] btAddress, String report); 70135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie} 702