1545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/* 24ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Copyright (C) 2011 The Android Open Source Project 3545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 4545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Licensed under the Apache License, Version 2.0 (the "License"); 5545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * you may not use this file except in compliance with the License. 6545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * You may obtain a copy of the License at 7545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 8545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * http://www.apache.org/licenses/LICENSE-2.0 9545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 10545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Unless required by applicable law or agreed to in writing, software 11545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * distributed under the License is distributed on an "AS IS" BASIS, 12545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * See the License for the specific language governing permissions and 14545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * limitations under the License. 15545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 16545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 17545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshpackage android.bluetooth; 18545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 19545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.annotation.SdkConstant; 20545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.annotation.SdkConstant.SdkConstantType; 21bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.ComponentName; 22545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.content.Context; 23bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.Intent; 24bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.ServiceConnection; 25545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.os.IBinder; 26545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.os.RemoteException; 27349e62f329bbb8edab89356973773a5648f26751Priti Agheraimport android.os.ServiceManager; 28545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.util.Log; 29545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 305a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.ArrayList; 315a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.List; 32545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 34545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/** 354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth Input 364ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device Profile. 37545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth 394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 404ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * the BluetoothInputDevice proxy object. 41545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 424ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>Each method is protected with its appropriate permission. 434ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *@hide 44545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 454ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganeshpublic final class BluetoothInputDevice implements BluetoothProfile { 46545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static final String TAG = "BluetoothInputDevice"; 470f42037eb7b5118015c2caca635538324ccf0ccffredc private static final boolean DBG = true; 48563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie private static final boolean VDBG = false; 49545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 50545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Intent used to broadcast the change in connection state of the Input 524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device profile. 534ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>This intent will have 3 extras: 554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <ul> 564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 574ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 584ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * </ul> 604ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 644ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 664ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * receive. 67545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 694ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 704ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; 71545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 72fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh /** 73349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 74349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 75349e62f329bbb8edab89356973773a5648f26751Priti Aghera @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 76349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String ACTION_PROTOCOL_MODE_CHANGED = 77349e62f329bbb8edab89356973773a5648f26751Priti Aghera "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED"; 78349e62f329bbb8edab89356973773a5648f26751Priti Aghera 79349e62f329bbb8edab89356973773a5648f26751Priti Aghera 80349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 81349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 82349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 83349e62f329bbb8edab89356973773a5648f26751Priti Aghera @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 84349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String ACTION_VIRTUAL_UNPLUG_STATUS = 85349e62f329bbb8edab89356973773a5648f26751Priti Aghera "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS"; 86349e62f329bbb8edab89356973773a5648f26751Priti Aghera 87349e62f329bbb8edab89356973773a5648f26751Priti Aghera 88349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 89fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh * Return codes for the connect and disconnect Bluez / Dbus calls. 904ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 91fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh */ 92fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000; 93fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 944ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 954ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 964ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 97fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001; 98fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 994ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1004ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1014ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 102fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002; 103fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 1044ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1054ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1064ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 107fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003; 108fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 1094ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1104ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1114ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 112fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_OPERATION_SUCCESS = 5004; 113fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 114349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 115349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 116349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 117349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int PROTOCOL_REPORT_MODE = 0; 118349e62f329bbb8edab89356973773a5648f26751Priti Aghera 119349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 120349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 121349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 122349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int PROTOCOL_BOOT_MODE = 1; 123349e62f329bbb8edab89356973773a5648f26751Priti Aghera 124349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 125349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 126349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 127349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int PROTOCOL_UNSUPPORTED_MODE = 255; 128349e62f329bbb8edab89356973773a5648f26751Priti Aghera 129349e62f329bbb8edab89356973773a5648f26751Priti Aghera /* int reportType, int reportType, int bufferSize */ 130349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 131349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 132349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 133349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final byte REPORT_TYPE_INPUT = 0; 134349e62f329bbb8edab89356973773a5648f26751Priti Aghera 135349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 136349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 137349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 138349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final byte REPORT_TYPE_OUTPUT = 1; 139349e62f329bbb8edab89356973773a5648f26751Priti Aghera 140349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 141349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 142349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 143349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final byte REPORT_TYPE_FEATURE = 2; 144349e62f329bbb8edab89356973773a5648f26751Priti Aghera 145349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 146349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 147349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 148349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0; 149349e62f329bbb8edab89356973773a5648f26751Priti Aghera 150349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 151349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 152349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 153349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1; 154349e62f329bbb8edab89356973773a5648f26751Priti Aghera 155349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 156349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 157349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 158349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE"; 159349e62f329bbb8edab89356973773a5648f26751Priti Aghera 160349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 161349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 162349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 163349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE"; 164349e62f329bbb8edab89356973773a5648f26751Priti Aghera 165349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 166349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 167349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 168349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID"; 169349e62f329bbb8edab89356973773a5648f26751Priti Aghera 170349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 171349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 172349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 173349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE"; 174349e62f329bbb8edab89356973773a5648f26751Priti Aghera 175349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 176349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 177349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 178349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT = "android.bluetooth.BluetoothInputDevice.extra.REPORT"; 179349e62f329bbb8edab89356973773a5648f26751Priti Aghera 180349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 181349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 182349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 183349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS"; 184349e62f329bbb8edab89356973773a5648f26751Priti Aghera 185bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private Context mContext; 1864ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private ServiceListener mServiceListener; 1874ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private BluetoothAdapter mAdapter; 188bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private IBluetoothInputDevice mService; 189545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 1900f42037eb7b5118015c2caca635538324ccf0ccffredc final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 1910f42037eb7b5118015c2caca635538324ccf0ccffredc new IBluetoothStateChangeCallback.Stub() { 1920f42037eb7b5118015c2caca635538324ccf0ccffredc public void onBluetoothStateChange(boolean up) { 1930f42037eb7b5118015c2caca635538324ccf0ccffredc if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 1940f42037eb7b5118015c2caca635538324ccf0ccffredc if (!up) { 195563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) Log.d(TAG,"Unbinding service..."); 1960f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 1970f42037eb7b5118015c2caca635538324ccf0ccffredc try { 1980f42037eb7b5118015c2caca635538324ccf0ccffredc mService = null; 1990f42037eb7b5118015c2caca635538324ccf0ccffredc mContext.unbindService(mConnection); 2000f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2010f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2020f42037eb7b5118015c2caca635538324ccf0ccffredc } 2030f42037eb7b5118015c2caca635538324ccf0ccffredc } 2040f42037eb7b5118015c2caca635538324ccf0ccffredc } else { 2050f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2060f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2070f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService == null) { 208563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) Log.d(TAG,"Binding service..."); 2090f42037eb7b5118015c2caca635538324ccf0ccffredc if (!mContext.bindService(new Intent(IBluetoothInputDevice.class.getName()), mConnection, 0)) { 2100f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG, "Could not bind to Bluetooth HID Service"); 2110f42037eb7b5118015c2caca635538324ccf0ccffredc } 2120f42037eb7b5118015c2caca635538324ccf0ccffredc } 2130f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2140f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2150f42037eb7b5118015c2caca635538324ccf0ccffredc } 2160f42037eb7b5118015c2caca635538324ccf0ccffredc } 2170f42037eb7b5118015c2caca635538324ccf0ccffredc } 2180f42037eb7b5118015c2caca635538324ccf0ccffredc } 2190f42037eb7b5118015c2caca635538324ccf0ccffredc }; 2200f42037eb7b5118015c2caca635538324ccf0ccffredc 221545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 222545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Create a BluetoothInputDevice proxy object for interacting with the local 2234ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Bluetooth Service which handles the InputDevice profile 2244ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 225545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 226bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie /*package*/ BluetoothInputDevice(Context context, ServiceListener l) { 227bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mContext = context; 2284ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mServiceListener = l; 2294ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 2300f42037eb7b5118015c2caca635538324ccf0ccffredc 2310f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2320f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2330f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2340f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 2350f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (RemoteException e) { 2360f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2370f42037eb7b5118015c2caca635538324ccf0ccffredc } 2380f42037eb7b5118015c2caca635538324ccf0ccffredc } 2390f42037eb7b5118015c2caca635538324ccf0ccffredc 240bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()), 241bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mConnection, 0)) { 242bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie Log.e(TAG, "Could not bind to Bluetooth HID Service"); 243545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 244545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 245545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 2469bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh /*package*/ void close() { 247563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("close()"); 2480f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2490f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2500f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2510f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 2520f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception e) { 2530f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2540f42037eb7b5118015c2caca635538324ccf0ccffredc } 2550f42037eb7b5118015c2caca635538324ccf0ccffredc } 2560f42037eb7b5118015c2caca635538324ccf0ccffredc 2570f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2580f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService != null) { 2590f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2600f42037eb7b5118015c2caca635538324ccf0ccffredc mService = null; 2610f42037eb7b5118015c2caca635538324ccf0ccffredc mContext.unbindService(mConnection); 2620f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2630f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2640f42037eb7b5118015c2caca635538324ccf0ccffredc } 2650f42037eb7b5118015c2caca635538324ccf0ccffredc } 266bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 2679bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 2689bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh } 2699bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh 2704ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 271f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate connection to a profile of the remote bluetooth device. 272f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 273f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The system supports connection to multiple input devices. 274f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 275f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API returns false in scenarios like the profile on the 276f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * device is already connected or Bluetooth is not turned on. 277f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * When this API returns true, it is guaranteed that 278f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * connection state intent for the profile will be broadcasted with 279f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * the state. Users can get the connection state of the profile 280f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * from this intent. 281f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 282f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 283f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 284f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 285f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 286f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 287f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 2884ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 289545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 2904ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 2914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 292bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 2934ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 294bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.connect(device); 2954ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 2964ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2974ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 298bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 299545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3004ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3014ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 302545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 303545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3044ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 305f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate disconnection from a profile 306f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 307f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API will return false in scenarios like the profile on the 308f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Bluetooth device is not in connected state etc. When this API returns, 309f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true, it is guaranteed that the connection state change 310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * intent will be broadcasted with the state. Users can get the 311f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * disconnection state of the profile from this intent. 312f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 313f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> If the disconnection is initiated by a remote device, the state 314f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * will transition from {@link #STATE_CONNECTED} to 315f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 316f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * host (local) device the state will transition from 317f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 318f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * state {@link #STATE_DISCONNECTED}. The transition to 319f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTING} can be used to distinguish between the 320f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * two scenarios. 321f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 322f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 323f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 324f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 325f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 326f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 327f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 3284ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 329545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3304ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 3314ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 332bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 3334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 334bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.disconnect(device); 3354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3364ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3374ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 338bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 339545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3404ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 342545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 343545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3444ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 3454ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 346545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3474ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public List<BluetoothDevice> getConnectedDevices() { 348563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getConnectedDevices()"); 3494ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService != null && isEnabled()) { 3504ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 351bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getConnectedDevices(); 3524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3534ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 355bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 3564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 3574ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3584ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 359545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 360545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 3624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 363545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3644ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 365563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getDevicesMatchingStates()"); 3664ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService != null && isEnabled()) { 3674ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 368bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getDevicesMatchingConnectionStates(states); 3694ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3704ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3714ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 372bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 373545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3744ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3754ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 376545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 377545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3784ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 3794ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 380545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3814ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 382563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getState(" + device + ")"); 383bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 3844ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 385bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getConnectionState(device); 3864ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3874ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3884ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 389bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 390545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3924ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 393545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 394545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 395545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 396f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Set priority of the profile 397f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 398f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The device should already be paired. 399f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Priority can be one of {@link #PRIORITY_ON} or 400f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_OFF}, 401f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 402f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 403f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 404f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 405f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Paired bluetooth device 406f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param priority 407f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return true if priority is set, false on error 4084ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 409545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 4104ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 4114ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 412bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 4134ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (priority != BluetoothProfile.PRIORITY_OFF && 4144ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh priority != BluetoothProfile.PRIORITY_ON) { 4154ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 4164ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 4174ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 418bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.setPriority(device, priority); 4194ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 4204ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4214ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 422bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 423545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 4244ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4254ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 426545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 427545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 428545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 429f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Get the priority of the profile. 430f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 431f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The priority can be any of: 432f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 433f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 434f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 435f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 436f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 437f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Bluetooth device 438f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return priority of the device 4394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 440545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 4414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 442563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getPriority(" + device + ")"); 443bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 4444ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 445bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getPriority(device); 4464ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 4474ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4484ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 449bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 450545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 4514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 4534ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 4544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 455bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private ServiceConnection mConnection = new ServiceConnection() { 456bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie public void onServiceConnected(ComponentName className, IBinder service) { 457bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) Log.d(TAG, "Proxy object connected"); 458bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mService = IBluetoothInputDevice.Stub.asInterface(service); 459bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie 460bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mServiceListener != null) { 461bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this); 462bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 463bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 464bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie public void onServiceDisconnected(ComponentName className) { 465bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) Log.d(TAG, "Proxy object disconnected"); 466bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mService = null; 467bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mServiceListener != null) { 468bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE); 469bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 470bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 471bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie }; 472bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie 4734ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private boolean isEnabled() { 4744ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 4754ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 4764ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 4774ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 4784ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 4794ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (device == null) return false; 4804ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 4814ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 4824ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 483545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 484545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 485349e62f329bbb8edab89356973773a5648f26751Priti Aghera 486349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 487349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Initiate virtual unplug for a HID input device. 488349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 489349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 490349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 491349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 492349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 493349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 494349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 495349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 496349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean virtualUnplug(BluetoothDevice device) { 497349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("virtualUnplug(" + device + ")"); 498349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 499349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 500349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.virtualUnplug(device); 501349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 502349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 503349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 504349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 505349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 506349e62f329bbb8edab89356973773a5648f26751Priti Aghera 507349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 508349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 509349e62f329bbb8edab89356973773a5648f26751Priti Aghera 510349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 511349e62f329bbb8edab89356973773a5648f26751Priti Aghera 512349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 513349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Get_Protocol_Mode command to the connected HID input device. 514349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 515349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 516349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 517349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 518349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 519349e62f329bbb8edab89356973773a5648f26751Priti Aghera *true otherwise 520349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 521349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 522349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean getProtocolMode(BluetoothDevice device) { 523563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getProtocolMode(" + device + ")"); 524349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 525349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 526349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.getProtocolMode(device); 527349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 528349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 529349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 530349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 531349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 532349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 533349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 534349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 535349e62f329bbb8edab89356973773a5648f26751Priti Aghera 536349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 537349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Set_Protocol_Mode command to the connected HID input device. 538349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 539349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 540349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 541349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 542349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 543349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 544349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 545349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 546349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean setProtocolMode(BluetoothDevice device, int protocolMode) { 547349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("setProtocolMode(" + device + ")"); 548349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 549349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 550349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.setProtocolMode(device, protocolMode); 551349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 552349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 553349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 554349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 555349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 556349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 557349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 558349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 559349e62f329bbb8edab89356973773a5648f26751Priti Aghera 560349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 561349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Get_Report command to the connected HID input device. 562349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 563349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 564349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 565349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 566349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param reportType Report type 567349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param reportId Report ID 568349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param bufferSize Report receiving buffer size 569349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 570349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 571349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 572349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 573349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) { 574563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize); 575349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 576349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 577349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.getReport(device, reportType, reportId, bufferSize); 578349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 579349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 580349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 581349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 582349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 583349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 584349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 585349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 586349e62f329bbb8edab89356973773a5648f26751Priti Aghera 587349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 588349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Set_Report command to the connected HID input device. 589349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 590349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 591349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 592349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 593349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param reportType Report type 594349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param report Report receiving buffer size 595349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 596349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 597349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 598349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 599349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean setReport(BluetoothDevice device, byte reportType, String report) { 600349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report); 601349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 602349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 603349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.setReport(device, reportType, report); 604349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 605349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 606349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 607349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 608349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 609349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 610349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 611349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 612349e62f329bbb8edab89356973773a5648f26751Priti Aghera 613349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 614349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Send_Data command to the connected HID input device. 615349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 616349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 617349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 618349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 619349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param data Data to send 620349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 621349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 622349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 623349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 624349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean sendData(BluetoothDevice device, String report) { 625349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("sendData(" + device + "), report=" + report); 626349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 627349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 628349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.sendData(device, report); 629349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 630349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 631349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 632349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 633349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 634349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 635349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 636349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 637545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static void log(String msg) { 6384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.d(TAG, msg); 639545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 640545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh} 641