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; 27545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.util.Log; 28545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 295a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.ArrayList; 305a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.List; 31545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 324ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 33545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/** 344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth Input 354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device Profile. 36545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 374ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth 384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * the BluetoothInputDevice proxy object. 40545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>Each method is protected with its appropriate permission. 424ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *@hide 43545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 444ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganeshpublic final class BluetoothInputDevice implements BluetoothProfile { 45545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static final String TAG = "BluetoothInputDevice"; 460f42037eb7b5118015c2caca635538324ccf0ccffredc private static final boolean DBG = true; 47563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie private static final boolean VDBG = false; 48545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 49545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 504ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Intent used to broadcast the change in connection state of the Input 514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device profile. 524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 534ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>This intent will have 3 extras: 544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <ul> 554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 574ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 584ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * </ul> 594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 604ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 644ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * receive. 66545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 674ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 694ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; 70545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 71fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh /** 72349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 73349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 74349e62f329bbb8edab89356973773a5648f26751Priti Aghera @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 75349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String ACTION_PROTOCOL_MODE_CHANGED = 76349e62f329bbb8edab89356973773a5648f26751Priti Aghera "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED"; 77349e62f329bbb8edab89356973773a5648f26751Priti Aghera 78d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen /** 79d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen * @hide 80d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen */ 81d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 828faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen public static final String ACTION_HANDSHAKE = 838faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen "android.bluetooth.input.profile.action.HANDSHAKE"; 848faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen 858faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen /** 868faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen * @hide 878faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen */ 888faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 89d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen public static final String ACTION_REPORT = 90d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen "android.bluetooth.input.profile.action.REPORT"; 91349e62f329bbb8edab89356973773a5648f26751Priti Aghera 92349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 93349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 94349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 95349e62f329bbb8edab89356973773a5648f26751Priti Aghera @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 96349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String ACTION_VIRTUAL_UNPLUG_STATUS = 97349e62f329bbb8edab89356973773a5648f26751Priti Aghera "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS"; 98349e62f329bbb8edab89356973773a5648f26751Priti Aghera 99349e62f329bbb8edab89356973773a5648f26751Priti Aghera 100349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 101fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh * Return codes for the connect and disconnect Bluez / Dbus calls. 1024ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 103fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh */ 104fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000; 105fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 1064ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1074ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1084ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 109fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001; 110fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 1114ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1124ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1134ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 114fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002; 115fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 1164ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1174ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1184ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 119fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003; 120fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 1214ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 1224ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 1234ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 124fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_OPERATION_SUCCESS = 5004; 125fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 126349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 127349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 128349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 129349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int PROTOCOL_REPORT_MODE = 0; 130349e62f329bbb8edab89356973773a5648f26751Priti Aghera 131349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 132349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 133349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 134349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int PROTOCOL_BOOT_MODE = 1; 135349e62f329bbb8edab89356973773a5648f26751Priti Aghera 136349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 137349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 138349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 139349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int PROTOCOL_UNSUPPORTED_MODE = 255; 140349e62f329bbb8edab89356973773a5648f26751Priti Aghera 141349e62f329bbb8edab89356973773a5648f26751Priti Aghera /* int reportType, int reportType, int bufferSize */ 142349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 143349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 144349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 1451b47f7cc1af63b3ae8ec79808dbf6147b73db605Mike J. Chen public static final byte REPORT_TYPE_INPUT = 1; 146349e62f329bbb8edab89356973773a5648f26751Priti Aghera 147349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 148349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 149349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 1501b47f7cc1af63b3ae8ec79808dbf6147b73db605Mike J. Chen public static final byte REPORT_TYPE_OUTPUT = 2; 151349e62f329bbb8edab89356973773a5648f26751Priti Aghera 152349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 153349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 154349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 1551b47f7cc1af63b3ae8ec79808dbf6147b73db605Mike J. Chen public static final byte REPORT_TYPE_FEATURE = 3; 156349e62f329bbb8edab89356973773a5648f26751Priti Aghera 157349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 158349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 159349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 160349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0; 161349e62f329bbb8edab89356973773a5648f26751Priti Aghera 162349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 163349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 164349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 165349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1; 166349e62f329bbb8edab89356973773a5648f26751Priti Aghera 167349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 168349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 169349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 170349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE"; 171349e62f329bbb8edab89356973773a5648f26751Priti Aghera 172349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 173349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 174349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 175349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE"; 176349e62f329bbb8edab89356973773a5648f26751Priti Aghera 177349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 178349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 179349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 180349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID"; 181349e62f329bbb8edab89356973773a5648f26751Priti Aghera 182349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 183349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 184349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 185349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE"; 186349e62f329bbb8edab89356973773a5648f26751Priti Aghera 187349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 188349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 189349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 190349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_REPORT = "android.bluetooth.BluetoothInputDevice.extra.REPORT"; 191349e62f329bbb8edab89356973773a5648f26751Priti Aghera 192349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 193349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 194349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 1958faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen public static final String EXTRA_STATUS = "android.bluetooth.BluetoothInputDevice.extra.STATUS"; 1968faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen 1978faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen /** 1988faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen * @hide 1998faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen */ 200349e62f329bbb8edab89356973773a5648f26751Priti Aghera public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS"; 201349e62f329bbb8edab89356973773a5648f26751Priti Aghera 202bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private Context mContext; 2034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private ServiceListener mServiceListener; 2044ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private BluetoothAdapter mAdapter; 205bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private IBluetoothInputDevice mService; 206545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 2070f42037eb7b5118015c2caca635538324ccf0ccffredc final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 2080f42037eb7b5118015c2caca635538324ccf0ccffredc new IBluetoothStateChangeCallback.Stub() { 2090f42037eb7b5118015c2caca635538324ccf0ccffredc public void onBluetoothStateChange(boolean up) { 2100f42037eb7b5118015c2caca635538324ccf0ccffredc if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 2110f42037eb7b5118015c2caca635538324ccf0ccffredc if (!up) { 212563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) Log.d(TAG,"Unbinding service..."); 2130f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2140f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2150f42037eb7b5118015c2caca635538324ccf0ccffredc mService = null; 2160f42037eb7b5118015c2caca635538324ccf0ccffredc mContext.unbindService(mConnection); 2170f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2180f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2190f42037eb7b5118015c2caca635538324ccf0ccffredc } 2200f42037eb7b5118015c2caca635538324ccf0ccffredc } 2210f42037eb7b5118015c2caca635538324ccf0ccffredc } else { 2220f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2230f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2240f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService == null) { 225563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) Log.d(TAG,"Binding service..."); 226221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn doBind(); 2270f42037eb7b5118015c2caca635538324ccf0ccffredc } 2280f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2290f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2300f42037eb7b5118015c2caca635538324ccf0ccffredc } 2310f42037eb7b5118015c2caca635538324ccf0ccffredc } 2320f42037eb7b5118015c2caca635538324ccf0ccffredc } 2330f42037eb7b5118015c2caca635538324ccf0ccffredc } 2340f42037eb7b5118015c2caca635538324ccf0ccffredc }; 2350f42037eb7b5118015c2caca635538324ccf0ccffredc 236545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 237545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Create a BluetoothInputDevice proxy object for interacting with the local 2384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Bluetooth Service which handles the InputDevice profile 2394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 240545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 241bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie /*package*/ BluetoothInputDevice(Context context, ServiceListener l) { 242bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mContext = context; 2434ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mServiceListener = l; 2444ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 2450f42037eb7b5118015c2caca635538324ccf0ccffredc 2460f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2470f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2480f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2490f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 2500f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (RemoteException e) { 2510f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2520f42037eb7b5118015c2caca635538324ccf0ccffredc } 2530f42037eb7b5118015c2caca635538324ccf0ccffredc } 2540f42037eb7b5118015c2caca635538324ccf0ccffredc 255221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn doBind(); 256221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn } 257221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn 258221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn boolean doBind() { 259221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn Intent intent = new Intent(IBluetoothInputDevice.class.getName()); 260221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 261221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn intent.setComponent(comp); 262466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 263466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn android.os.Process.myUserHandle())) { 264221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent); 265221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn return false; 266545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 267221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn return true; 268545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 269545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 2709bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh /*package*/ void close() { 271563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("close()"); 2720f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2730f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2740f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2750f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 2760f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception e) { 2770f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2780f42037eb7b5118015c2caca635538324ccf0ccffredc } 2790f42037eb7b5118015c2caca635538324ccf0ccffredc } 2800f42037eb7b5118015c2caca635538324ccf0ccffredc 2810f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2820f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService != null) { 2830f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2840f42037eb7b5118015c2caca635538324ccf0ccffredc mService = null; 2850f42037eb7b5118015c2caca635538324ccf0ccffredc mContext.unbindService(mConnection); 2860f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2870f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2880f42037eb7b5118015c2caca635538324ccf0ccffredc } 2890f42037eb7b5118015c2caca635538324ccf0ccffredc } 290bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 2919bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 2929bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh } 2939bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh 2944ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 295f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate connection to a profile of the remote bluetooth device. 296f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 297f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The system supports connection to multiple input devices. 298f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 299f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API returns false in scenarios like the profile on the 300f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * device is already connected or Bluetooth is not turned on. 301f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * When this API returns true, it is guaranteed that 302f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * connection state intent for the profile will be broadcasted with 303f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * the state. Users can get the connection state of the profile 304f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * from this intent. 305f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 306f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 307f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 308f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 309f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 311f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 3124ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 313545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3144ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 3154ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 316bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 3174ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 318bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.connect(device); 3194ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3204ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3214ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 322bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 323545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3244ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3254ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 326545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 327545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3284ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 329f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate disconnection from a profile 330f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 331f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API will return false in scenarios like the profile on the 332f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Bluetooth device is not in connected state etc. When this API returns, 333f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true, it is guaranteed that the connection state change 334f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * intent will be broadcasted with the state. Users can get the 335f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * disconnection state of the profile from this intent. 336f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 337f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> If the disconnection is initiated by a remote device, the state 338f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * will transition from {@link #STATE_CONNECTED} to 339f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 340f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * host (local) device the state will transition from 341f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 342f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * state {@link #STATE_DISCONNECTED}. The transition to 343f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTING} can be used to distinguish between the 344f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * two scenarios. 345f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 346f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 347f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 348f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 349f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 350f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 351f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 3524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 353545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 3554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 356bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 3574ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 358bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.disconnect(device); 3594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3604ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 362bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 363545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3644ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 366545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 367545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 3694ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 370545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3714ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public List<BluetoothDevice> getConnectedDevices() { 372563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getConnectedDevices()"); 3734ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService != null && isEnabled()) { 3744ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 375bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getConnectedDevices(); 3764ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3774ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3784ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 379bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 3804ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 3814ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3824ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 383545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 384545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 3854ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 3864ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 387545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 3884ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 389563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getDevicesMatchingStates()"); 3904ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService != null && isEnabled()) { 3914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 392bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getDevicesMatchingConnectionStates(states); 3934ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3944ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3954ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 396bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 397545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3984ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3994ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 400545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 401545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 4024ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 4034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 404545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 4054ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 406563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getState(" + device + ")"); 407bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 4084ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 409bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getConnectionState(device); 4104ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 4114ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4124ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 413bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 414545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 4154ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4164ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 417545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 418545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 419545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 420f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Set priority of the profile 421f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 422f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The device should already be paired. 423f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Priority can be one of {@link #PRIORITY_ON} or 424f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_OFF}, 425f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 426f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 427f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 428f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 429f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Paired bluetooth device 430f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param priority 431f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return true if priority is set, false on error 4324ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 433545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 4344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 4354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 436bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 4374ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (priority != BluetoothProfile.PRIORITY_OFF && 4384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh priority != BluetoothProfile.PRIORITY_ON) { 4394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 4404ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 4414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 442bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.setPriority(device, priority); 4434ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 4444ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4454ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 446bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 447545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 4484ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4494ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 450545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 451545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 452545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 453f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Get the priority of the profile. 454f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 455f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The priority can be any of: 456f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 457f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 458f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 459f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 460f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 461f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Bluetooth device 462f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return priority of the device 4634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 464545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 4654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 466563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getPriority(" + device + ")"); 467bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 4684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 469bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getPriority(device); 4704ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 4714ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4724ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 473bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 474545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 4754ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4764ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 4774ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 4784ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 4799b6939939901cb82bc6fca93aad3810a4936dfc6Matthew Xie private final ServiceConnection mConnection = new ServiceConnection() { 480bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie public void onServiceConnected(ComponentName className, IBinder service) { 481bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) Log.d(TAG, "Proxy object connected"); 482bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mService = IBluetoothInputDevice.Stub.asInterface(service); 483bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie 484bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mServiceListener != null) { 485bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this); 486bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 487bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 488bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie public void onServiceDisconnected(ComponentName className) { 489bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) Log.d(TAG, "Proxy object disconnected"); 490bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mService = null; 491bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mServiceListener != null) { 492bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE); 493bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 494bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 495bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie }; 496bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie 4974ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private boolean isEnabled() { 4984ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 4994ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 5004ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 5014ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 5024ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 5034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (device == null) return false; 5044ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 5054ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 5064ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 507545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 508545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 509349e62f329bbb8edab89356973773a5648f26751Priti Aghera 510349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 511349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Initiate virtual unplug for a HID input device. 512349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 513349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 514349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 515349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 516349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 517349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 518349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 519349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 520349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean virtualUnplug(BluetoothDevice device) { 521349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("virtualUnplug(" + device + ")"); 522349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 523349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 524349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.virtualUnplug(device); 525349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 526349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 527349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 528349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 529349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 530349e62f329bbb8edab89356973773a5648f26751Priti Aghera 531349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 532349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 533349e62f329bbb8edab89356973773a5648f26751Priti Aghera 534349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 535349e62f329bbb8edab89356973773a5648f26751Priti Aghera 536349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 537349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Get_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 getProtocolMode(BluetoothDevice device) { 547563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getProtocolMode(" + device + ")"); 548349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 549349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 550349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.getProtocolMode(device); 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 Set_Protocol_Mode 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 * @return false on immediate error, 567349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 568349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 569349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 570349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean setProtocolMode(BluetoothDevice device, int protocolMode) { 571349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("setProtocolMode(" + device + ")"); 572349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 573349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 574349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.setProtocolMode(device, protocolMode); 575349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 576349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 577349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 578349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 579349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 580349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 581349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 582349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 583349e62f329bbb8edab89356973773a5648f26751Priti Aghera 584349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 585349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Get_Report command to the connected HID input device. 586349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 587349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 588349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 589349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 590349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param reportType Report type 591349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param reportId Report ID 592349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param bufferSize Report receiving buffer size 593349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 594349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 595349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 596349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 597349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) { 598563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize); 599349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 600349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 601349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.getReport(device, reportType, reportId, bufferSize); 602349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 603349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 604349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 605349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 606349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 607349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 608349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 609349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 610349e62f329bbb8edab89356973773a5648f26751Priti Aghera 611349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 612349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Set_Report command to the connected HID input device. 613349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 614349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 615349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 616349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 617349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param reportType Report type 618349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param report Report receiving buffer size 619349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 620349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 621349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 622349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 623349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean setReport(BluetoothDevice device, byte reportType, String report) { 6248faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report); 625349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 626349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 627349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.setReport(device, reportType, report); 628349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 629349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 630349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 631349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 632349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 633349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 634349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 635349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 636349e62f329bbb8edab89356973773a5648f26751Priti Aghera 637349e62f329bbb8edab89356973773a5648f26751Priti Aghera /** 638349e62f329bbb8edab89356973773a5648f26751Priti Aghera * Send Send_Data command to the connected HID input device. 639349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 640349e62f329bbb8edab89356973773a5648f26751Priti Aghera * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 641349e62f329bbb8edab89356973773a5648f26751Priti Aghera * 642349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @param device Remote Bluetooth Device 643707fd39f8bac49e216de3bd6f4248ee61d207aecAng Li * @param report Report to send 644349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @return false on immediate error, 645349e62f329bbb8edab89356973773a5648f26751Priti Aghera * true otherwise 646349e62f329bbb8edab89356973773a5648f26751Priti Aghera * @hide 647349e62f329bbb8edab89356973773a5648f26751Priti Aghera */ 648349e62f329bbb8edab89356973773a5648f26751Priti Aghera public boolean sendData(BluetoothDevice device, String report) { 649349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (DBG) log("sendData(" + device + "), report=" + report); 650349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService != null && isEnabled() && isValidDevice(device)) { 651349e62f329bbb8edab89356973773a5648f26751Priti Aghera try { 652349e62f329bbb8edab89356973773a5648f26751Priti Aghera return mService.sendData(device, report); 653349e62f329bbb8edab89356973773a5648f26751Priti Aghera } catch (RemoteException e) { 654349e62f329bbb8edab89356973773a5648f26751Priti Aghera Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 655349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 656349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 657349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 658349e62f329bbb8edab89356973773a5648f26751Priti Aghera if (mService == null) Log.w(TAG, "Proxy not attached to service"); 659349e62f329bbb8edab89356973773a5648f26751Priti Aghera return false; 660349e62f329bbb8edab89356973773a5648f26751Priti Aghera } 661545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static void log(String msg) { 6624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.d(TAG, msg); 663545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 664545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh} 665