1e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta/* 2e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Copyright (C) 2016 The Android Open Source Project 3e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 4e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 5e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * you may not use this file except in compliance with the License. 6e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * You may obtain a copy of the License at 7e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 8e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * http://www.apache.org/licenses/LICENSE-2.0 9e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 10e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Unless required by applicable law or agreed to in writing, software 11e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * distributed under the License is distributed on an "AS IS" BASIS, 12e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * See the License for the specific language governing permissions and 14e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * limitations under the License. 15e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 16e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 17e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptapackage android.bluetooth; 18e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 190afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogovimport android.annotation.SdkConstant; 200afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogovimport android.annotation.SdkConstant.SdkConstantType; 21e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.content.ComponentName; 22e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.content.Context; 23e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.content.Intent; 24e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.content.ServiceConnection; 25e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.os.IBinder; 26e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.os.RemoteException; 27e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport android.util.Log; 28e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 29dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogovimport java.util.ArrayList; 300146463d70355592da85c3605aaaef4cf0b7335eJack Heimport java.util.Arrays; 31e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport java.util.List; 32e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 33e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta/** 34e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @hide 35e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 360afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogovpublic final class BluetoothInputHost implements BluetoothProfile { 37e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 380afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov private static final String TAG = BluetoothInputHost.class.getSimpleName(); 39e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 400afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov /** 410afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * Intent used to broadcast the change in connection state of the Input 420afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * Host profile. 430afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * 440afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <p>This intent will have 3 extras: 450afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <ul> 460afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 470afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 480afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 490afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * </ul> 500afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * 510afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 520afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 530afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 540afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * 550afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 560afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov * receive. 570afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov */ 580afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 59e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final String ACTION_CONNECTION_STATE_CHANGED = 600afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov "android.bluetooth.inputhost.profile.action.CONNECTION_STATE_CHANGED"; 61e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 62e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 63e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Constants representing device subclass. 64e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 65e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @see #registerApp(String, String, String, byte, byte[], 66e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * BluetoothHidDeviceCallback) 67e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 68e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS1_NONE = (byte) 0x00; 69e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS1_KEYBOARD = (byte) 0x40; 70e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS1_MOUSE = (byte) 0x80; 71e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS1_COMBO = (byte) 0xC0; 72e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 73e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_UNCATEGORIZED = (byte) 0x00; 74e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_JOYSTICK = (byte) 0x01; 75e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_GAMEPAD = (byte) 0x02; 76e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_REMOTE_CONTROL = (byte) 0x03; 77e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_SENSING_DEVICE = (byte) 0x04; 78e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_DIGITIZER_TABLED = (byte) 0x05; 79e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte SUBCLASS2_CARD_READER = (byte) 0x06; 80e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 81e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 82e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Constants representing report types. 83e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 84e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @see BluetoothHidDeviceCallback#onGetReport(byte, byte, int) 85e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @see BluetoothHidDeviceCallback#onSetReport(byte, byte, byte[]) 86e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @see BluetoothHidDeviceCallback#onIntrData(byte, byte[]) 87e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 88e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte REPORT_TYPE_INPUT = (byte) 1; 89e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte REPORT_TYPE_OUTPUT = (byte) 2; 90e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte REPORT_TYPE_FEATURE = (byte) 3; 91e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 92e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 93e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Constants representing error response for Set Report. 94e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 95e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @see BluetoothHidDeviceCallback#onSetReport(byte, byte, byte[]) 96e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 97e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte ERROR_RSP_SUCCESS = (byte) 0; 98e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte ERROR_RSP_NOT_READY = (byte) 1; 99e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte ERROR_RSP_INVALID_RPT_ID = (byte) 2; 100e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte ERROR_RSP_UNSUPPORTED_REQ = (byte) 3; 101e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte ERROR_RSP_INVALID_PARAM = (byte) 4; 102e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte ERROR_RSP_UNKNOWN = (byte) 14; 103e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 104e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 105e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Constants representing protocol mode used set by host. Default is always 106e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link #PROTOCOL_REPORT_MODE} unless notified otherwise. 107e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 108e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @see BluetoothHidDeviceCallback#onSetProtocol(byte) 109e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 110e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte PROTOCOL_BOOT_MODE = (byte) 0; 111e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public static final byte PROTOCOL_REPORT_MODE = (byte) 1; 112e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 113e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta private Context mContext; 114e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 115e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta private ServiceListener mServiceListener; 116e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 1170146463d70355592da85c3605aaaef4cf0b7335eJack He private volatile IBluetoothInputHost mService; 118e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 119e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta private BluetoothAdapter mAdapter; 120e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 121e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta private static class BluetoothHidDeviceCallbackWrapper extends IBluetoothHidDeviceCallback.Stub { 122e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 123e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta private BluetoothHidDeviceCallback mCallback; 124e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 125e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public BluetoothHidDeviceCallbackWrapper(BluetoothHidDeviceCallback callback) { 126e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mCallback = callback; 127e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 128e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 129e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 130e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onAppStatusChanged(BluetoothDevice pluggedDevice, 131e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceAppConfiguration config, boolean registered) { 132e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mCallback.onAppStatusChanged(pluggedDevice, config, registered); 133e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 134e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 135e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 136e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onConnectionStateChanged(BluetoothDevice device, int state) { 137e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mCallback.onConnectionStateChanged(device, state); 138e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 139e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 140e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 141dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) { 142dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov mCallback.onGetReport(device, type, id, bufferSize); 143e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 144e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 145e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 146dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) { 147dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov mCallback.onSetReport(device, type, id, data); 148e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 149e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 150e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 151dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public void onSetProtocol(BluetoothDevice device, byte protocol) { 152dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov mCallback.onSetProtocol(device, protocol); 153e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 154e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 155e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 156dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public void onIntrData(BluetoothDevice device, byte reportId, byte[] data) { 157dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov mCallback.onIntrData(device, reportId, data); 158e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 159e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 160e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta @Override 161dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public void onVirtualCableUnplug(BluetoothDevice device) { 162dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov mCallback.onVirtualCableUnplug(device); 163e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 164e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 165e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 166e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 167e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta new IBluetoothStateChangeCallback.Stub() { 168e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 169e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onBluetoothStateChange(boolean up) { 170e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "onBluetoothStateChange: up=" + up); 171e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta synchronized (mConnection) { 172e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (!up) { 173e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG,"Unbinding service..."); 174e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 175e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mService = null; 176e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 177e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mContext.unbindService(mConnection); 178e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (IllegalArgumentException e) { 179e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG,"onBluetoothStateChange: could not unbind service:", e); 180e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 181e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 182e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 183e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 184e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService == null) { 185e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG,"Binding HID Device service..."); 186e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta doBind(); 187e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 188e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (IllegalStateException e) { 189e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG,"onBluetoothStateChange: could not bind to HID Dev service: ", e); 190e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (SecurityException e) { 191e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG,"onBluetoothStateChange: could not bind to HID Dev service: ", e); 192e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 193e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 194e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 195e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 196e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta }; 197e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 1980146463d70355592da85c3605aaaef4cf0b7335eJack He private final ServiceConnection mConnection = new ServiceConnection() { 199e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onServiceConnected(ComponentName className, IBinder service) { 200e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "onServiceConnected()"); 2010afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov mService = IBluetoothInputHost.Stub.asInterface(service); 202e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mServiceListener != null) { 2030afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov mServiceListener.onServiceConnected(BluetoothProfile.INPUT_HOST, 2040afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov BluetoothInputHost.this); 205e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 206e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 207e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onServiceDisconnected(ComponentName className) { 208e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "onServiceDisconnected()"); 209e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mService = null; 210e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mServiceListener != null) { 2110afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_HOST); 212e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 213e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 214e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta }; 215e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 2160afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov BluetoothInputHost(Context context, ServiceListener listener) { 2170afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov Log.v(TAG, "BluetoothInputHost"); 218e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 219e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mContext = context; 220e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mServiceListener = listener; 221e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mAdapter = BluetoothAdapter.getDefaultAdapter(); 222e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 223e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta IBluetoothManager mgr = mAdapter.getBluetoothManager(); 224e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mgr != null) { 225e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 226e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 227e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 228e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta e.printStackTrace(); 229e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 230e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 231e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 232e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta doBind(); 233e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 234e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 235e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean doBind() { 2360afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov Intent intent = new Intent(IBluetoothInputHost.class.getName()); 237e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 238e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta intent.setComponent(comp); 239e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 240e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta android.os.Process.myUserHandle())) { 241e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent); 242e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return false; 243e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 244e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "Bound to HID Device Service"); 245e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return true; 246e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 247e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 248e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta void close() { 249e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "close()"); 250e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 251e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta IBluetoothManager mgr = mAdapter.getBluetoothManager(); 252e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mgr != null) { 253e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 254e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 255e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 256e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta e.printStackTrace(); 257e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 258e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 259e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 260e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta synchronized (mConnection) { 261e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 262e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mService = null; 263e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 264e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mContext.unbindService(mConnection); 265e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (IllegalArgumentException e) { 266e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG,"close: could not unbind HID Dev service: ", e); 267e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 268e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 269e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 270e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 271e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mServiceListener = null; 272e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 273e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 274dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov /** 275dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@inheritDoc} 276dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov */ 277e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public List<BluetoothDevice> getConnectedDevices() { 278e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "getConnectedDevices()"); 279dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 2800146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 2810146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 282dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov try { 2830146463d70355592da85c3605aaaef4cf0b7335eJack He return service.getConnectedDevices(); 284dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } catch (RemoteException e) { 285dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.e(TAG, e.toString()); 286dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 287dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } else { 288dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.w(TAG, "Proxy not attached to service"); 289dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 290dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 291dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return new ArrayList<BluetoothDevice>(); 292e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 293e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 294dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov /** 295dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@inheritDoc} 296dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov */ 297e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 298e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states)); 299dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 3000146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 3010146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 302dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov try { 3030146463d70355592da85c3605aaaef4cf0b7335eJack He return service.getDevicesMatchingConnectionStates(states); 304dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } catch (RemoteException e) { 305dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.e(TAG, e.toString()); 306dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 307dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } else { 308dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.w(TAG, "Proxy not attached to service"); 309dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 310dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 311dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return new ArrayList<BluetoothDevice>(); 312e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 313e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 314dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov /** 315dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@inheritDoc} 316dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov */ 317e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public int getConnectionState(BluetoothDevice device) { 318dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "getConnectionState(): device=" + device); 319dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 3200146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 3210146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 322dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov try { 3230146463d70355592da85c3605aaaef4cf0b7335eJack He return service.getConnectionState(device); 324dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } catch (RemoteException e) { 325dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.e(TAG, e.toString()); 326dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 327dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } else { 328dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.w(TAG, "Proxy not attached to service"); 329dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 330e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 331e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return STATE_DISCONNECTED; 332e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 333e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 334e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 335e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Registers application to be used for HID device. Connections to HID 336e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Device are only possible when application is registered. Only one 337e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * application can be registered at time. When no longer used, application 338e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * should be unregistered using 339e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link #unregisterApp(BluetoothHidDeviceAppConfiguration)}. 340e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 341e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of 342e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * HID Device SDP record. 343e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param inQos {@link BluetoothHidDeviceAppQosSettings} object of 344e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Incoming QoS Settings. 345e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param outQos {@link BluetoothHidDeviceAppQosSettings} object of 346e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Outgoing QoS Settings. 347e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param callback {@link BluetoothHidDeviceCallback} object to which 348e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * callback messages will be sent. 349e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 350e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 351e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public boolean registerApp(BluetoothHidDeviceAppSdpSettings sdp, 352e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceAppQosSettings inQos, BluetoothHidDeviceAppQosSettings outQos, 353e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceCallback callback) { 354e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "registerApp(): sdp=" + sdp + " inQos=" + inQos + " outQos=" + outQos 355e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta + " callback=" + callback); 356e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 357e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 358e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 359e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (sdp == null || callback == null) { 360e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return false; 361e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 362e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 3630146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 3640146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 365e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 366e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceAppConfiguration config = 3670146463d70355592da85c3605aaaef4cf0b7335eJack He new BluetoothHidDeviceAppConfiguration(); 368e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceCallbackWrapper cbw = 3690146463d70355592da85c3605aaaef4cf0b7335eJack He new BluetoothHidDeviceCallbackWrapper(callback); 3700146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.registerApp(config, sdp, inQos, outQos, cbw); 371e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 372e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 373e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 374e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 375e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 376e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 377e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 378e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 379e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 380e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 381e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 382e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Unregisters application. Active connection will be disconnected and no 383e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * new connections will be allowed until registered again using 384e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link #registerApp(String, String, String, byte, byte[], BluetoothHidDeviceCallback)} 385e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 386e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param config {@link BluetoothHidDeviceAppConfiguration} object as 387e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * obtained from 388e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link BluetoothHidDeviceCallback#onAppStatusChanged(BluetoothDevice, 389e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * BluetoothHidDeviceAppConfiguration, boolean)} 390e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 391e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 392e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 393e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public boolean unregisterApp(BluetoothHidDeviceAppConfiguration config) { 394e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "unregisterApp()"); 395e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 396e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 397e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 3980146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 3990146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 400e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 4010146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.unregisterApp(config); 402e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 403e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 404e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 405e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 406e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 407e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 408e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 409e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 410e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 411e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 412e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 413e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends report to remote host using interrupt channel. 414e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 415e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param id Report Id, as defined in descriptor. Can be 0 in case Report Id 416e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * are not defined in descriptor. 417e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param data Report data, not including Report Id. 418e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 419e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 420dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean sendReport(BluetoothDevice device, int id, byte[] data) { 421e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 422e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 4230146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 4240146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 425e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 4260146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.sendReport(device, id, data); 427e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 428e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 429e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 430e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 431e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 432e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 433e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 434e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 435e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 436e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 437e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 438e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends report to remote host as reply for GET_REPORT request from 439dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@link BluetoothHidDeviceCallback#onGetReport(BluetoothDevice, byte, byte, int)}. 440e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 441e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param type Report Type, as in request. 442e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param id Report Id, as in request. 443e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param data Report data, not including Report Id. 444e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 445e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 446dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) { 447dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "replyReport(): device=" + device + " type=" + type + " id=" + id); 448e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 449e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 450e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 4510146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 4520146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 453e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 4540146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.replyReport(device, type, id, data); 455e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 456e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 457e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 458e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 459e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 460e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 461e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 462e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 463e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 464e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 465e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 466e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends error handshake message as reply for invalid SET_REPORT request 467dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * from {@link BluetoothHidDeviceCallback#onSetReport(BluetoothDevice, byte, byte, byte[])}. 468e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 469e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param error Error to be sent for SET_REPORT via HANDSHAKE. 470e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 471e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 472dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean reportError(BluetoothDevice device, byte error) { 473dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "reportError(): device=" + device + " error=" + error); 474e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 475e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 476e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 4770146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 4780146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 479e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 4800146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.reportError(device, error); 481e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 482e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 483e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 484e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 485e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 486e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 487e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 488e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 489e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 490e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 491e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 492e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends Virtual Cable Unplug to currently connected host. 493e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 494e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 495e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 496dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean unplug(BluetoothDevice device) { 497dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "unplug(): device=" + device); 498e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 499e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 500e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 5010146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 5020146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 503e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 5040146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.unplug(device); 505e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 506e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 507e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 508e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 509e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 510e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 511e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 512e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 513e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 514e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 515e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 516e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Initiates connection to host which currently has Virtual Cable 517e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * established with device. 518e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 519e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 520e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 521dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean connect(BluetoothDevice device) { 522dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "connect(): device=" + device); 523e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 524e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 525e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 5260146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 5270146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 528e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 5290146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.connect(device); 530e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 531e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 532e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 533e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 534e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 535e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 536e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 537e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 538e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 539e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 540e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 541e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Disconnects from currently connected host. 542e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 543e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 544e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 545dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean disconnect(BluetoothDevice device) { 546dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "disconnect(): device=" + device); 547e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 548e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 549e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 5500146463d70355592da85c3605aaaef4cf0b7335eJack He final IBluetoothInputHost service = mService; 5510146463d70355592da85c3605aaaef4cf0b7335eJack He if (service != null) { 552e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 5530146463d70355592da85c3605aaaef4cf0b7335eJack He result = service.disconnect(device); 554e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 555e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 556e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 557e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 558e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 559e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 560e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 561e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 562e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 563e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta} 564